diff --git a/CHANGELOG.md b/CHANGELOG.md
index c6555d2..8574697 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,29 @@
 
 ### Language
 
+### Core libraries
+
+### Dart VM
+
+### Tools
+
+#### Pub
+
+#### Linter
+
+The Linter was updated to `0.1.97+1`, which includes:
+
+* internal migration away from using analyzer `resolutionMap`
+* various fixes and improvements to anticipate support for extension-methods
+* new lint: `camel_case_extensions`
+* rule template generation improvements
+* new lint: `avoid_equals_and_hash_code_on_mutable_classes`
+* extended `avoid_slow_async_io` to flag async `Directory` methods
+
+## 2.5.0 - 2019-09-10
+
+### Language
+
 The set of operations allowed in constant expressions has been expanded as
 described in
 the [constant update proposal](https://github.com/dart-lang/language/issues/61).
@@ -124,7 +147,7 @@
 
 #### `dart:io`
 
-* **Breaking change** [#37192](https://github.com/dart-lang/sdk/issues/37192): 
+* **Breaking change** [#37192](https://github.com/dart-lang/sdk/issues/37192):
   The `Cookie` class's constructor's `name` and `value`
   optional positional parameters are now mandatory. The
   signature changes from:
@@ -142,7 +165,7 @@
   Since code could not previously correctly omit the parameters, this is not
   really a breaking change.
 
-* **Breaking change** [#37192](https://github.com/dart-lang/sdk/issues/37192): 
+* **Breaking change** [#37192](https://github.com/dart-lang/sdk/issues/37192):
   The `Cookie` class's `name` and `value` setters now
   validates that the strings are made from the allowed character set and are not
   null. The constructor already made these checks and this
@@ -161,14 +184,11 @@
 
 #### Linter
 
-The Linter was updated to `0.1.97+1`, which includes:
+The Linter was updated to `0.1.96`, which includes:
 
-* internal migration away from using analyzer `resolutionMap`
-* various fixes and improvements to anticipate support for extension-methods
-* new lint: `camel_case_extensions`
-* rule template generation improvements
-* new lint: `avoid_equals_and_hash_code_on_mutable_classes`
-* extended `avoid_slow_async_io` to flag async `Directory` methods
+* fixed false positives in `unnecessary_parens`
+* various changes to migrate to preferred analyzer APIs
+* rule test fixes
 
 #### Dartdoc
 
diff --git a/DEPS b/DEPS
index 6033eca..dc46d63 100644
--- a/DEPS
+++ b/DEPS
@@ -174,7 +174,7 @@
   Var("dart_root") + "/tools/sdks": {
       "packages": [{
           "package": "dart/dart-sdk/${{platform}}",
-          "version": "version:2.5.0-dev.1.0",
+          "version": "version:2.5.0",
       }],
       "dep_type": "cipd",
   },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 7beb3f8..63a5b47 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -57,16 +57,6 @@
     return unformatted_files
 
 
-def _CheckBuildStatus(input_api, output_api):
-    results = []
-    status_check = input_api.canned_checks.CheckTreeIsOpen(
-        input_api,
-        output_api,
-        json_url='http://dart-status.appspot.com/current?format=json')
-    results.extend(status_check)
-    return results
-
-
 def _CheckDartFormat(input_api, output_api):
     local_root = input_api.change.RepositoryRoot()
     upstream = input_api.change._upstream
@@ -250,16 +240,22 @@
             long_text=stdout)
     ]
 
+
+def _CommonChecks(input_api, output_api):
+    results = []
+    results.extend(_CheckValidHostsInDEPS(input_api, output_api))
+    results.extend(_CheckDartFormat(input_api, output_api))
+    results.extend(_CheckStatusFiles(input_api, output_api))
+    results.extend(_CheckLayering(input_api, output_api))
+    results.extend(_CheckClangTidy(input_api, output_api))
+    results.extend(
+        input_api.canned_checks.CheckPatchFormatted(input_api, output_api))
+    return results
+
+
 def CheckChangeOnCommit(input_api, output_api):
-    return (_CheckValidHostsInDEPS(input_api, output_api) + _CheckBuildStatus(
-        input_api, output_api) + _CheckDartFormat(input_api, output_api) +
-            _CheckStatusFiles(input_api, output_api) + _CheckLayering(
-                input_api, output_api) + _CheckClangTidy(
-                input_api, output_api))
+    return _CommonChecks(input_api, output_api)
 
 
 def CheckChangeOnUpload(input_api, output_api):
-    return (_CheckValidHostsInDEPS(input_api, output_api) + _CheckDartFormat(
-        input_api, output_api) + _CheckStatusFiles(input_api, output_api) +
-            _CheckLayering(input_api, output_api) + _CheckClangTidy(
-                input_api, output_api))
+    return _CommonChecks(input_api, output_api)
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index 9e1113b..4d77c9c 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -214,6 +214,7 @@
       if (opType.includeReturnValueSuggestions) {
         kinds.add(protocol.ElementKind.CONSTRUCTOR);
         kinds.add(protocol.ElementKind.ENUM_CONSTANT);
+        kinds.add(protocol.ElementKind.EXTENSION);
         kinds.add(protocol.ElementKind.FUNCTION);
         kinds.add(protocol.ElementKind.TOP_LEVEL_VARIABLE);
       }
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 9cb8c62..3d37042 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -104,9 +104,7 @@
   static const CONVERT_TO_PACKAGE_IMPORT = const AssistKind(
       'dart.assist.convert.relativeToPackageImport',
       30,
-      "Convert to 'package:' import",
-      // todo (pq): migrate to (conditional) fix
-      associatedErrorCodes: <String>['avoid_relative_lib_imports']);
+      "Convert to 'package:' import");
   static const CONVERT_TO_SET_LITERAL = const AssistKind(
       'dart.assist.convert.toSetLiteral', 30, "Convert to set literal",
       // todo (brianwilkerson): unify w/ fix
@@ -114,13 +112,9 @@
   static const CONVERT_TO_SINGLE_QUOTED_STRING = const AssistKind(
       'dart.assist.convert.toSingleQuotedString',
       30,
-      "Convert to single quoted string",
-      // todo (pq): migrate to (conditional) fix
-      associatedErrorCodes: <String>['prefer_single_quotes']);
-  static const CONVERT_TO_SPREAD =
-      const AssistKind('dart.assist.convertToSpread', 30, "Convert to a spread",
-          // todo (pq): migrate to (conditional) fix
-          associatedErrorCodes: <String>['prefer_spread_collections']);
+      "Convert to single quoted string");
+  static const CONVERT_TO_SPREAD = const AssistKind(
+      'dart.assist.convertToSpread', 30, "Convert to a spread");
   static const ENCAPSULATE_FIELD =
       const AssistKind('dart.assist.encapsulateField', 30, "Encapsulate field");
   static const EXCHANGE_OPERANDS =
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index f3ba612..8d88015 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -101,8 +101,16 @@
     )) {
       await _addProposal_convertToNullAware();
     }
-    await _addProposal_convertToPackageImport();
-    await _addProposal_convertToSingleQuotedString();
+    if (!_containsErrorCode(
+      {LintNames.avoid_relative_lib_imports},
+    )) {
+      await _addProposal_convertToPackageImport();
+    }
+    if (!_containsErrorCode(
+      {LintNames.prefer_single_quotes},
+    )) {
+      await _addProposal_convertToSingleQuotedString();
+    }
     await _addProposal_encapsulateField();
     await _addProposal_exchangeOperands();
     await _addProposal_flutterConvertToChildren();
@@ -151,7 +159,11 @@
       }
     }
     if (experimentStatus.spread_collections) {
-      await _addProposal_convertAddAllToSpread();
+      if (!_containsErrorCode(
+        {LintNames.prefer_spread_collections},
+      )) {
+        await _addProposal_convertAddAllToSpread();
+      }
     }
 
     return assists;
@@ -252,83 +264,13 @@
   }
 
   Future<void> _addProposal_convertAddAllToSpread() async {
-    AstNode node = this.node;
-    if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
-      _coverageMarker();
-      return;
+    final change = await createBuilder_convertAddAllToSpread();
+    if (change != null) {
+      final kind = change.isLineInvocation
+          ? DartAssistKind.INLINE_INVOCATION
+          : DartAssistKind.CONVERT_TO_SPREAD;
+      _addAssistFromBuilder(change.builder, kind, args: change.args);
     }
-    SimpleIdentifier name = node;
-    MethodInvocation invocation = node.parent;
-    if (name != invocation.methodName ||
-        name.name != 'addAll' ||
-        !invocation.isCascaded ||
-        invocation.argumentList.arguments.length != 1) {
-      _coverageMarker();
-      return;
-    }
-    CascadeExpression cascade = invocation.thisOrAncestorOfType();
-    NodeList<Expression> sections = cascade.cascadeSections;
-    Expression target = cascade.target;
-    if (target is! ListLiteral || sections[0] != invocation) {
-      // TODO(brianwilkerson) Consider extending this to handle set literals.
-      _coverageMarker();
-      return;
-    }
-
-    bool isEmptyListLiteral(Expression expression) =>
-        expression is ListLiteral && expression.elements.isEmpty;
-
-    ListLiteral list = target;
-    Expression argument = invocation.argumentList.arguments[0];
-    String elementText;
-    AssistKind kind = DartAssistKind.CONVERT_TO_SPREAD;
-    List<String> args = null;
-    if (argument is BinaryExpression &&
-        argument.operator.type == TokenType.QUESTION_QUESTION) {
-      Expression right = argument.rightOperand;
-      if (isEmptyListLiteral(right)) {
-        // ..addAll(things ?? const [])
-        // ..addAll(things ?? [])
-        elementText = '...?${utils.getNodeText(argument.leftOperand)}';
-      }
-    } else if (experimentStatus.control_flow_collections &&
-        argument is ConditionalExpression) {
-      Expression elseExpression = argument.elseExpression;
-      if (isEmptyListLiteral(elseExpression)) {
-        // ..addAll(condition ? things : const [])
-        // ..addAll(condition ? things : [])
-        String conditionText = utils.getNodeText(argument.condition);
-        String thenText = utils.getNodeText(argument.thenExpression);
-        elementText = 'if ($conditionText) ...$thenText';
-      }
-    } else if (argument is ListLiteral) {
-      // ..addAll([ ... ])
-      NodeList<CollectionElement> elements = argument.elements;
-      if (elements.isEmpty) {
-        // TODO(brianwilkerson) Consider adding a cleanup for the empty list
-        //  case. We can essentially remove the whole invocation because it does
-        //  nothing.
-        return;
-      }
-      int startOffset = elements.first.offset;
-      int endOffset = elements.last.end;
-      elementText = utils.getText(startOffset, endOffset - startOffset);
-      kind = DartAssistKind.INLINE_INVOCATION;
-      args = ['addAll'];
-    }
-    elementText ??= '...${utils.getNodeText(argument)}';
-    DartChangeBuilder changeBuilder = _newDartChangeBuilder();
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      if (list.elements.isNotEmpty) {
-        // ['a']..addAll(['b', 'c']);
-        builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
-      } else {
-        // []..addAll(['b', 'c']);
-        builder.addSimpleInsertion(list.leftBracket.end, elementText);
-      }
-      builder.addDeletion(range.node(invocation));
-    });
-    _addAssistFromBuilder(changeBuilder, kind, args: args);
   }
 
   Future<void> _addProposal_convertClassToMixin() async {
@@ -1310,45 +1252,9 @@
   }
 
   Future<void> _addProposal_convertToPackageImport() async {
-    var node = this.node;
-    if (node is StringLiteral) {
-      node = node.parent;
-    }
-    if (node is ImportDirective) {
-      ImportDirective importDirective = node;
-      var uriSource = importDirective.uriSource;
-
-      // Ignore if invalid URI.
-      if (uriSource == null) {
-        return;
-      }
-
-      var importUri = uriSource.uri;
-      if (importUri.scheme != 'package') {
-        return;
-      }
-
-      // Don't offer to convert a 'package:' URI to itself.
-      try {
-        if (Uri.parse(importDirective.uriContent).scheme == 'package') {
-          return;
-        }
-      } on FormatException {
-        return;
-      }
-
-      var changeBuilder = _newDartChangeBuilder();
-      await changeBuilder.addFileEdit(file, (builder) {
-        builder.addSimpleReplacement(
-          range.node(importDirective.uri),
-          "'$importUri'",
-        );
-      });
-      _addAssistFromBuilder(
-        changeBuilder,
-        DartAssistKind.CONVERT_TO_PACKAGE_IMPORT,
-      );
-    }
+    final changeBuilder = await createBuilder_convertToPackageImport();
+    _addAssistFromBuilder(
+        changeBuilder, DartAssistKind.CONVERT_TO_PACKAGE_IMPORT);
   }
 
   Future<void> _addProposal_convertToSingleQuotedString() async {
@@ -3432,57 +3338,8 @@
   }
 
   Future<void> _convertQuotes(bool fromDouble, AssistKind kind) async {
-    if (node is SimpleStringLiteral) {
-      SimpleStringLiteral literal = node;
-      if (fromDouble ? !literal.isSingleQuoted : literal.isSingleQuoted) {
-        String newQuote = literal.isMultiline
-            ? (fromDouble ? "'''" : '"""')
-            : (fromDouble ? "'" : '"');
-        int quoteLength = literal.isMultiline ? 3 : 1;
-        String lexeme = literal.literal.lexeme;
-        if (lexeme.indexOf(newQuote) < 0) {
-          var changeBuilder = _newDartChangeBuilder();
-          await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-            builder.addSimpleReplacement(
-                new SourceRange(
-                    literal.offset + (literal.isRaw ? 1 : 0), quoteLength),
-                newQuote);
-            builder.addSimpleReplacement(
-                new SourceRange(literal.end - quoteLength, quoteLength),
-                newQuote);
-          });
-          _addAssistFromBuilder(changeBuilder, kind);
-        }
-      }
-    } else if (node is InterpolationString) {
-      StringInterpolation parent = node.parent;
-      if (fromDouble ? !parent.isSingleQuoted : parent.isSingleQuoted) {
-        String newQuote = parent.isMultiline
-            ? (fromDouble ? "'''" : '"""')
-            : (fromDouble ? "'" : '"');
-        int quoteLength = parent.isMultiline ? 3 : 1;
-        NodeList<InterpolationElement> elements = parent.elements;
-        for (int i = 0; i < elements.length; i++) {
-          InterpolationElement element = elements[i];
-          if (element is InterpolationString) {
-            String lexeme = element.contents.lexeme;
-            if (lexeme.indexOf(newQuote) >= 0) {
-              return;
-            }
-          }
-        }
-        var changeBuilder = _newDartChangeBuilder();
-        await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-          builder.addSimpleReplacement(
-              new SourceRange(
-                  parent.offset + (parent.isRaw ? 1 : 0), quoteLength),
-              newQuote);
-          builder.addSimpleReplacement(
-              new SourceRange(parent.end - quoteLength, quoteLength), newQuote);
-        });
-        _addAssistFromBuilder(changeBuilder, kind);
-      }
-    }
+    final changeBuilder = await createBuilder_convertQuotes(fromDouble);
+    _addAssistFromBuilder(changeBuilder, kind);
   }
 
   /**
diff --git a/pkg/analysis_server/lib/src/services/correction/base_processor.dart b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
index a67b7ca..e054c8f 100644
--- a/pkg/analysis_server/lib/src/services/correction/base_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
@@ -155,182 +155,6 @@
     return validChange ? changeBuilder : null;
   }
 
-  Future<ChangeBuilder> createBuilder_convertToNullAware() async {
-    AstNode node = this.node;
-    if (node is! ConditionalExpression) {
-      _coverageMarker();
-      return null;
-    }
-    ConditionalExpression conditional = node;
-    Expression condition = conditional.condition.unParenthesized;
-    SimpleIdentifier identifier;
-    Expression nullExpression;
-    Expression nonNullExpression;
-    int periodOffset;
-
-    if (condition is BinaryExpression) {
-      //
-      // Identify the variable being compared to `null`, or return if the
-      // condition isn't a simple comparison of `null` to a variable's value.
-      //
-      Expression leftOperand = condition.leftOperand;
-      Expression rightOperand = condition.rightOperand;
-      if (leftOperand is NullLiteral && rightOperand is SimpleIdentifier) {
-        identifier = rightOperand;
-      } else if (rightOperand is NullLiteral &&
-          leftOperand is SimpleIdentifier) {
-        identifier = leftOperand;
-      } else {
-        _coverageMarker();
-        return null;
-      }
-      if (identifier.staticElement is! LocalElement) {
-        _coverageMarker();
-        return null;
-      }
-      //
-      // Identify the expression executed when the variable is `null` and when
-      // it is non-`null`. Return if the `null` expression isn't a null literal
-      // or if the non-`null` expression isn't a method invocation whose target
-      // is the save variable being compared to `null`.
-      //
-      if (condition.operator.type == TokenType.EQ_EQ) {
-        nullExpression = conditional.thenExpression;
-        nonNullExpression = conditional.elseExpression;
-      } else if (condition.operator.type == TokenType.BANG_EQ) {
-        nonNullExpression = conditional.thenExpression;
-        nullExpression = conditional.elseExpression;
-      }
-      if (nullExpression == null || nonNullExpression == null) {
-        _coverageMarker();
-        return null;
-      }
-      if (nullExpression.unParenthesized is! NullLiteral) {
-        _coverageMarker();
-        return null;
-      }
-      Expression unwrappedExpression = nonNullExpression.unParenthesized;
-      Expression target;
-      Token operator;
-      if (unwrappedExpression is MethodInvocation) {
-        target = unwrappedExpression.target;
-        operator = unwrappedExpression.operator;
-      } else if (unwrappedExpression is PrefixedIdentifier) {
-        target = unwrappedExpression.prefix;
-        operator = unwrappedExpression.period;
-      } else {
-        _coverageMarker();
-        return null;
-      }
-      if (operator.type != TokenType.PERIOD) {
-        _coverageMarker();
-        return null;
-      }
-      if (!(target is SimpleIdentifier &&
-          target.staticElement == identifier.staticElement)) {
-        _coverageMarker();
-        return null;
-      }
-      periodOffset = operator.offset;
-
-      DartChangeBuilder changeBuilder = _newDartChangeBuilder();
-      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-        builder.addDeletion(range.startStart(node, nonNullExpression));
-        builder.addSimpleInsertion(periodOffset, '?');
-        builder.addDeletion(range.endEnd(nonNullExpression, node));
-      });
-      return changeBuilder;
-    }
-    return null;
-  }
-
-  Future<ChangeBuilder> createBuilder_convertToExpressionFunctionBody() async {
-    // prepare current body
-    FunctionBody body = getEnclosingFunctionBody();
-    if (body is! BlockFunctionBody || body.isGenerator) {
-      _coverageMarker();
-      return null;
-    }
-    // prepare return statement
-    List<Statement> statements = (body as BlockFunctionBody).block.statements;
-    if (statements.length != 1) {
-      _coverageMarker();
-      return null;
-    }
-    Statement onlyStatement = statements.first;
-    // prepare returned expression
-    Expression returnExpression;
-    if (onlyStatement is ReturnStatement) {
-      returnExpression = onlyStatement.expression;
-    } else if (onlyStatement is ExpressionStatement) {
-      returnExpression = onlyStatement.expression;
-    }
-    if (returnExpression == null) {
-      _coverageMarker();
-      return null;
-    }
-
-    // Return expressions can be quite large, e.g. Flutter build() methods.
-    // It is surprising to see this Quick Assist deep in the function body.
-    if (selectionOffset >= returnExpression.offset) {
-      _coverageMarker();
-      return null;
-    }
-
-    var changeBuilder = _newDartChangeBuilder();
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      builder.addReplacement(range.node(body), (DartEditBuilder builder) {
-        if (body.isAsynchronous) {
-          builder.write('async ');
-        }
-        builder.write('=> ');
-        builder.write(_getNodeText(returnExpression));
-        if (body.parent is! FunctionExpression ||
-            body.parent.parent is FunctionDeclaration) {
-          builder.write(';');
-        }
-      });
-    });
-    return changeBuilder;
-  }
-
-  /// Returns the text of the given node in the unit.
-  String /* TODO (pq): make visible */ _getNodeText(AstNode node) =>
-      utils.getNodeText(node);
-
-  FunctionBody getEnclosingFunctionBody() {
-    // TODO(brianwilkerson) Determine whether there is a reason why this method
-    // isn't just "return node.getAncestor((node) => node is FunctionBody);"
-    {
-      FunctionExpression function =
-          node.thisOrAncestorOfType<FunctionExpression>();
-      if (function != null) {
-        return function.body;
-      }
-    }
-    {
-      FunctionDeclaration function =
-          node.thisOrAncestorOfType<FunctionDeclaration>();
-      if (function != null) {
-        return function.functionExpression.body;
-      }
-    }
-    {
-      ConstructorDeclaration constructor =
-          node.thisOrAncestorOfType<ConstructorDeclaration>();
-      if (constructor != null) {
-        return constructor.body;
-      }
-    }
-    {
-      MethodDeclaration method = node.thisOrAncestorOfType<MethodDeclaration>();
-      if (method != null) {
-        return method.body;
-      }
-    }
-    return null;
-  }
-
   Future<ChangeBuilder>
       createBuilder_addTypeAnnotation_VariableDeclaration() async {
     AstNode node = this.node;
@@ -391,6 +215,90 @@
     return validChange ? changeBuilder : null;
   }
 
+  Future<ConvertToSpreadCollectionsChange>
+      createBuilder_convertAddAllToSpread() async {
+    AstNode node = this.node;
+    if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
+      _coverageMarker();
+      return null;
+    }
+    SimpleIdentifier name = node;
+    MethodInvocation invocation = node.parent;
+    if (name != invocation.methodName ||
+        name.name != 'addAll' ||
+        !invocation.isCascaded ||
+        invocation.argumentList.arguments.length != 1) {
+      _coverageMarker();
+      return null;
+    }
+    CascadeExpression cascade = invocation.thisOrAncestorOfType();
+    NodeList<Expression> sections = cascade.cascadeSections;
+    Expression target = cascade.target;
+    if (target is! ListLiteral || sections[0] != invocation) {
+      // TODO(brianwilkerson) Consider extending this to handle set literals.
+      _coverageMarker();
+      return null;
+    }
+
+    bool isEmptyListLiteral(Expression expression) =>
+        expression is ListLiteral && expression.elements.isEmpty;
+
+    ListLiteral list = target;
+    Expression argument = invocation.argumentList.arguments[0];
+    String elementText;
+    ConvertToSpreadCollectionsChange change =
+        ConvertToSpreadCollectionsChange();
+    List<String> args = null;
+    if (argument is BinaryExpression &&
+        argument.operator.type == TokenType.QUESTION_QUESTION) {
+      Expression right = argument.rightOperand;
+      if (isEmptyListLiteral(right)) {
+        // ..addAll(things ?? const [])
+        // ..addAll(things ?? [])
+        elementText = '...?${utils.getNodeText(argument.leftOperand)}';
+      }
+    } else if (experimentStatus.control_flow_collections &&
+        argument is ConditionalExpression) {
+      Expression elseExpression = argument.elseExpression;
+      if (isEmptyListLiteral(elseExpression)) {
+        // ..addAll(condition ? things : const [])
+        // ..addAll(condition ? things : [])
+        String conditionText = utils.getNodeText(argument.condition);
+        String thenText = utils.getNodeText(argument.thenExpression);
+        elementText = 'if ($conditionText) ...$thenText';
+      }
+    } else if (argument is ListLiteral) {
+      // ..addAll([ ... ])
+      NodeList<CollectionElement> elements = argument.elements;
+      if (elements.isEmpty) {
+        // TODO(brianwilkerson) Consider adding a cleanup for the empty list
+        //  case. We can essentially remove the whole invocation because it does
+        //  nothing.
+        return null;
+      }
+      int startOffset = elements.first.offset;
+      int endOffset = elements.last.end;
+      elementText = utils.getText(startOffset, endOffset - startOffset);
+      change.isLineInvocation = true;
+      args = ['addAll'];
+    }
+    elementText ??= '...${utils.getNodeText(argument)}';
+    DartChangeBuilder changeBuilder = _newDartChangeBuilder();
+    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+      if (list.elements.isNotEmpty) {
+        // ['a']..addAll(['b', 'c']);
+        builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
+      } else {
+        // []..addAll(['b', 'c']);
+        builder.addSimpleInsertion(list.leftBracket.end, elementText);
+      }
+      builder.addDeletion(range.node(invocation));
+    });
+    change.args = args;
+    change.builder = changeBuilder;
+    return change;
+  }
+
   Future<ChangeBuilder>
       createBuilder_convertConditionalExpressionToIfElement() async {
     AstNode node = this.node.thisOrAncestorOfType<ConditionalExpression>();
@@ -649,6 +557,111 @@
     return changeBuilder;
   }
 
+  Future<ChangeBuilder> createBuilder_convertQuotes(bool fromDouble) async {
+    if (node is SimpleStringLiteral) {
+      SimpleStringLiteral literal = node;
+      if (fromDouble ? !literal.isSingleQuoted : literal.isSingleQuoted) {
+        String newQuote = literal.isMultiline
+            ? (fromDouble ? "'''" : '"""')
+            : (fromDouble ? "'" : '"');
+        int quoteLength = literal.isMultiline ? 3 : 1;
+        String lexeme = literal.literal.lexeme;
+        if (lexeme.indexOf(newQuote) < 0) {
+          var changeBuilder = _newDartChangeBuilder();
+          await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+            builder.addSimpleReplacement(
+                new SourceRange(
+                    literal.offset + (literal.isRaw ? 1 : 0), quoteLength),
+                newQuote);
+            builder.addSimpleReplacement(
+                new SourceRange(literal.end - quoteLength, quoteLength),
+                newQuote);
+          });
+          return changeBuilder;
+        }
+      }
+    } else if (node is InterpolationString) {
+      StringInterpolation parent = node.parent;
+      if (fromDouble ? !parent.isSingleQuoted : parent.isSingleQuoted) {
+        String newQuote = parent.isMultiline
+            ? (fromDouble ? "'''" : '"""')
+            : (fromDouble ? "'" : '"');
+        int quoteLength = parent.isMultiline ? 3 : 1;
+        NodeList<InterpolationElement> elements = parent.elements;
+        for (int i = 0; i < elements.length; i++) {
+          InterpolationElement element = elements[i];
+          if (element is InterpolationString) {
+            String lexeme = element.contents.lexeme;
+            if (lexeme.indexOf(newQuote) >= 0) {
+              return null;
+            }
+          }
+        }
+        var changeBuilder = _newDartChangeBuilder();
+        await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+          builder.addSimpleReplacement(
+              new SourceRange(
+                  parent.offset + (parent.isRaw ? 1 : 0), quoteLength),
+              newQuote);
+          builder.addSimpleReplacement(
+              new SourceRange(parent.end - quoteLength, quoteLength), newQuote);
+        });
+        return changeBuilder;
+      }
+    }
+    return null;
+  }
+
+  Future<ChangeBuilder> createBuilder_convertToExpressionFunctionBody() async {
+    // prepare current body
+    FunctionBody body = getEnclosingFunctionBody();
+    if (body is! BlockFunctionBody || body.isGenerator) {
+      _coverageMarker();
+      return null;
+    }
+    // prepare return statement
+    List<Statement> statements = (body as BlockFunctionBody).block.statements;
+    if (statements.length != 1) {
+      _coverageMarker();
+      return null;
+    }
+    Statement onlyStatement = statements.first;
+    // prepare returned expression
+    Expression returnExpression;
+    if (onlyStatement is ReturnStatement) {
+      returnExpression = onlyStatement.expression;
+    } else if (onlyStatement is ExpressionStatement) {
+      returnExpression = onlyStatement.expression;
+    }
+    if (returnExpression == null) {
+      _coverageMarker();
+      return null;
+    }
+
+    // Return expressions can be quite large, e.g. Flutter build() methods.
+    // It is surprising to see this Quick Assist deep in the function body.
+    if (selectionOffset >= returnExpression.offset) {
+      _coverageMarker();
+      return null;
+    }
+
+    var changeBuilder = _newDartChangeBuilder();
+    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addReplacement(range.node(body), (DartEditBuilder builder) {
+        if (body.isAsynchronous) {
+          builder.write('async ');
+        }
+        builder.write('=> ');
+        builder.write(_getNodeText(returnExpression));
+        if (body.parent is! FunctionExpression ||
+            body.parent.parent is FunctionDeclaration) {
+          builder.write(';');
+        }
+      });
+    });
+    return changeBuilder;
+  }
+
   Future<ChangeBuilder> createBuilder_convertToIntLiteral() async {
     if (node is! DoubleLiteral) {
       _coverageMarker();
@@ -676,6 +689,135 @@
     return changeBuilder;
   }
 
+  Future<ChangeBuilder> createBuilder_convertToNullAware() async {
+    AstNode node = this.node;
+    if (node is! ConditionalExpression) {
+      _coverageMarker();
+      return null;
+    }
+    ConditionalExpression conditional = node;
+    Expression condition = conditional.condition.unParenthesized;
+    SimpleIdentifier identifier;
+    Expression nullExpression;
+    Expression nonNullExpression;
+    int periodOffset;
+
+    if (condition is BinaryExpression) {
+      //
+      // Identify the variable being compared to `null`, or return if the
+      // condition isn't a simple comparison of `null` to a variable's value.
+      //
+      Expression leftOperand = condition.leftOperand;
+      Expression rightOperand = condition.rightOperand;
+      if (leftOperand is NullLiteral && rightOperand is SimpleIdentifier) {
+        identifier = rightOperand;
+      } else if (rightOperand is NullLiteral &&
+          leftOperand is SimpleIdentifier) {
+        identifier = leftOperand;
+      } else {
+        _coverageMarker();
+        return null;
+      }
+      if (identifier.staticElement is! LocalElement) {
+        _coverageMarker();
+        return null;
+      }
+      //
+      // Identify the expression executed when the variable is `null` and when
+      // it is non-`null`. Return if the `null` expression isn't a null literal
+      // or if the non-`null` expression isn't a method invocation whose target
+      // is the save variable being compared to `null`.
+      //
+      if (condition.operator.type == TokenType.EQ_EQ) {
+        nullExpression = conditional.thenExpression;
+        nonNullExpression = conditional.elseExpression;
+      } else if (condition.operator.type == TokenType.BANG_EQ) {
+        nonNullExpression = conditional.thenExpression;
+        nullExpression = conditional.elseExpression;
+      }
+      if (nullExpression == null || nonNullExpression == null) {
+        _coverageMarker();
+        return null;
+      }
+      if (nullExpression.unParenthesized is! NullLiteral) {
+        _coverageMarker();
+        return null;
+      }
+      Expression unwrappedExpression = nonNullExpression.unParenthesized;
+      Expression target;
+      Token operator;
+      if (unwrappedExpression is MethodInvocation) {
+        target = unwrappedExpression.target;
+        operator = unwrappedExpression.operator;
+      } else if (unwrappedExpression is PrefixedIdentifier) {
+        target = unwrappedExpression.prefix;
+        operator = unwrappedExpression.period;
+      } else {
+        _coverageMarker();
+        return null;
+      }
+      if (operator.type != TokenType.PERIOD) {
+        _coverageMarker();
+        return null;
+      }
+      if (!(target is SimpleIdentifier &&
+          target.staticElement == identifier.staticElement)) {
+        _coverageMarker();
+        return null;
+      }
+      periodOffset = operator.offset;
+
+      DartChangeBuilder changeBuilder = _newDartChangeBuilder();
+      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+        builder.addDeletion(range.startStart(node, nonNullExpression));
+        builder.addSimpleInsertion(periodOffset, '?');
+        builder.addDeletion(range.endEnd(nonNullExpression, node));
+      });
+      return changeBuilder;
+    }
+    return null;
+  }
+
+  Future<ChangeBuilder> createBuilder_convertToPackageImport() async {
+    var node = this.node;
+    if (node is StringLiteral) {
+      node = node.parent;
+    }
+    if (node is ImportDirective) {
+      ImportDirective importDirective = node;
+      var uriSource = importDirective.uriSource;
+
+      // Ignore if invalid URI.
+      if (uriSource == null) {
+        return null;
+      }
+
+      var importUri = uriSource.uri;
+      if (importUri.scheme != 'package') {
+        return null;
+      }
+
+      // Don't offer to convert a 'package:' URI to itself.
+      try {
+        if (Uri.parse(importDirective.uriContent).scheme == 'package') {
+          return null;
+        }
+      } on FormatException {
+        return null;
+      }
+
+      var changeBuilder = _newDartChangeBuilder();
+      await changeBuilder.addFileEdit(file, (builder) {
+        builder.addSimpleReplacement(
+          range.node(importDirective.uri),
+          "'$importUri'",
+        );
+      });
+      return changeBuilder;
+    }
+    return null;
+  }
+
   @protected
   Future<ChangeBuilder> createBuilder_useCurlyBraces() async {
     Future<ChangeBuilder> doStatement(DoStatement node) async {
@@ -803,6 +945,39 @@
     return null;
   }
 
+  FunctionBody getEnclosingFunctionBody() {
+    // TODO(brianwilkerson) Determine whether there is a reason why this method
+    // isn't just "return node.getAncestor((node) => node is FunctionBody);"
+    {
+      FunctionExpression function =
+          node.thisOrAncestorOfType<FunctionExpression>();
+      if (function != null) {
+        return function.body;
+      }
+    }
+    {
+      FunctionDeclaration function =
+          node.thisOrAncestorOfType<FunctionDeclaration>();
+      if (function != null) {
+        return function.functionExpression.body;
+      }
+    }
+    {
+      ConstructorDeclaration constructor =
+          node.thisOrAncestorOfType<ConstructorDeclaration>();
+      if (constructor != null) {
+        return constructor.body;
+      }
+    }
+    {
+      MethodDeclaration method = node.thisOrAncestorOfType<MethodDeclaration>();
+      if (method != null) {
+        return method.body;
+      }
+    }
+    return null;
+  }
+
   @protected
   bool setupCompute() {
     final locator = NodeLocator(selectionOffset, selectionEnd);
@@ -822,6 +997,10 @@
     }
   }
 
+  /// Returns the text of the given node in the unit.
+  String /* TODO (pq): make visible */ _getNodeText(AstNode node) =>
+      utils.getNodeText(node);
+
   DartChangeBuilder _newDartChangeBuilder() =>
       DartChangeBuilderImpl.forWorkspace(workspace);
 
@@ -833,6 +1012,12 @@
   static void _coverageMarker() {}
 }
 
+class ConvertToSpreadCollectionsChange {
+  ChangeBuilder builder;
+  List<String> args;
+  bool isLineInvocation = false;
+}
+
 /// A visitor that can be used to find references to a parameter.
 class _ParameterReferenceFinder extends RecursiveAstVisitor<void> {
   /// The parameter for which references are being sought, or `null` if we are
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index ff70d93..bac44cb 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -199,6 +199,12 @@
       'CONVERT_TO_NAMED_ARGUMENTS', 50, "Convert to named arguments");
   static const CONVERT_TO_NULL_AWARE =
       const FixKind('CONVERT_TO_NULL_AWARE', 50, "Convert to use '?.'");
+  static const CONVERT_TO_PACKAGE_IMPORT = const FixKind(
+      'CONVERT_TO_PACKAGE_IMPORT', 50, "Convert to 'package:' import");
+  static const CONVERT_TO_SINGLE_QUOTED_STRING = const FixKind(
+      'CONVERT_TO_SINGLE_QUOTED_STRING', 50, "Convert to single quoted string");
+  static const CONVERT_TO_SPREAD =
+      const FixKind('CONVERT_TO_SPREAD', 50, "Convert to a spread");
   static const CREATE_CLASS =
       const FixKind('CREATE_CLASS', 50, "Create class '{0}'");
   static const CREATE_CONSTRUCTOR =
@@ -245,6 +251,8 @@
       const FixKind('IMPORT_LIBRARY_SDK', 54, "Import library '{0}'");
   static const IMPORT_LIBRARY_SHOW =
       const FixKind('IMPORT_LIBRARY_SHOW', 55, "Update library '{0}' import");
+  static const INLINE_INVOCATION =
+      const FixKind('INLINE_INVOCATION', 30, "Inline invocation of '{0}'");
   static const INSERT_SEMICOLON =
       const FixKind('INSERT_SEMICOLON', 50, "Insert ';'");
   static const MAKE_CLASS_ABSTRACT =
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 0a857ce..491d0e2 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -585,6 +585,9 @@
       if (name == LintNames.avoid_init_to_null) {
         await _addFix_removeInitializer();
       }
+      if (name == LintNames.avoid_relative_lib_imports) {
+        await _addFix_convertToPackageImport();
+      }
       if (name == LintNames.avoid_return_types_on_setters) {
         await _addFix_removeTypeAnnotation();
       }
@@ -656,9 +659,15 @@
       if (name == LintNames.prefer_null_aware_operators) {
         await _addFix_convertToNullAware();
       }
+      if (name == LintNames.prefer_single_quotes) {
+        await _addFix_convertSingleQuotes();
+      }
       if (errorCode.name == LintNames.slash_for_doc_comments) {
         await _addFix_convertDocumentationIntoLine();
       }
+      if (name == LintNames.prefer_spread_collections) {
+        await _addFix_convertAddAllToSpread();
+      }
       if (name == LintNames.type_init_formals) {
         await _addFix_removeTypeAnnotation();
       }
@@ -738,11 +747,6 @@
     _addFixFromBuilder(changeBuilder, DartFixKind.ADD_CURLY_BRACES);
   }
 
-  Future<void> _addFix_convertToNullAware() async {
-    final changeBuilder = await createBuilder_convertToNullAware();
-    _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_NULL_AWARE);
-  }
-
   Future<void> _addFix_addExplicitCast() async {
     if (coveredNode is! Expression) {
       return;
@@ -1368,6 +1372,12 @@
     _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_FOR_ELEMENT);
   }
 
+  Future<void> _addFix_convertSingleQuotes() async {
+    final changeBuilder = await createBuilder_convertQuotes(true);
+    _addFixFromBuilder(
+        changeBuilder, DartFixKind.CONVERT_TO_SINGLE_QUOTED_STRING);
+  }
+
   Future<void> _addFix_convertToExpressionBody() async {
     final changeBuilder = await createBuilder_convertToExpressionFunctionBody();
     _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_INTO_EXPRESSION_BODY);
@@ -1449,6 +1459,16 @@
     }
   }
 
+  Future<void> _addFix_convertToNullAware() async {
+    final changeBuilder = await createBuilder_convertToNullAware();
+    _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_NULL_AWARE);
+  }
+
+  Future<void> _addFix_convertToPackageImport() async {
+    final changeBuilder = await createBuilder_convertToPackageImport();
+    _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_PACKAGE_IMPORT);
+  }
+
   Future<void> _addFix_createClass() async {
     Element prefixElement = null;
     String name = null;
@@ -1857,6 +1877,16 @@
     }
   }
 
+  Future<void> _addFix_convertAddAllToSpread() async {
+    final change = await createBuilder_convertAddAllToSpread();
+    if (change != null) {
+      final kind = change.isLineInvocation
+          ? DartFixKind.INLINE_INVOCATION
+          : DartFixKind.CONVERT_TO_SPREAD;
+      _addFixFromBuilder(change.builder, kind, args: change.args);
+    }
+  }
+
   Future<void> _addFix_createField() async {
     if (node is! SimpleIdentifier) {
       return;
diff --git a/pkg/analysis_server/lib/src/services/linter/lint_names.dart b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
index c52000b..b935e7f 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -12,6 +12,7 @@
       'avoid_annotating_with_dynamic';
   static const String avoid_empty_else = 'avoid_empty_else';
   static const String avoid_init_to_null = 'avoid_init_to_null';
+  static const String avoid_relative_lib_imports = 'avoid_relative_lib_imports';
   static const String avoid_return_types_on_setters =
       'avoid_return_types_on_setters';
   static const String avoid_types_on_closure_parameters =
@@ -46,7 +47,9 @@
   static const String prefer_is_not_empty = 'prefer_is_not_empty';
   static const String prefer_null_aware_operators =
       'prefer_null_aware_operators';
+  static const String prefer_single_quotes = 'prefer_single_quotes';
   static const String slash_for_doc_comments = 'slash_for_doc_comments';
+  static const String prefer_spread_collections = 'prefer_spread_collections';
   static const String type_annotate_public_apis = 'type_annotate_public_apis';
   static const String type_init_formals = 'type_init_formals';
   static const String unawaited_futures = 'unawaited_futures';
diff --git a/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart b/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart
index e6704f8..d9f168d 100644
--- a/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart
+++ b/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart
@@ -181,6 +181,7 @@
         ElementKind.CONSTRUCTOR,
         ElementKind.ENUM,
         ElementKind.ENUM_CONSTANT,
+        ElementKind.EXTENSION,
         ElementKind.FUNCTION,
         ElementKind.FUNCTION_TYPE_ALIAS,
         ElementKind.MIXIN,
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_package_import_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_package_import_test.dart
index 84df167..9da35b6 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_package_import_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_package_import_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -52,7 +53,7 @@
 
   test_nonPackage_Uri() async {
     addSource('/home/test/lib/foo.dart', '');
-
+    testFile = convertPath('/home/test/lib/src/test.dart');
     await resolveTestUnit('''
 import 'dart:core';
 ''');
@@ -83,4 +84,15 @@
 import 'package:test/foo/bar.dart';
 ''');
   }
+
+  test_relativeImport_noAssistWithLint() async {
+    createAnalysisOptionsFile(lints: [LintNames.avoid_relative_lib_imports]);
+    verifyNoTestUnitErrors = false;
+    addSource('/home/test/lib/foo.dart', '');
+
+    await resolveTestUnit('''
+import '../lib/foo.dart';
+''');
+    await assertNoAssist();
+  }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_single_quoted_string_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_single_quoted_string_test.dart
index 161f62c..6c34598 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_single_quoted_string_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_single_quoted_string_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -80,6 +81,17 @@
 ''');
   }
 
+  test_one_simple_noAssistWithLint() async {
+    createAnalysisOptionsFile(lints: [LintNames.prefer_single_quotes]);
+    verifyNoTestUnitErrors = false;
+    await resolveTestUnit('''
+main() {
+  print("abc");
+}
+''');
+    await assertNoAssist();
+  }
+
   test_three_embeddedTarget() async {
     await resolveTestUnit('''
 main() {
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart
index 6242b56..4e354c7 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -41,6 +42,18 @@
 ''');
   }
 
+  test_addAll_expression_noAssistWithLint() async {
+    createAnalysisOptionsFile(lints: [LintNames.prefer_spread_collections]);
+    verifyNoTestUnitErrors = false;
+    await resolveTestUnit('''
+f() {
+  var ints = [1, 2, 3];
+  print(['a']..addAl/*caret*/l(ints.map((i) => i.toString()))..addAll(['c']));
+}
+''');
+    await assertNoAssist();
+  }
+
   test_addAll_expression_toEmptyList() async {
     await resolveTestUnit('''
 f() {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_package_import_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_package_import_test.dart
new file mode 100644
index 0000000..dfa4706
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_package_import_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for 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:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConvertToPackageImportTest);
+  });
+}
+
+@reflectiveTest
+class ConvertToPackageImportTest extends FixProcessorLintTest {
+  @override
+  FixKind get kind => DartFixKind.CONVERT_TO_PACKAGE_IMPORT;
+
+  @override
+  String get lintCode => LintNames.avoid_relative_lib_imports;
+
+  /// More coverage in the `convert_to_package_import_test.dart` assist test.
+  test_relativeImport() async {
+    addSource('/home/test/lib/foo.dart', '');
+    testFile = convertPath('/home/test/lib/src/test.dart');
+    await resolveTestUnit('''
+import /*LINT*/'../lib/foo.dart';
+''');
+
+    await assertHasFix('''
+import /*LINT*/'package:test/lib/foo.dart';
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_single_quoted_string_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_single_quoted_string_test.dart
new file mode 100644
index 0000000..97e2746
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_single_quoted_string_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for 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:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConvertToSingleQuotedStringTest);
+  });
+}
+
+@reflectiveTest
+class ConvertToSingleQuotedStringTest extends FixProcessorLintTest {
+  @override
+  FixKind get kind => DartFixKind.CONVERT_TO_SINGLE_QUOTED_STRING;
+
+  @override
+  String get lintCode => LintNames.prefer_single_quotes;
+
+  /// More coverage in the `convert_to_single_quoted_string_test.dart` assist test.
+  test_one_simple() async {
+    await resolveTestUnit('''
+main() {
+  print(/*LINT*/"abc");
+}
+''');
+    await assertHasFix('''
+main() {
+  print(/*LINT*/'abc');
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_spread_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_spread_test.dart
new file mode 100644
index 0000000..a2cf96e
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_spread_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for 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:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConvertToSpreadTest);
+  });
+}
+
+@reflectiveTest
+class ConvertToSpreadTest extends FixProcessorLintTest {
+  @override
+  FixKind get kind => DartFixKind.CONVERT_TO_SPREAD;
+
+  @override
+  String get lintCode => LintNames.prefer_spread_collections;
+
+  /// More coverage in the `convert_to_spread_test.dart` assist test.
+  test_addAll_expression() async {
+    await resolveTestUnit('''
+f() {
+  var ints = [1, 2, 3];
+  print(['a']../*LINT*/addAll(ints.map((i) => i.toString()))..addAll(['c']));
+}
+''');
+    await assertHasFix('''
+f() {
+  var ints = [1, 2, 3];
+  print(['a', ...ints.map((i) => i.toString())]..addAll(['c']));
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index 67efef9..4e74718 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -43,6 +43,10 @@
 import 'convert_to_int_literal_test.dart' as convert_to_int_literal;
 import 'convert_to_named_arguments_test.dart' as convert_to_named_arguments;
 import 'convert_to_null_aware_test.dart' as convert_to_null_aware;
+import 'convert_to_package_import_test.dart' as convert_to_package_import;
+import 'convert_to_single_quoted_string_test.dart'
+    as convert_to_single_quoted_string;
+import 'convert_to_spread_test.dart' as convert_to_spread;
 import 'create_class_test.dart' as create_class;
 import 'create_constructor_for_final_fields_test.dart'
     as create_constructor_for_final_field;
@@ -156,6 +160,9 @@
     convert_to_int_literal.main();
     convert_to_named_arguments.main();
     convert_to_null_aware.main();
+    convert_to_package_import.main();
+    convert_to_single_quoted_string.main();
+    convert_to_spread.main();
     create_class.main();
     create_constructor_for_final_field.main();
     create_constructor_super.main();
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 1b18be9..02fdde9 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -825,7 +825,8 @@
 ///        [Expression] cascadeSection*
 ///
 ///    cascadeSection ::=
-///        '..'  (cascadeSelector arguments*) (assignableSelector arguments*)*
+///        ('..' | '?..') (cascadeSelector arguments*)
+///        (assignableSelector arguments*)*
 ///        (assignmentOperator expressionWithoutCascade)?
 ///
 ///    cascadeSelector ::=
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 2b09546..0d75a23 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -2396,6 +2396,8 @@
     ErrorCode errorCode = error.errorCode;
     if (errorCode is CompileTimeErrorCode) {
       switch (errorCode) {
+        case CompileTimeErrorCode
+            .CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST:
         case CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL:
         case CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT:
         case CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING:
@@ -2405,8 +2407,7 @@
         case CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE:
         case CompileTimeErrorCode.CONST_WITH_NON_CONST:
         case CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT:
-        case CompileTimeErrorCode
-            .CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST:
+        case CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS:
         case CompileTimeErrorCode.INVALID_CONSTANT:
         case CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL:
         case CompileTimeErrorCode.MISSING_CONST_IN_MAP_LITERAL:
@@ -5912,8 +5913,8 @@
   /// index expression is part of a cascade expression.
   ExpressionImpl _target;
 
-  /// The period ("..") before a cascaded index expression, or `null` if this
-  /// index expression is not part of a cascade expression.
+  /// The period (".." | "?..") before a cascaded index expression,
+  /// or `null` if this index expression is not part of a cascade expression.
   @override
   Token period;
 
@@ -7130,7 +7131,7 @@
   /// The operator that separates the target from the method name, or `null`
   /// if there is no target. In an ordinary method invocation this will be a
   /// period ('.'). In a cascade section this will be the cascade operator
-  /// ('..').
+  /// ('..' | '?..').
   @override
   Token operator;
 
@@ -7179,7 +7180,9 @@
 
   @override
   bool get isCascaded =>
-      operator != null && operator.type == TokenType.PERIOD_PERIOD;
+      operator != null &&
+      (operator.type == TokenType.PERIOD_PERIOD ||
+          operator.type == TokenType.QUESTION_PERIOD_PERIOD);
 
   @override
   SimpleIdentifier get methodName => _methodName;
@@ -8436,7 +8439,9 @@
 
   @override
   bool get isCascaded =>
-      operator != null && operator.type == TokenType.PERIOD_PERIOD;
+      operator != null &&
+      (operator.type == TokenType.PERIOD_PERIOD ||
+          operator.type == TokenType.QUESTION_PERIOD_PERIOD);
 
   @override
   Precedence get precedence => Precedence.postfix;
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index bbff1e7..86d5b66 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -7526,7 +7526,7 @@
   @override
   void visitIndexExpression(IndexExpression node) {
     if (node.isCascaded) {
-      _writer.print("..");
+      _writer.print(node.period.lexeme);
     } else {
       _visitNode(node.target);
     }
@@ -7635,7 +7635,7 @@
   @override
   void visitMethodInvocation(MethodInvocation node) {
     if (node.isCascaded) {
-      _writer.print("..");
+      _writer.print(node.operator.lexeme);
     } else {
       if (node.target != null) {
         node.target.accept(this);
@@ -7735,7 +7735,7 @@
   @override
   void visitPropertyAccess(PropertyAccess node) {
     if (node.isCascaded) {
-      _writer.print("..");
+      _writer.print(node.operator.lexeme);
     } else {
       _visitNode(node.target);
       _writer.print(node.operator.lexeme);
@@ -8833,7 +8833,7 @@
   @override
   void visitIndexExpression(IndexExpression node) {
     if (node.isCascaded) {
-      sink.write("..");
+      sink.write(node.period.lexeme);
     } else {
       safelyVisitNode(node.target);
     }
@@ -8942,7 +8942,7 @@
   @override
   void visitMethodInvocation(MethodInvocation node) {
     if (node.isCascaded) {
-      sink.write("..");
+      sink.write(node.operator.lexeme);
     } else {
       if (node.target != null) {
         node.target.accept(this);
@@ -9042,7 +9042,7 @@
   @override
   void visitPropertyAccess(PropertyAccess node) {
     if (node.isCascaded) {
-      sink.write("..");
+      sink.write(node.operator.lexeme);
     } else {
       safelyVisitNode(node.target);
       sink.write(node.operator.lexeme);
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 76ba63d..0d8b1c2 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -734,7 +734,7 @@
    */
   static const HintCode SDK_VERSION_EXTENSION_METHODS = const HintCode(
       'SDK_VERSION_EXTENSION_METHODS',
-      "Extension methods weren't supported until version 2.X.0, "
+      "Extension methods weren't supported until version 2.6.0, "
           "but this code is required to be able to run on earlier versions.",
       correction: "Try updating the SDK constraints.");
 
diff --git a/pkg/analyzer/lib/src/error/literal_element_verifier.dart b/pkg/analyzer/lib/src/error/literal_element_verifier.dart
index 5e2e26c..fb2cced 100644
--- a/pkg/analyzer/lib/src/error/literal_element_verifier.dart
+++ b/pkg/analyzer/lib/src/error/literal_element_verifier.dart
@@ -4,7 +4,6 @@
 
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/element/type.dart';
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index f45a35a..fa944a9 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -169,7 +169,7 @@
   }
 
   void beginCascade(Token token) {
-    assert(optional('..', token));
+    assert(optional('..', token) || optional('?..', token));
     debugEvent("beginCascade");
 
     Expression expression = pop();
@@ -577,12 +577,14 @@
     assert(operatorToken.isOperator ||
         optional('.', operatorToken) ||
         optional('?.', operatorToken) ||
-        optional('..', operatorToken));
+        optional('..', operatorToken) ||
+        optional('?..', operatorToken));
     debugEvent("BinaryExpression");
 
     if (identical(".", operatorToken.stringValue) ||
         identical("?.", operatorToken.stringValue) ||
-        identical("..", operatorToken.stringValue)) {
+        identical("..", operatorToken.stringValue) ||
+        identical("?..", operatorToken.stringValue)) {
       doDotExpression(operatorToken);
     } else {
       Expression right = pop();
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 8518284..e91190e 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -173,8 +173,8 @@
         String methodName = operatorType.lexeme;
         // TODO(brianwilkerson) Change the [methodNameNode] from the left hand
         //  side to the operator.
-        ResolutionResult result =
-            _lookUpMethod(leftHandSide, staticType, methodName, leftHandSide);
+        var result = _newPropertyResolver().resolveOperator(
+            leftHandSide, staticType, methodName, leftHandSide);
         node.staticElement = result.function;
         if (_shouldReportInvalidMember(staticType, result)) {
           _recordUndefinedToken(
@@ -266,20 +266,11 @@
         }
         if (node.newKeyword == null) {
           if (element is ClassElement) {
-            Element memberElement =
-                _lookupGetterOrMethod(element.type, name.name);
-            if (memberElement == null) {
-              memberElement = element.getNamedConstructor(name.name);
-              if (memberElement == null) {
-                memberElement =
-                    _lookUpSetter(prefix, element.type, name.name, name).setter;
-              }
-            }
-            if (memberElement == null) {
-//              reportGetterOrSetterNotFound(identifier, name, element.getDisplayName());
-            } else {
-              name.staticElement = memberElement;
-            }
+            var propertyResolver = _newPropertyResolver();
+            propertyResolver.resolve(prefix, element.type, name.name, name);
+            name.staticElement = propertyResolver.getterResult.getter ??
+                propertyResolver.setterResult.setter ??
+                element.getNamedConstructor(name.name);
           } else {
             // TODO(brianwilkerson) Report this error.
           }
@@ -481,16 +472,16 @@
     bool isInSetterContext = node.inSetterContext();
     if (isInGetterContext && isInSetterContext) {
       // lookup setter
-      ResolutionResult setterResult =
-          _lookUpMethod(target, staticType, setterMethodName, target);
+      ResolutionResult setterResult = _newPropertyResolver()
+          .resolveOperator(target, staticType, setterMethodName, target);
       // set setter element
       node.staticElement = setterResult.function;
       // generate undefined method warning
       _checkForUndefinedIndexOperator(
           node, target, setterMethodName, setterResult, staticType);
       // lookup getter method
-      ResolutionResult getterResult =
-          _lookUpMethod(target, staticType, getterMethodName, target);
+      ResolutionResult getterResult = _newPropertyResolver()
+          .resolveOperator(target, staticType, getterMethodName, target);
       // set getter element
       AuxiliaryElements auxiliaryElements =
           new AuxiliaryElements(getterResult.function, null);
@@ -500,8 +491,8 @@
           node, target, getterMethodName, getterResult, staticType);
     } else if (isInGetterContext) {
       // lookup getter method
-      ResolutionResult methodResult =
-          _lookUpMethod(target, staticType, getterMethodName, target);
+      ResolutionResult methodResult = _newPropertyResolver()
+          .resolveOperator(target, staticType, getterMethodName, target);
       // set getter element
       node.staticElement = methodResult.function;
       // generate undefined method warning
@@ -509,8 +500,8 @@
           node, target, getterMethodName, methodResult, staticType);
     } else if (isInSetterContext) {
       // lookup setter method
-      ResolutionResult methodResult =
-          _lookUpMethod(target, staticType, setterMethodName, target);
+      ResolutionResult methodResult = _newPropertyResolver()
+          .resolveOperator(target, staticType, setterMethodName, target);
       // set setter element
       node.staticElement = methodResult.function;
       // generate undefined method warning
@@ -566,10 +557,8 @@
     }
     String methodName = _getPostfixOperator(node);
     DartType staticType = _getStaticType(operand);
-    // TODO(brianwilkerson) Change the [methodNameNode] from the operand to
-    //  the operator.
-    ResolutionResult result =
-        _lookUpMethod(operand, staticType, methodName, operand);
+    var result = _newPropertyResolver()
+        .resolveOperator(operand, staticType, methodName, operand);
     node.staticElement = result.function;
     if (_shouldReportInvalidMember(staticType, result)) {
       if (operand is SuperExpression) {
@@ -674,10 +663,8 @@
       Expression operand = node.operand;
       String methodName = _getPrefixOperator(node);
       DartType staticType = _getStaticType(operand, read: true);
-      // TODO(brianwilkerson) Change the [methodNameNode] from the operand to
-      //  the operator.
-      ResolutionResult result =
-          _lookUpMethod(operand, staticType, methodName, operand);
+      var result = _newPropertyResolver()
+          .resolveOperator(operand, staticType, methodName, operand);
       node.staticElement = result.function;
       if (_shouldReportInvalidMember(staticType, result)) {
         if (operand is SuperExpression) {
@@ -874,9 +861,12 @@
         node.inGetterContext() &&
         enclosingClass != null) {
       InterfaceType enclosingType = enclosingClass.type;
-      AuxiliaryElements auxiliaryElements = new AuxiliaryElements(
-          _lookUpGetter(null, enclosingType, node.name, node).getter, null);
-      node.auxiliaryElements = auxiliaryElements;
+      var propertyResolver = _newPropertyResolver();
+      propertyResolver.resolve(null, enclosingType, node.name, node);
+      node.auxiliaryElements = AuxiliaryElements(
+        propertyResolver.getterResult.getter,
+        null,
+      );
     }
     //
     // Validate annotation element.
@@ -1090,8 +1080,10 @@
       parameterizableType = invokeType;
       parameters = invokeType.typeFormals;
     } else if (invokeType is InterfaceType) {
-      MethodElement callMethod =
-          _lookUpCallMethod(invokeType, invocation.function);
+      var propertyResolver = _newPropertyResolver();
+      propertyResolver.resolve(null, invokeType,
+          FunctionElement.CALL_METHOD_NAME, invocation.function);
+      MethodElement callMethod = propertyResolver.getterResult.function;
       invocation.staticElement = callMethod;
       parameterizableType = callMethod?.type;
       parameters = (parameterizableType as FunctionType)?.typeFormals;
@@ -1210,135 +1202,9 @@
     }
   }
 
-  /**
-   * Return the element representing the `call` method that is defined for the
-   * given [type]. If there are multiple `call` methods defined by extensions,
-   * use the given [node] to report the error.
-   */
-  MethodElement _lookUpCallMethod(InterfaceType type, Expression node) {
-    var callMethod = type.lookUpMethod(
-      FunctionElement.CALL_METHOD_NAME,
-      _resolver.definingLibrary,
-    );
-    if (callMethod != null) {
-      return callMethod;
-    }
-
-    var result = _extensionResolver.findExtension(
-        type, FunctionElement.CALL_METHOD_NAME, node);
-    var instantiatedMember = result.function;
-    if (instantiatedMember is MethodElement) {
-      return instantiatedMember;
-    }
-
-    return null;
-  }
-
-  /**
-   * Look up the getter with the given [name] in the given [type]. Return a
-   * result representing the result of that lookup. The [target] is the target
-   * of the invocation, or `null` if there is no target.
-   */
-  ResolutionResult _lookUpGetter(
-      Expression target, DartType type, String name, Expression nameNode) {
-    type = _resolveTypeParameter(type);
-    ResolutionResult result = ResolutionResult.none;
-
-    void lookupIn(InterfaceType type) {
-      var getter = type.lookUpInheritedGetter(name,
-          library: _definingLibrary, thisType: target is! SuperExpression);
-      if (getter != null) {
-        result = ResolutionResult(property: getter.variable);
-      }
-    }
-
-    if (type is InterfaceType) {
-      lookupIn(type);
-    } else if (type is FunctionType) {
-      lookupIn(_resolver.typeProvider.functionType);
-    } else {
-      return ResolutionResult.none;
-    }
-    if (result.isNone) {
-      result = _extensionResolver.findExtension(type, name, nameNode);
-    }
-    return result;
-  }
-
-  /**
-   * 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 `null` if there is no method or getter with the given name.
-   */
-  ExecutableElement _lookupGetterOrMethod(DartType type, String name) {
-    type = _resolveTypeParameter(type);
-    if (type is InterfaceType) {
-      return type.lookUpInheritedGetterOrMethod(name,
-          library: _definingLibrary);
-    }
-    return null;
-  }
-
-  /**
-   * Look up the method with the given [name] in the given [type]. Return a
-   * result representing the result of that lookup. The [target] is the target
-   * of the invocation, or `null` if there is no target.
-   */
-  ResolutionResult _lookUpMethod(
-      Expression target, DartType type, String name, Expression nameNode) {
-    type = _resolveTypeParameter(type);
-    ResolutionResult result = ResolutionResult.none;
-
-    void lookupIn(InterfaceType type) {
-      var method = type.lookUpInheritedMethod(name,
-          library: _definingLibrary, thisType: target is! SuperExpression);
-      if (method != null) {
-        result = ResolutionResult(function: method);
-      }
-    }
-
-    if (type is InterfaceType) {
-      lookupIn(type);
-    } else if (type is FunctionType) {
-      lookupIn(_resolver.typeProvider.functionType);
-    } else {
-      return ResolutionResult.none;
-    }
-    if (result.isNone) {
-      result = _extensionResolver.findExtension(type, name, nameNode);
-    }
-    return result;
-  }
-
-  /**
-   * Look up the setter with the given [name] in the given [type]. Return a
-   * result representing the result of that lookup. The [target] is the target
-   * of the invocation, or `null` if there is no target.
-   */
-  ResolutionResult _lookUpSetter(
-      Expression target, DartType type, String name, Expression nameNode) {
-    type = _resolveTypeParameter(type);
-    ResolutionResult result = ResolutionResult.none;
-
-    void lookupIn(InterfaceType type) {
-      var setter = type.lookUpInheritedSetter(name,
-          library: _definingLibrary, thisType: target is! SuperExpression);
-      if (setter != null) {
-        result = ResolutionResult(property: setter.variable);
-      }
-    }
-
-    if (type is InterfaceType) {
-      lookupIn(type);
-    } else if (type is FunctionType) {
-      lookupIn(_resolver.typeProvider.functionType);
-    } else {
-      return ResolutionResult.none;
-    }
-    if (result.isNone) {
-      result = _extensionResolver.findExtension(type, name, nameNode);
-    }
-    return result;
+  _PropertyResolver _newPropertyResolver() {
+    return _PropertyResolver(_resolver.typeProvider, _inheritance,
+        _definingLibrary, _extensionResolver);
   }
 
   /**
@@ -1573,35 +1439,13 @@
         return;
       }
       DartType leftType = _getStaticType(leftOperand);
-      var isSuper = leftOperand is SuperExpression;
-
-      ResolutionResult result = ResolutionResult.none;
-
-      void lookupIn(InterfaceType type) {
-        ExecutableElement invokeElement = _inheritance.getMember(
-          type,
-          new Name(_definingLibrary.source.uri, methodName),
-          forSuper: isSuper,
-        );
-        if (invokeElement != null) {
-          result = ResolutionResult(function: invokeElement);
-        }
-      }
-
-      if (leftType is InterfaceType) {
-        lookupIn(leftType);
-      } else if (leftType is FunctionType) {
-        lookupIn(_resolver.typeProvider.functionType);
-      }
-
-      if (result.isNone) {
-        result = _extensionResolver.findExtension(leftType, methodName, node);
-      }
+      ResolutionResult result = _newPropertyResolver()
+          .resolveOperator(leftOperand, leftType, methodName, node);
 
       node.staticElement = result.function;
       node.staticInvokeType = result.function?.type;
       if (_shouldReportInvalidMember(leftType, result)) {
-        if (isSuper) {
+        if (leftOperand is SuperExpression) {
           _recordUndefinedToken(
               leftType.element,
               StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR,
@@ -1699,18 +1543,15 @@
    */
   ResolutionResult _resolveProperty(
       Expression target, DartType targetType, SimpleIdentifier propertyName) {
+    var propertyResolver = _newPropertyResolver();
+    propertyResolver.resolve(
+        target, targetType, propertyName.name, propertyName);
     ResolutionResult result = ResolutionResult.none;
     if (propertyName.inSetterContext()) {
-      result =
-          _lookUpSetter(target, targetType, propertyName.name, propertyName);
+      result = propertyResolver.setterResult;
     }
     if (result.isNone) {
-      result =
-          _lookUpGetter(target, targetType, propertyName.name, propertyName);
-    }
-    if (result.isNone) {
-      result =
-          _lookUpMethod(target, targetType, propertyName.name, propertyName);
+      result = propertyResolver.getterResult;
     }
     return result;
   }
@@ -1907,9 +1748,10 @@
           //
           ClassElement enclosingClass = _resolver.enclosingClass;
           if (enclosingClass != null) {
-            setter = _lookUpSetter(
-                    null, enclosingClass.type, identifier.name, identifier)
-                .setter;
+            var propertyResolver = _newPropertyResolver();
+            propertyResolver.resolve(
+                null, enclosingClass.type, identifier.name, identifier);
+            setter = propertyResolver.setterResult.setter;
           }
         }
         if (setter != null) {
@@ -1943,24 +1785,15 @@
       } else {
         enclosingType = enclosingClass.type;
       }
-      if (enclosingType != null) {
-        if (element == null &&
-            (identifier.inSetterContext() ||
-                identifier.parent is CommentReference)) {
-          element =
-              _lookUpSetter(null, enclosingType, identifier.name, identifier)
-                  .setter;
+      if (element == null && enclosingType != null) {
+        var propertyResolver = _newPropertyResolver();
+        propertyResolver.resolve(
+            null, enclosingType, identifier.name, identifier);
+        if (identifier.inSetterContext() ||
+            identifier.parent is CommentReference) {
+          element = propertyResolver.setterResult.setter;
         }
-        if (element == null && identifier.inGetterContext()) {
-          element =
-              _lookUpGetter(null, enclosingType, identifier.name, identifier)
-                  .getter;
-        }
-        if (element == null) {
-          element =
-              _lookUpMethod(null, enclosingType, identifier.name, identifier)
-                  .getter;
-        }
+        element ??= propertyResolver.getterResult.getter;
       }
     }
     return element;
@@ -2114,3 +1947,98 @@
   @override
   void visitChildren(AstVisitor visitor) {}
 }
+
+/// Helper for resolving properties (getters, setters, or methods).
+class _PropertyResolver {
+  final TypeProvider _typeProvider;
+  final InheritanceManager3 _inheritance;
+  final LibraryElement _definingLibrary;
+  final ExtensionMemberResolver _extensionResolver;
+
+  ResolutionResult getterResult = ResolutionResult.none;
+  ResolutionResult setterResult = ResolutionResult.none;
+
+  _PropertyResolver(
+    this._typeProvider,
+    this._inheritance,
+    this._definingLibrary,
+    this._extensionResolver,
+  );
+
+  /// Look up the getter and the setter with the given [name] in the [type].
+  /// Set results into [getterResult] or [setterResult] correspondingly.
+  /// Methods are considered getters for this purpose.
+  ///
+  /// The [target] is optional, and used to identify `super`.
+  ///
+  /// The [errorNode] is used to report the ambiguous extension issue.
+  void resolve(
+    Expression target,
+    DartType type,
+    String name,
+    Expression errorNode,
+  ) {
+    type = _resolveTypeParameter(type);
+
+    PropertyAccessorElement typeGetter;
+    PropertyAccessorElement typeSetter;
+    ExecutableElement typeMethod;
+
+    void lookupIn(InterfaceType type) {
+      var isSuper = target is SuperExpression;
+
+      typeGetter = type.lookUpInheritedGetter(name,
+          library: _definingLibrary, thisType: !isSuper);
+
+      typeSetter = type.lookUpInheritedSetter(name,
+          library: _definingLibrary, thisType: !isSuper);
+
+      typeMethod = type.lookUpInheritedMethod(name,
+          library: _definingLibrary, thisType: !isSuper);
+    }
+
+    if (type is InterfaceType) {
+      lookupIn(type);
+    } else if (type is FunctionType) {
+      lookupIn(_typeProvider.functionType);
+    } else {
+      return;
+    }
+
+    if (typeGetter != null) {
+      getterResult = ResolutionResult(property: typeGetter.variable);
+    } else if (typeMethod != null) {
+      getterResult = ResolutionResult(function: typeMethod);
+    }
+    if (typeSetter != null) {
+      setterResult = ResolutionResult(property: typeSetter.variable);
+    }
+
+    if (getterResult.isNone && setterResult.isNone) {
+      var result = _extensionResolver.findExtension(type, name, errorNode);
+      if (result.isSingle) {
+        if (result.getter != null) {
+          getterResult = result;
+        } else {
+          assert(result.setter != null);
+          setterResult = result;
+        }
+      } else if (result.isAmbiguous) {
+        getterResult = ResolutionResult.ambiguous;
+        setterResult = ResolutionResult.ambiguous;
+      }
+    }
+  }
+
+  ResolutionResult resolveOperator(
+      Expression target, DartType type, String name, Expression nameNode) {
+    resolve(target, type, name, nameNode);
+    return getterResult;
+  }
+
+  /// If the given [type] is a type parameter, replace it with its bound.
+  /// Otherwise, return the original type.
+  DartType _resolveTypeParameter(DartType type) {
+    return type?.resolveToBound(_typeProvider.objectType);
+  }
+}
diff --git a/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart b/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
index 9a559a5..cfb7917 100644
--- a/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
+++ b/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
@@ -34,6 +34,10 @@
   /// field.
   bool _checkConstantUpdate2018;
 
+  /// A cached flag indicating whether uses of extension method features need to
+  /// be checked. Use [checkExtensionMethods] to access this field.
+  bool _checkExtensionMethods;
+
   /// A cached flag indicating whether references to Future and Stream need to
   /// be checked. Use [checkFutureAndStream] to access this field.
   bool _checkFutureAndStream;
@@ -76,6 +80,10 @@
   VersionRange get before_2_5_0 =>
       new VersionRange(max: Version.parse('2.5.0'), includeMax: false);
 
+  /// Return a range covering every version up to, but not including, 2.6.0.
+  VersionRange get before_2_6_0 =>
+      new VersionRange(max: Version.parse('2.6.0'), includeMax: false);
+
   /// Return `true` if references to the constant-update-2018 features need to
   /// be checked.
   bool get checkConstantUpdate2018 => _checkConstantUpdate2018 ??=
@@ -83,9 +91,8 @@
 
   /// Return `true` if references to the extension method features need to
   /// be checked.
-  // TODO(brianwilkerson) Implement this as a version check when a version has
-  //  been selected.
-  bool get checkExtensionMethods => true;
+  bool get checkExtensionMethods => _checkExtensionMethods ??=
+      !before_2_6_0.intersect(_versionConstraint).isEmpty;
 
   /// Return `true` if references to Future and Stream need to be checked.
   bool get checkFutureAndStream => _checkFutureAndStream ??=
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 2ac377b..00c787a 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -23610,6 +23610,7 @@
         kind == idl.LinkedNodeKind.compilationUnit ||
         kind == idl.LinkedNodeKind.constructorDeclaration ||
         kind == idl.LinkedNodeKind.defaultFormalParameter ||
+        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
         kind == idl.LinkedNodeKind.enumDeclaration ||
         kind == idl.LinkedNodeKind.extensionDeclaration ||
         kind == idl.LinkedNodeKind.fieldFormalParameter ||
@@ -23631,6 +23632,7 @@
         kind == idl.LinkedNodeKind.compilationUnit ||
         kind == idl.LinkedNodeKind.constructorDeclaration ||
         kind == idl.LinkedNodeKind.defaultFormalParameter ||
+        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
         kind == idl.LinkedNodeKind.enumDeclaration ||
         kind == idl.LinkedNodeKind.extensionDeclaration ||
         kind == idl.LinkedNodeKind.fieldFormalParameter ||
@@ -23654,6 +23656,7 @@
         kind == idl.LinkedNodeKind.compilationUnit ||
         kind == idl.LinkedNodeKind.constructorDeclaration ||
         kind == idl.LinkedNodeKind.defaultFormalParameter ||
+        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
         kind == idl.LinkedNodeKind.enumDeclaration ||
         kind == idl.LinkedNodeKind.extensionDeclaration ||
         kind == idl.LinkedNodeKind.fieldFormalParameter ||
@@ -23675,6 +23678,7 @@
         kind == idl.LinkedNodeKind.compilationUnit ||
         kind == idl.LinkedNodeKind.constructorDeclaration ||
         kind == idl.LinkedNodeKind.defaultFormalParameter ||
+        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
         kind == idl.LinkedNodeKind.enumDeclaration ||
         kind == idl.LinkedNodeKind.extensionDeclaration ||
         kind == idl.LinkedNodeKind.fieldFormalParameter ||
@@ -23944,9 +23948,13 @@
         _variantField_10 = defaultFormalParameter_defaultValueCode;
 
   UnlinkedInformativeDataBuilder.enumConstantDeclaration({
+    int codeLength,
+    int codeOffset,
     int nameOffset,
     List<String> documentationComment_tokens,
   })  : _kind = idl.LinkedNodeKind.enumConstantDeclaration,
+        _variantField_2 = codeLength,
+        _variantField_3 = codeOffset,
         _variantField_1 = nameOffset,
         _variantField_4 = documentationComment_tokens;
 
@@ -24219,6 +24227,8 @@
     } else if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
       signature.addInt(this.kind == null ? 0 : this.kind.index);
       signature.addInt(this.nameOffset ?? 0);
+      signature.addInt(this.codeLength ?? 0);
+      signature.addInt(this.codeOffset ?? 0);
       if (this.documentationComment_tokens == null) {
         signature.addInt(0);
       } else {
@@ -24486,6 +24496,7 @@
         kind == idl.LinkedNodeKind.compilationUnit ||
         kind == idl.LinkedNodeKind.constructorDeclaration ||
         kind == idl.LinkedNodeKind.defaultFormalParameter ||
+        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
         kind == idl.LinkedNodeKind.enumDeclaration ||
         kind == idl.LinkedNodeKind.extensionDeclaration ||
         kind == idl.LinkedNodeKind.fieldFormalParameter ||
@@ -24509,6 +24520,7 @@
         kind == idl.LinkedNodeKind.compilationUnit ||
         kind == idl.LinkedNodeKind.constructorDeclaration ||
         kind == idl.LinkedNodeKind.defaultFormalParameter ||
+        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
         kind == idl.LinkedNodeKind.enumDeclaration ||
         kind == idl.LinkedNodeKind.extensionDeclaration ||
         kind == idl.LinkedNodeKind.fieldFormalParameter ||
@@ -24688,6 +24700,8 @@
             defaultFormalParameter_defaultValueCode;
     }
     if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
+      if (codeLength != 0) _result["codeLength"] = codeLength;
+      if (codeOffset != 0) _result["codeOffset"] = codeOffset;
       if (nameOffset != 0) _result["nameOffset"] = nameOffset;
       if (documentationComment_tokens.isNotEmpty)
         _result["documentationComment_tokens"] = documentationComment_tokens;
@@ -24863,6 +24877,8 @@
     }
     if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
       return {
+        "codeLength": codeLength,
+        "codeOffset": codeOffset,
         "nameOffset": nameOffset,
         "documentationComment_tokens": documentationComment_tokens,
         "kind": kind,
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 5e71b0e..0ada341 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -3645,6 +3645,7 @@
     LinkedNodeKind.compilationUnit,
     LinkedNodeKind.constructorDeclaration,
     LinkedNodeKind.defaultFormalParameter,
+    LinkedNodeKind.enumConstantDeclaration,
     LinkedNodeKind.enumDeclaration,
     LinkedNodeKind.extensionDeclaration,
     LinkedNodeKind.fieldFormalParameter,
@@ -3666,6 +3667,7 @@
     LinkedNodeKind.compilationUnit,
     LinkedNodeKind.constructorDeclaration,
     LinkedNodeKind.defaultFormalParameter,
+    LinkedNodeKind.enumConstantDeclaration,
     LinkedNodeKind.enumDeclaration,
     LinkedNodeKind.extensionDeclaration,
     LinkedNodeKind.fieldFormalParameter,
diff --git a/pkg/analyzer/lib/src/summary2/informative_data.dart b/pkg/analyzer/lib/src/summary2/informative_data.dart
index 1bf085d..c26e114 100644
--- a/pkg/analyzer/lib/src/summary2/informative_data.dart
+++ b/pkg/analyzer/lib/src/summary2/informative_data.dart
@@ -116,6 +116,8 @@
     setData(
       node,
       UnlinkedInformativeDataBuilder.enumConstantDeclaration(
+        codeOffset: node.offset,
+        codeLength: node.length,
         documentationComment_tokens: _nodeCommentTokens(node),
         nameOffset: node.name.offset,
       ),
diff --git a/pkg/analyzer/lib/src/summary2/lazy_ast.dart b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
index 97fd87a..1ab9a95 100644
--- a/pkg/analyzer/lib/src/summary2/lazy_ast.dart
+++ b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
@@ -574,6 +574,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    LinkedUnitContext context,
+    EnumConstantDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null) {
+      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    LinkedUnitContext context,
+    EnumConstantDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null) {
+      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
+    }
+    return node.offset;
+  }
+
   static void readDocumentationComment(
     LinkedUnitContext context,
     EnumConstantDeclaration node,
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 801f3b0..823fef5 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -148,6 +148,8 @@
       }
     } else if (node is ConstructorDeclaration) {
       return LazyConstructorDeclaration.getCodeLength(this, node);
+    } else if (node is EnumConstantDeclaration) {
+      return LazyEnumConstantDeclaration.getCodeLength(this, node);
     } else if (node is EnumDeclaration) {
       return LazyEnumDeclaration.getCodeLength(this, node);
     } else if (node is ExtensionDeclaration) {
@@ -181,6 +183,8 @@
       return 0;
     } else if (node is ConstructorDeclaration) {
       return LazyConstructorDeclaration.getCodeOffset(this, node);
+    } else if (node is EnumConstantDeclaration) {
+      return LazyEnumConstantDeclaration.getCodeOffset(this, node);
     } else if (node is EnumDeclaration) {
       return LazyEnumDeclaration.getCodeOffset(this, node);
     } else if (node is ExtensionDeclaration) {
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index 3187ffa..6392ba2 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -145,6 +145,9 @@
     LinkingNodeContext(node, functionScope);
 
     node.parameters?.accept(this);
+    node.initializers.accept(
+      _SetGenericFunctionTypeIdVisitor(this),
+    );
 
     scope = outerScope;
     reference = outerReference;
@@ -153,6 +156,9 @@
   @override
   void visitDefaultFormalParameter(DefaultFormalParameter node) {
     node.parameter.accept(this);
+    node.defaultValue?.accept(
+      _SetGenericFunctionTypeIdVisitor(this),
+    );
   }
 
   @override
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 0bc30b6..42e45f2 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -2544,6 +2544,16 @@
     parseCompilationUnit('D? foo(X? x) { X? x1; X? x2 = x + bar(7); }');
   }
 
+  void test_assignment_complex2() {
+    parseCompilationUnit(r'''
+main() {
+  A? a;
+  String? s = '';
+  a?..foo().length..x27 = s!..toString().length;
+}
+''');
+  }
+
   void test_assignment_simple() {
     parseCompilationUnit('D? foo(X? x) { X? x1; X? x2 = x; }');
   }
@@ -2561,6 +2571,39 @@
     expect(rhs.name, 'x2');
   }
 
+  void test_cascade_withNullCheck_indexExpression() {
+    var unit = parseCompilationUnit('main() { a?..[27]; }');
+    FunctionDeclaration funct = unit.declarations[0];
+    BlockFunctionBody body = funct.functionExpression.body;
+    ExpressionStatement statement = body.block.statements[0];
+    CascadeExpression cascade = statement.expression;
+    IndexExpression indexExpression = cascade.cascadeSections[0];
+    expect(indexExpression.period.lexeme, '?..');
+    expect(indexExpression.toSource(), '?..[27]');
+  }
+
+  void test_cascade_withNullCheck_methodInvocation() {
+    var unit = parseCompilationUnit('main() { a?..foo(); }');
+    FunctionDeclaration funct = unit.declarations[0];
+    BlockFunctionBody body = funct.functionExpression.body;
+    ExpressionStatement statement = body.block.statements[0];
+    CascadeExpression cascade = statement.expression;
+    MethodInvocation invocation = cascade.cascadeSections[0];
+    expect(invocation.operator.lexeme, '?..');
+    expect(invocation.toSource(), '?..foo()');
+  }
+
+  void test_cascade_withNullCheck_propertyAccess() {
+    var unit = parseCompilationUnit('main() { a?..x27; }');
+    FunctionDeclaration funct = unit.declarations[0];
+    BlockFunctionBody body = funct.functionExpression.body;
+    ExpressionStatement statement = body.block.statements[0];
+    CascadeExpression cascade = statement.expression;
+    PropertyAccess propertyAccess = cascade.cascadeSections[0];
+    expect(propertyAccess.operator.lexeme, '?..');
+    expect(propertyAccess.toSource(), '?..x27');
+  }
+
   void test_conditional() {
     parseCompilationUnit('D? foo(X? x) { X ? 7 : y; }');
   }
diff --git a/pkg/analyzer/test/src/diagnostics/assignment_to_final_no_setter_test.dart b/pkg/analyzer/test/src/diagnostics/assignment_to_final_no_setter_test.dart
index a5f6427..238174f 100644
--- a/pkg/analyzer/test/src/diagnostics/assignment_to_final_no_setter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/assignment_to_final_no_setter_test.dart
@@ -2,7 +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.
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/driver_resolution.dart';
@@ -43,3 +45,25 @@
     ]);
   }
 }
+
+@reflectiveTest
+class AssignmentToMethodWithExtensionMethodsTest
+    extends AssignmentToFinalNoSetterTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+  test_instance_undefined_hasGetter() async {
+    await assertErrorsInCode('''
+extension E on int {
+  int get foo => 0;
+}
+f() {
+  0.foo = 1;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER, 53, 3),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/assignment_to_method_test.dart b/pkg/analyzer/test/src/diagnostics/assignment_to_method_test.dart
index 0a24297..912eefe 100644
--- a/pkg/analyzer/test/src/diagnostics/assignment_to_method_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/assignment_to_method_test.dart
@@ -2,7 +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.
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/driver_resolution.dart';
@@ -10,6 +12,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(AssignmentToMethodTest);
+    defineReflectiveTests(AssignmentToMethodWithExtensionMethodsTest);
   });
 }
 
@@ -27,3 +30,50 @@
     ]);
   }
 }
+
+@reflectiveTest
+class AssignmentToMethodWithExtensionMethodsTest
+    extends AssignmentToMethodTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+  test_instance_extendedHasMethod_extensionHasSetter() async {
+    await assertErrorsInCode('''
+class C {
+  void foo() {}
+}
+
+extension E on C {
+  void set foo(int _) {}
+}
+
+f(C c) {
+  c.foo = 0;
+}
+''', [
+      error(StaticWarningCode.ASSIGNMENT_TO_METHOD, 87, 5),
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 95, 1),
+    ]);
+  }
+
+  test_this_extendedHasMethod_extensionHasSetter() async {
+    await assertErrorsInCode('''
+class C {
+  void foo() {}
+}
+
+extension E on C {
+  void set foo(int _) {}
+
+  f() {
+    this.foo = 0;
+  }
+}
+''', [
+      error(StaticWarningCode.ASSIGNMENT_TO_METHOD, 86, 8),
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 97, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_version_extension_methods_test.dart b/pkg/analyzer/test/src/diagnostics/sdk_version_extension_methods_test.dart
index 9afa451..e10751d 100644
--- a/pkg/analyzer/test/src/diagnostics/sdk_version_extension_methods_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/sdk_version_extension_methods_test.dart
@@ -21,7 +21,6 @@
   AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
     ..enabledExperiments = [EnableString.extension_methods];
 
-  @failingTest
   test_extension_equals() async {
     await verifyVersion('2.6.0', '''
 extension E on int {}
@@ -36,7 +35,6 @@
     ]);
   }
 
-  @failingTest
   test_extensionOverride_equals() async {
     await verifyVersion('2.6.0', '''
 extension E on int {
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_extension_getter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_extension_getter_test.dart
index dc99786..1917d08 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_extension_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_extension_getter_test.dart
@@ -22,7 +22,7 @@
     ..contextFeatures = new FeatureSet.forTesting(
         sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
 
-  test_instance_defined() async {
+  test_override_defined() async {
     await assertNoErrorsInCode('''
 extension E on String {
   int get g => 0;
@@ -33,7 +33,7 @@
 ''');
   }
 
-  test_instance_withoutSetter() async {
+  test_override_undefined() async {
     await assertErrorsInCode('''
 extension E on String {}
 f() {
@@ -44,7 +44,7 @@
     ]);
   }
 
-  test_instance_withSetter() async {
+  test_override_undefined_hasSetter() async {
     await assertErrorsInCode('''
 extension E on String {
   void set s(int x) {}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_extension_setter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_extension_setter_test.dart
index 9c38d0c..f6c2f65 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_extension_setter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_extension_setter_test.dart
@@ -22,36 +22,49 @@
     ..contextFeatures = new FeatureSet.forTesting(
         sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
 
-  test_instance_defined() async {
+  test_override_defined() async {
     await assertNoErrorsInCode('''
-extension E on String {
-  void set s(int x) {}
+extension E on int {
+  void set foo(int _) {}
 }
 f() {
-  E('a').s = 1;
+  E(0).foo = 1;
 }
 ''');
   }
 
-  test_instance_undefined() async {
+  test_override_undefined() async {
     await assertErrorsInCode('''
-extension E on String {}
+extension E on int {}
 f() {
-  E('a').s = 1;
+  E(0).foo = 1;
 }
 ''', [
-      error(CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER, 40, 1),
+      error(CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER, 35, 3),
+    ]);
+  }
+
+  test_override_undefined_hasGetter() async {
+    await assertErrorsInCode('''
+extension E on int {
+  int get foo => 0;
+}
+f() {
+  E(0).foo = 1;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER, 56, 3),
     ]);
   }
 
   test_static_undefined() async {
     await assertErrorsInCode('''
-extension E on Object {}
+extension E on int {}
 void f() {
-  E.s = 3;
+  E.foo = 3;
 }
 ''', [
-      error(CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER, 40, 1),
+      error(CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER, 37, 3),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
index d56ebb7..5f3050e 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
@@ -125,6 +125,37 @@
     ..contextFeatures = new FeatureSet.forTesting(
         sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
 
+  test_instance_extendedHasSetter_extensionHasGetter() async {
+    await assertErrorsInCode('''
+class C {
+  void set foo(int _) {}
+}
+
+extension E on C {
+  int get foo => 0;
+
+  f() {
+    this.foo;
+  }
+}
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_GETTER, 95, 3),
+    ]);
+  }
+
+  test_instance_undefined_hasSetter() async {
+    await assertErrorsInCode('''
+extension E on int {
+  void set foo(int _) {}
+}
+f() {
+  0.foo;
+}
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_GETTER, 58, 3),
+    ]);
+  }
+
   test_instance_withInference() async {
     await assertErrorsInCode(r'''
 extension E on int {}
@@ -147,4 +178,22 @@
       error(StaticTypeWarningCode.UNDEFINED_GETTER, 46, 1),
     ]);
   }
+
+  test_this_extendedHasSetter_extensionHasGetter() async {
+    await assertErrorsInCode('''
+class C {
+  void set foo(int _) {}
+}
+
+extension E on C {
+  int get foo => 0;
+}
+
+f(C c) {
+  c.foo;
+}
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_GETTER, 93, 3),
+    ]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/unused_import_test.dart b/pkg/analyzer/test/src/diagnostics/unused_import_test.dart
index 0a78364..19a7be4 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_import_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_import_test.dart
@@ -328,14 +328,14 @@
   test_instance_setter() async {
     newFile('/test/lib/lib1.dart', content: r'''
 extension E on String {
-  void set length(int i) {}
+  void set foo(int i) {}
 }
 ''');
     await assertNoErrorsInCode('''
 import 'lib1.dart';
 
 f() {
-  'abc'.length = 2;
+  'abc'.foo = 2;
 }
 ''');
   }
diff --git a/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart b/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart
index befdee3..2d07417 100644
--- a/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart
+++ b/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart
@@ -184,6 +184,16 @@
     assertCanBeConst("A(", false);
   }
 
+  void test_false_typeParameter() async {
+    await resolve('''
+class A<T> {
+  const A();
+}
+f<U>() => A<U>();
+''');
+    assertCanBeConst("A<U>", false);
+  }
+
   void test_true_constConstructorArg() async {
     await resolve('''
 class A {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 38ce11b..e68375d 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -2075,6 +2075,28 @@
         withConstElements: false);
   }
 
+  test_codeRange_enum() async {
+    var library = await checkLibrary('''
+enum E {
+  aaa, bbb, ccc
+}
+''');
+    checkElementText(
+        library,
+        r'''
+enum E/*codeOffset=0, codeLength=26*/ {
+  synthetic final int index/*codeOffset=null, codeLength=null*/;
+  synthetic static const List<E> values/*codeOffset=null, codeLength=null*/;
+  static const E aaa/*codeOffset=11, codeLength=3*/;
+  static const E bbb/*codeOffset=16, codeLength=3*/;
+  static const E ccc/*codeOffset=21, codeLength=3*/;
+  String toString/*codeOffset=null, codeLength=null*/() {}
+}
+''',
+        withCodeRanges: true,
+        withConstElements: false);
+  }
+
   test_codeRange_extensions() async {
     featureSet = enableExtensionMethods;
     var library = await checkLibrary('''
@@ -4617,6 +4639,31 @@
 ''');
   }
 
+  test_constructor_initializers_genericFunctionType() async {
+    var library = await checkLibrary('''
+class A<T> {
+  const A();
+}
+class B {
+  const B(dynamic x);
+  const B.f()
+   : this(A<Function()>());
+}
+''');
+    if (isAstBasedSummary) {
+      checkElementText(library, r'''
+class A<T> {
+  const A();
+}
+class B {
+  const B(dynamic x);
+  const B.f() = B : this(
+        A/*location: test.dart;A*/<Function()>());
+}
+''');
+    }
+  }
+
   test_constructor_initializers_superInvocation_named() async {
     var library = await checkLibrary('''
 class A {
@@ -5261,6 +5308,28 @@
 ''');
   }
 
+  test_defaultValue_genericFunctionType() async {
+    var library = await checkLibrary('''
+class A<T> {
+  const A();
+}
+class B {
+  void foo({a: const A<Function()>()}) {}
+}
+''');
+    if (isAstBasedSummary) {
+      checkElementText(library, r'''
+class A<T> {
+  const A();
+}
+class B {
+  void foo({dynamic a: const
+        A/*location: test.dart;A*/<Function()>()}) {}
+}
+''');
+    }
+  }
+
   test_defaultValue_refersToExtension_method_inside() async {
     featureSet = enableExtensionMethods;
     var library = await checkLibrary('''
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index bf7c912..e9bb860 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1479,7 +1479,9 @@
   @override
   void endBinaryExpression(Token token) {
     debugEvent("BinaryExpression");
-    if (optional(".", token) || optional("..", token)) {
+    if (optional(".", token) ||
+        optional("..", token) ||
+        optional("?..", token)) {
       return doDotOrCascadeExpression(token);
     }
     if (optional("&&", token) || optional("||", token)) {
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index a296c652..9ad4e92 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -4285,7 +4285,7 @@
 
   Token parseCascadeExpression(Token token) {
     Token cascadeOperator = token = token.next;
-    assert(optional('..', cascadeOperator));
+    assert(optional('..', cascadeOperator) || optional('?..', cascadeOperator));
     listener.beginCascade(cascadeOperator);
     if (optional('[', token.next)) {
       token = parseArgumentOrIndexStar(token, noTypeParamOrArg);
diff --git a/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart b/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
index 50fedf3..e34362d 100644
--- a/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
@@ -877,16 +877,22 @@
   }
 
   int tokenizeQuestion(int next) {
-    // ? ?. ?? ??=
+    // ? ?. ?.. ?? ??=
     next = advance();
     if (identical(next, $QUESTION)) {
       return select(
           $EQ, TokenType.QUESTION_QUESTION_EQ, TokenType.QUESTION_QUESTION);
     } else if (identical(next, $PERIOD)) {
       next = advance();
-      if (_enableNonNullable && identical($OPEN_SQUARE_BRACKET, next)) {
-        appendBeginGroup(TokenType.QUESTION_PERIOD_OPEN_SQUARE_BRACKET);
-        return advance();
+      if (_enableNonNullable) {
+        if (identical($PERIOD, next)) {
+          appendPrecedenceToken(TokenType.QUESTION_PERIOD_PERIOD);
+          return advance();
+        }
+        if (identical($OPEN_SQUARE_BRACKET, next)) {
+          appendBeginGroup(TokenType.QUESTION_PERIOD_OPEN_SQUARE_BRACKET);
+          return advance();
+        }
       }
       appendPrecedenceToken(TokenType.QUESTION_PERIOD);
       return next;
diff --git a/pkg/front_end/lib/src/fasta/scanner/token_constants.dart b/pkg/front_end/lib/src/fasta/scanner/token_constants.dart
index e468145..f8cc645 100644
--- a/pkg/front_end/lib/src/fasta/scanner/token_constants.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/token_constants.dart
@@ -90,3 +90,5 @@
 const int PERIOD_PERIOD_PERIOD_QUESTION_TOKEN = GT_GT_GT_TOKEN + 1;
 const int GT_GT_GT_EQ_TOKEN = PERIOD_PERIOD_PERIOD_QUESTION_TOKEN + 1;
 const int QUESTION_PERIOD_OPEN_SQUARE_BRACKET_TOKEN = GT_GT_GT_EQ_TOKEN + 1;
+const int QUESTION_PERIOD_PERIOD_TOKEN =
+    QUESTION_PERIOD_OPEN_SQUARE_BRACKET_TOKEN + 1;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
index dab1b69..3912f27 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
@@ -259,12 +259,6 @@
     // identical().  If P and Q are equal but not identical, recursing through
     // the types will give the proper result.
     if (identical(subtype, supertype)) return true;
-    // Any type `P` is a subtype match for `dynamic`, `Object`, or `void` under
-    // no constraints.
-    if (_isTop(supertype)) return true;
-    // `Null` is a subtype match for any type `Q` under no constraints.
-    // Note that nullable types will change this.
-    if (_isNull(subtype)) return true;
 
     // Handle FutureOr<T> union type.
     if (subtype is InterfaceType &&
@@ -302,11 +296,34 @@
       //   - And `P` is a subtype match for `Q` with respect to `L` under
       //     constraints `C`
       DartType supertypeArg = supertype.typeArguments[0];
-      InterfaceType supertypeFuture = futureType(supertypeArg);
-      return trySubtypeMatch(subtype, supertypeFuture) ||
-          _isSubtypeMatch(subtype, supertypeArg);
+      DartType supertypeFuture = futureType(supertypeArg);
+
+      // The outcome of both trySubtypeMatch and _isSubtypeMatch is includes the
+      // returned boolean value and the added constraints to _protoConstraints.
+      // Here we need to match 'subtype' against both possibilities of the
+      // FutureOr<X> which is 'supertype,' that is, we need to match 'subtype'
+      // against Future<X> and X.  However, if the first matching against
+      // Future<X> finds any new constraints and adds them to _protoConstraints,
+      // we should prefer them over the constraints possibly found while
+      // matching against X.  Note that if matching against Future<X> returned
+      // true, but didn't find any new constraints, then matching against X
+      // should still be done and the new constraints should still be added to
+      // _protoConstraints.
+      int oldProtoConstraintsLength = _protoConstraints.length;
+      bool matchesFuture = trySubtypeMatch(subtype, supertypeFuture);
+      bool matchesArg = oldProtoConstraintsLength != _protoConstraints.length
+          ? false
+          : _isSubtypeMatch(subtype, supertypeArg);
+      return matchesFuture || matchesArg;
     }
 
+    // Any type `P` is a subtype match for `dynamic`, `Object`, or `void` under
+    // no constraints.
+    if (_isTop(supertype)) return true;
+    // `Null` is a subtype match for any type `Q` under no constraints.
+    // Note that nullable types will change this.
+    if (_isNull(subtype)) return true;
+
     // A type variable `T` not in `L` with bound `P` is a subtype match for the
     // same type variable `T` with bound `Q` with respect to `L` under
     // constraints `C`:
diff --git a/pkg/front_end/lib/src/scanner/token.dart b/pkg/front_end/lib/src/scanner/token.dart
index f7429c3..d16d2d4 100644
--- a/pkg/front_end/lib/src/scanner/token.dart
+++ b/pkg/front_end/lib/src/scanner/token.dart
@@ -1450,6 +1450,12 @@
       SELECTOR_PRECEDENCE,
       QUESTION_PERIOD_OPEN_SQUARE_BRACKET_TOKEN);
 
+  static const TokenType QUESTION_PERIOD_PERIOD = const TokenType(
+      '?..',
+      'QUESTION_PERIOD_PERIOD',
+      CASCADE_PRECEDENCE,
+      QUESTION_PERIOD_PERIOD_TOKEN);
+
   static const TokenType AS = Keyword.AS;
 
   static const TokenType IS = Keyword.IS;
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index 056b0f5..f27e950 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -97,6 +97,7 @@
 also
 alternating
 alternative
+alternatives
 alternatively
 although
 always
@@ -1984,6 +1985,7 @@
 positions
 positive
 positives
+possibilities
 possible
 possibly
 post
diff --git a/pkg/front_end/test/static_types/data/constraint_gatherer_for_future_or.dart b/pkg/front_end/test/static_types/data/constraint_gatherer_for_future_or.dart
new file mode 100644
index 0000000..8e74122
--- /dev/null
+++ b/pkg/front_end/test/static_types/data/constraint_gatherer_for_future_or.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 test checks the gathering of the constraints during type inference in
+// case the supertype of the match is a FutureOr<X> or one of its alternatives
+// (either Future<X> or X).
+
+import 'dart:async';
+
+// -----------------------------------------------------------------------------
+
+// Gathering constraints for S from comparison Null <: FutureOr<S>.
+void func1() {
+  void foo<S>(FutureOr<S> bar) {}
+
+  /*invoke: void*/ foo/*<Null>*/(/*Null*/ null);
+}
+
+// -----------------------------------------------------------------------------
+
+// Gathering constraints for S from comparison Null <: Future<S>.
+void func2() {
+  void foo<S>(Future<S> bar) {}
+
+  /*invoke: void*/ foo/*<dynamic>*/(/*Null*/ null);
+}
+
+// -----------------------------------------------------------------------------
+
+// Gathering constraints for S from comparison Null <: S.
+void func3() {
+  void foo<S>(S bar) {}
+
+  /*invoke: void*/ foo/*<Null>*/(/*Null*/ null);
+}
+
+// -----------------------------------------------------------------------------
+
+void func4() {
+  void foo<S>(FutureOr<FutureOr<S>> bar) {}
+
+  /*invoke: void*/ foo/*<Null>*/(/*Null*/ null);
+}
+
+// -----------------------------------------------------------------------------
+
+// Gathering constraints for S from comparison int <: FutureOr<S>.
+void func5() {
+  void foo<S>(FutureOr<S> bar) {}
+
+  /*invoke: void*/ foo/*<int>*/(/*int*/ 42);
+}
+
+// -----------------------------------------------------------------------------
+
+// Gathering constraints for S from comparison int <: S.
+void func6() {
+  void foo<S>(S bar) {}
+
+  /*invoke: void*/ foo/*<int>*/(/*int*/ 42);
+}
+
+// -----------------------------------------------------------------------------
+
+void func7() {
+  void foo<S>(FutureOr<FutureOr<S>> bar) {}
+
+  /*invoke: void*/ foo/*<int>*/(/*int*/ 42);
+}
+
+// -----------------------------------------------------------------------------
+
+main() {}
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index 5a73336..f802599 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -274,15 +274,17 @@
   @override
   DecoratedType visitAssignmentExpression(AssignmentExpression node) {
     _CompoundOperatorInfo compoundOperatorInfo;
+    bool isQuestionAssign = false;
     if (node.operator.type == TokenType.QUESTION_QUESTION_EQ) {
-      _unimplemented(node, 'Assignment with operator ??=');
+      isQuestionAssign = true;
     } else if (node.operator.type != TokenType.EQ) {
       compoundOperatorInfo = _CompoundOperatorInfo(
           node.staticElement, node.operator.offset, node.staticType);
     }
     var expressionType = _handleAssignment(node.rightHandSide,
         destinationExpression: node.leftHandSide,
-        compoundOperatorInfo: compoundOperatorInfo);
+        compoundOperatorInfo: compoundOperatorInfo,
+        questionAssignNode: isQuestionAssign ? node : null);
     var conditionalNode = _conditionalNodes[node.leftHandSide];
     if (conditionalNode != null) {
       expressionType = expressionType.withNode(
@@ -369,13 +371,17 @@
           (callee.enclosingElement as ClassElement)
               .typeParameters
               .isNotEmpty)); // TODO(paulberry)
-      assert(callee != null); // TODO(paulberry)
-      var calleeType = getOrComputeElementType(callee);
-      // TODO(paulberry): substitute if necessary
-      assert(calleeType.positionalParameters.length > 0); // TODO(paulberry)
-      _handleAssignment(node.rightOperand,
-          destinationType: calleeType.positionalParameters[0]);
-      return _fixNumericTypes(calleeType.returnType, node.staticType);
+      if (callee == null) {
+        node.rightOperand.accept(this);
+        return _dynamicType;
+      } else {
+        var calleeType = getOrComputeElementType(callee);
+        // TODO(paulberry): substitute if necessary
+        assert(calleeType.positionalParameters.length > 0); // TODO(paulberry)
+        _handleAssignment(node.rightOperand,
+            destinationType: calleeType.positionalParameters[0]);
+        return _fixNumericTypes(calleeType.returnType, node.staticType);
+      }
     } else {
       // TODO(paulberry)
       node.leftOperand.accept(this);
@@ -662,9 +668,8 @@
   @override
   DecoratedType visitFunctionExpressionInvocation(
       FunctionExpressionInvocation node) {
-    DecoratedType calleeType = node.function.accept(this);
-    return _handleInvocationArguments(node, node.argumentList.arguments,
-        node.typeArguments, node.typeArgumentTypes, calleeType, null);
+    return _handleFunctionExpressionInvocation(node, node.function,
+        node.argumentList, node.typeArguments, node.typeArgumentTypes);
   }
 
   @override
@@ -901,7 +906,13 @@
       // Dynamic dispatch.  The return type is `dynamic`.
       // TODO(paulberry): would it be better to assume a return type of `Never`
       // so that we don't unnecessarily propagate nullabilities everywhere?
+      node.typeArguments?.accept(this);
+      node.argumentList.accept(this);
       return _dynamicType;
+    } else if (callee is VariableElement) {
+      // Function expression invocation that looks like a method invocation.
+      return _handleFunctionExpressionInvocation(node, node.methodName,
+          node.argumentList, node.typeArguments, node.typeArgumentTypes);
     }
     var calleeType = getOrComputeElementType(callee, targetType: targetType);
     if (callee is PropertyAccessorElement) {
@@ -1184,7 +1195,7 @@
 
   @override
   DecoratedType visitSuperExpression(SuperExpression node) {
-    return DecoratedType(node.staticType, _graph.never);
+    return _handleThisOrSuper(node);
   }
 
   @override
@@ -1214,7 +1225,7 @@
 
   @override
   DecoratedType visitThisExpression(ThisExpression node) {
-    return DecoratedType(node.staticType, _graph.never);
+    return _handleThisOrSuper(node);
   }
 
   @override
@@ -1535,6 +1546,7 @@
       {DecoratedType destinationType,
       Expression destinationExpression,
       _CompoundOperatorInfo compoundOperatorInfo,
+      Expression questionAssignNode,
       bool canInsertChecks = true}) {
     assert(
         (destinationExpression == null) != (destinationType == null),
@@ -1554,47 +1566,64 @@
         destinationType = destinationExpression.accept(this);
       }
     }
-    var sourceType = expression.accept(this);
-    if (sourceType == null) {
-      throw StateError('No type computed for ${expression.runtimeType} '
-          '(${expression.toSource()}) offset=${expression.offset}');
+    if (questionAssignNode != null) {
+      _guards.add(destinationType.node);
     }
-    ExpressionChecks expressionChecks;
-    if (canInsertChecks && !sourceType.type.isDynamic) {
-      expressionChecks = ExpressionChecks(expression.end);
-      _variables.recordExpressionChecks(source, expression, expressionChecks);
-    }
-    if (compoundOperatorInfo != null) {
-      var compoundOperatorMethod = compoundOperatorInfo.method;
-      if (compoundOperatorMethod != null) {
-        _checkAssignment(
-            CompoundAssignmentOrigin(source, compoundOperatorInfo.offset),
-            source: destinationType,
-            destination: _notNullType,
-            hard:
-                _postDominatedLocals.isReferenceInScope(destinationExpression));
-        DecoratedType compoundOperatorType =
-            getOrComputeElementType(compoundOperatorMethod);
-        assert(compoundOperatorType.positionalParameters.length > 0);
+    DecoratedType sourceType;
+    try {
+      sourceType = expression.accept(this);
+      if (sourceType == null) {
+        throw StateError('No type computed for ${expression.runtimeType} '
+            '(${expression.toSource()}) offset=${expression.offset}');
+      }
+      ExpressionChecks expressionChecks;
+      if (canInsertChecks && !sourceType.type.isDynamic) {
+        expressionChecks = ExpressionChecks(expression.end);
+        _variables.recordExpressionChecks(source, expression, expressionChecks);
+      }
+      if (compoundOperatorInfo != null) {
+        var compoundOperatorMethod = compoundOperatorInfo.method;
+        if (compoundOperatorMethod != null) {
+          _checkAssignment(
+              CompoundAssignmentOrigin(source, compoundOperatorInfo.offset),
+              source: destinationType,
+              destination: _notNullType,
+              hard: _postDominatedLocals
+                  .isReferenceInScope(destinationExpression));
+          DecoratedType compoundOperatorType =
+              getOrComputeElementType(compoundOperatorMethod);
+          assert(compoundOperatorType.positionalParameters.length > 0);
+          _checkAssignment(expressionChecks,
+              source: sourceType,
+              destination: compoundOperatorType.positionalParameters[0],
+              hard: _postDominatedLocals.isReferenceInScope(expression));
+          sourceType = _fixNumericTypes(compoundOperatorType.returnType,
+              compoundOperatorInfo.undecoratedType);
+          _checkAssignment(
+              CompoundAssignmentOrigin(source, compoundOperatorInfo.offset),
+              source: sourceType,
+              destination: destinationType,
+              hard: false);
+        } else {
+          sourceType = _dynamicType;
+        }
+      } else {
         _checkAssignment(expressionChecks,
             source: sourceType,
-            destination: compoundOperatorType.positionalParameters[0],
-            hard: _postDominatedLocals.isReferenceInScope(expression));
-        sourceType = _fixNumericTypes(compoundOperatorType.returnType,
-            compoundOperatorInfo.undecoratedType);
-        _checkAssignment(
-            CompoundAssignmentOrigin(source, compoundOperatorInfo.offset),
-            source: sourceType,
             destination: destinationType,
-            hard: false);
-      } else {
-        sourceType = _dynamicType;
+            hard: _postDominatedLocals.isReferenceInScope(expression));
       }
-    } else {
-      _checkAssignment(expressionChecks,
-          source: sourceType,
-          destination: destinationType,
-          hard: _postDominatedLocals.isReferenceInScope(expression));
+      if (questionAssignNode != null) {
+        // a ??= b is only nullable if both a and b are nullable.
+        sourceType = destinationType.withNode(_nullabilityNodeForGLB(
+            questionAssignNode, sourceType.node, destinationType.node));
+        _variables.recordDecoratedExpressionType(
+            questionAssignNode, sourceType);
+      }
+    } finally {
+      if (questionAssignNode != null) {
+        _guards.removeLast();
+      }
     }
     if (destinationExpression != null) {
       _postDominatedLocals.removeReferenceFromAllScopes(destinationExpression);
@@ -1647,9 +1676,9 @@
     assert(_currentFunctionType == null);
     metadata.accept(this);
     returnType?.accept(this);
+    _createFlowAnalysis(body);
     parameters?.accept(this);
     _currentFunctionType = _variables.decoratedElementType(declaredElement);
-    _createFlowAnalysis(body);
     _addParametersToFlowAnalysis(parameters);
     // Push a scope of post-dominated declarations on the stack.
     _postDominatedLocals.pushScope(elements: declaredElement.parameters);
@@ -1780,6 +1809,24 @@
     });
   }
 
+  DecoratedType _handleFunctionExpressionInvocation(
+      AstNode node,
+      Expression function,
+      ArgumentList argumentList,
+      TypeArgumentList typeArguments,
+      List<DartType> typeArgumentTypes) {
+    DecoratedType calleeType = _checkExpressionNotNull(function);
+    if (calleeType.type is FunctionType) {
+      return _handleInvocationArguments(node, argumentList.arguments,
+          typeArguments, typeArgumentTypes, calleeType, null);
+    } else {
+      // Invocation of type `dynamic` or `Function`.
+      typeArguments?.accept(this);
+      argumentList.accept(this);
+      return _dynamicType;
+    }
+  }
+
   /// Creates the necessary constraint(s) for an [argumentList] when invoking an
   /// executable element whose type is [calleeType].
   ///
@@ -1913,6 +1960,19 @@
     }
   }
 
+  DecoratedType _handleThisOrSuper(Expression node) {
+    var type = node.staticType as InterfaceType;
+    // Instantiate the type, and any type arguments, with `_graph.never`,
+    // because the type of `this` is always `ClassName<Param, Param, ...>` with
+    // no `?`s.  (Even if some of the type parameters are allowed to be
+    // instantiated with nullable types at runtime, a reference to `this` can't
+    // be migrated in such a way that forces them to be nullable).
+    return DecoratedType(type, _graph.never,
+        typeArguments: type.typeArguments
+            .map((t) => DecoratedType(t, _graph.never))
+            .toList());
+  }
+
   bool _isConditionalExpression(Expression expression) {
     Token token;
     if (expression is MethodInvocation) {
@@ -2037,6 +2097,35 @@
       {@required DecoratedType source, @required DecoratedType destination}) {
     var sourceType = source.type;
     var destinationType = destination.type;
+    if (!_typeSystem.isSubtypeOf(sourceType, destinationType)) {
+      // Not a proper upcast assignment.  It is either an implicit downcast or
+      // some illegal code.  It's handled on a "best effort" basis.
+      if (destinationType is TypeParameterType &&
+          sourceType is! TypeParameterType) {
+        // Assume an assignment to the type parameter's bound.
+        _checkAssignment(origin,
+            source: source,
+            destination:
+                _getTypeParameterTypeBound(destination).withNode(_graph.always),
+            hard: false);
+        return;
+      }
+      if (sourceType is InterfaceType && destinationType is InterfaceType) {
+        if (_typeSystem.isSubtypeOf(destinationType, sourceType)) {
+          var rewrittenDestination = _decoratedClassHierarchy.asInstanceOf(
+              destination, sourceType.element);
+          assert(rewrittenDestination.typeArguments.length ==
+              source.typeArguments.length);
+          for (int i = 0; i < rewrittenDestination.typeArguments.length; i++) {
+            _checkAssignment(origin,
+                source: source.typeArguments[i],
+                destination: rewrittenDestination.typeArguments[i],
+                hard: false);
+          }
+        }
+      }
+      return;
+    }
     if (destinationType.isDartAsyncFutureOr) {
       // (From the subtyping spec):
       // if T1 is FutureOr<S1> then T0 <: T1 iff any of the following hold:
@@ -2059,8 +2148,9 @@
       else if (sourceType is TypeParameterType) {
         throw UnimplementedError('TODO(paulberry)');
       } else {
-        // Not a subtype; this must be a downcast.
-        throw UnimplementedError('TODO(paulberry)');
+        // Not a subtype.  This should never happen, since we handle the
+        // implicit downcast case above.
+        assert(false, 'not a subtype');
       }
     }
     if (sourceType.isBottom || sourceType.isDartCoreNull) {
@@ -2083,44 +2173,17 @@
             hard: false);
         return;
       }
-    } else if (destinationType is TypeParameterType) {
-      // Effectively this is a downcast assignment from the source type to the
-      // type parameter's bound.
-      _checkAssignment(origin,
-          source: source,
-          destination:
-              _getTypeParameterTypeBound(destination).withNode(_graph.always),
-          hard: false);
     } else if (sourceType is InterfaceType &&
         destinationType is InterfaceType) {
-      if (_typeSystem.isSubtypeOf(sourceType, destinationType)) {
-        // Ordinary (upcast) assignment.  No cast necessary.
-        var rewrittenSource = _decoratedClassHierarchy.asInstanceOf(
-            source, destinationType.element);
-        assert(rewrittenSource.typeArguments.length ==
-            destination.typeArguments.length);
-        for (int i = 0; i < rewrittenSource.typeArguments.length; i++) {
-          _checkAssignment(origin,
-              source: rewrittenSource.typeArguments[i],
-              destination: destination.typeArguments[i],
-              hard: false);
-        }
-      } else if (_typeSystem.isSubtypeOf(destinationType, sourceType)) {
-        // Implicit downcast assignment.
-        // TODO(paulberry): the migration tool should insert a cast.
-        var rewrittenDestination = _decoratedClassHierarchy.asInstanceOf(
-            destination, sourceType.element);
-        assert(rewrittenDestination.typeArguments.length ==
-            source.typeArguments.length);
-        for (int i = 0; i < rewrittenDestination.typeArguments.length; i++) {
-          _checkAssignment(origin,
-              source: source.typeArguments[i],
-              destination: rewrittenDestination.typeArguments[i],
-              hard: false);
-        }
-      } else {
-        // This should never arise for correct code; if it does arise, recover
-        // from the error by just not creating any additional edges.
+      var rewrittenSource = _decoratedClassHierarchy.asInstanceOf(
+          source, destinationType.element);
+      assert(rewrittenSource.typeArguments.length ==
+          destination.typeArguments.length);
+      for (int i = 0; i < rewrittenSource.typeArguments.length; i++) {
+        _checkAssignment(origin,
+            source: rewrittenSource.typeArguments[i],
+            destination: destination.typeArguments[i],
+            hard: false);
       }
     } else if (sourceType is FunctionType && destinationType is FunctionType) {
       _checkAssignment(origin,
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index 079cf85..1db66dc 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -375,6 +375,16 @@
     return variables.decoratedExpressionType(findNode.expression(text));
   }
 
+  test_already_migrated_field() async {
+    await analyze('''
+double f() => double.NAN;
+''');
+    var nanElement = typeProvider.doubleType.element.getField('NAN');
+    assertEdge(variables.decoratedElementType(nanElement).node,
+        decoratedTypeAnnotation('double f').node,
+        hard: false);
+  }
+
   test_as_dynamic() async {
     await analyze('''
 void f(Object o) {
@@ -401,16 +411,6 @@
     assertEdge(decoratedTypeAnnotation('int').node, never, hard: false);
   }
 
-  test_already_migrated_field() async {
-    await analyze('''
-double f() => double.NAN;
-''');
-    var nanElement = typeProvider.doubleType.element.getField('NAN');
-    assertEdge(variables.decoratedElementType(nanElement).node,
-        decoratedTypeAnnotation('double f').node,
-        hard: false);
-  }
-
   test_assert_demonstrates_non_null_intent() async {
     await analyze('''
 void f(int i) {
@@ -747,6 +747,48 @@
         hard: true);
   }
 
+  test_assignmentExpression_nullAware_complex_contravariant() async {
+    await analyze('''
+void Function(int) f(void Function(int) x, void Function(int) y) => x ??= y;
+''');
+    var xNullable =
+        decoratedGenericFunctionTypeAnnotation('void Function(int) x').node;
+    var xParamNullable = decoratedTypeAnnotation('int) x').node;
+    var yParamNullable = decoratedTypeAnnotation('int) y').node;
+    var returnParamNullable = decoratedTypeAnnotation('int) f').node;
+    assertEdge(xParamNullable, yParamNullable,
+        hard: false, guards: [xNullable]);
+    assertEdge(returnParamNullable, xParamNullable, hard: false);
+  }
+
+  test_assignmentExpression_nullAware_complex_covariant() async {
+    await analyze('''
+List<int> f(List<int> x, List<int> y) => x ??= y;
+''');
+    var xNullable = decoratedTypeAnnotation('List<int> x').node;
+    var xElementNullable = decoratedTypeAnnotation('int> x').node;
+    var yElementNullable = decoratedTypeAnnotation('int> y').node;
+    var returnElementNullable = decoratedTypeAnnotation('int> f').node;
+    assertEdge(yElementNullable, xElementNullable,
+        hard: false, guards: [xNullable]);
+    assertEdge(xElementNullable, returnElementNullable, hard: false);
+  }
+
+  test_assignmentExpression_nullAware_simple() async {
+    await analyze('''
+int f(int x, int y) => (x ??= y);
+''');
+    var yNullable = decoratedTypeAnnotation('int y').node;
+    var xNullable = decoratedTypeAnnotation('int x').node;
+    var returnNullable = decoratedTypeAnnotation('int f').node;
+    var glbNode = decoratedExpressionType('(x ??= y)').node;
+    assertEdge(yNullable, xNullable, hard: true, guards: [xNullable]);
+    assertEdge(yNullable, glbNode, hard: false, guards: [xNullable]);
+    assertEdge(glbNode, xNullable, hard: false);
+    assertEdge(glbNode, yNullable, hard: false);
+    assertEdge(glbNode, returnNullable, hard: false);
+  }
+
   test_assignmentExpression_operands() async {
     await analyze('''
 void f(int i, int j) {
@@ -939,6 +981,18 @@
     assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
   }
 
+  test_binaryExpression_left_dynamic() async {
+    await analyze('''
+Object f(dynamic x, int y) => x + g(y);
+int g(int z) => z;
+''');
+    assertEdge(decoratedTypeAnnotation('int y').node,
+        decoratedTypeAnnotation('int z').node,
+        hard: true);
+    assertNoEdge(decoratedTypeAnnotation('int g').node, anyNode);
+    assertEdge(always, decoratedTypeAnnotation('Object f').node, hard: false);
+  }
+
   test_binaryExpression_lt_result_not_null() async {
     await analyze('''
 bool f(int i, int j) => i < j;
@@ -1088,6 +1142,20 @@
     assertEdge(right, expression, guards: [left], hard: false);
   }
 
+  test_binaryExpression_right_dynamic() async {
+    await analyze('''
+class C {
+  C operator+(C other) => other;
+}
+C f(C x, dynamic y) => x + y;
+''');
+    assertNullCheck(checkExpression('x +'),
+        assertEdge(decoratedTypeAnnotation('C x').node, never, hard: true));
+    assertEdge(decoratedTypeAnnotation('C operator').node,
+        decoratedTypeAnnotation('C f').node,
+        hard: false);
+  }
+
   test_binaryExpression_slash_result_not_null() async {
     await analyze('''
 double f(int i, int j) => i / j;
@@ -1439,6 +1507,15 @@
     assertLUB(nullable_conditional, nullable_i, always);
   }
 
+  test_constructor_default_parameter_value_bool() async {
+    await analyze('''
+class C {
+  C([bool b = true]);
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('bool b').node);
+  }
+
   test_constructor_named() async {
     await analyze('''
 class C {
@@ -2486,6 +2563,92 @@
     assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
   }
 
+  test_invocation_arguments() async {
+    await analyze('''
+int f(Function g, int i, int j) => g(h(i), named: h(j));
+int h(int x) => 0;
+''');
+    // Make sure the appropriate edges get created for the calls to h().
+    assertEdge(decoratedTypeAnnotation('int i').node,
+        decoratedTypeAnnotation('int x').node,
+        hard: true);
+    assertEdge(decoratedTypeAnnotation('int j').node,
+        decoratedTypeAnnotation('int x').node,
+        hard: true);
+  }
+
+  test_invocation_arguments_parenthesized() async {
+    await analyze('''
+int f(Function g, int i, int j) => (g)(h(i), named: h(j));
+int h(int x) => 0;
+''');
+    // Make sure the appropriate edges get created for the calls to h().
+    assertEdge(decoratedTypeAnnotation('int i').node,
+        decoratedTypeAnnotation('int x').node,
+        hard: true);
+    assertEdge(decoratedTypeAnnotation('int j').node,
+        decoratedTypeAnnotation('int x').node,
+        hard: true);
+  }
+
+  test_invocation_dynamic() async {
+    await analyze('''
+int f(dynamic g) => g();
+''');
+    assertEdge(always, decoratedTypeAnnotation('int f').node, hard: false);
+  }
+
+  test_invocation_dynamic_parenthesized() async {
+    await analyze('''
+int f(dynamic g) => (g)();
+''');
+    assertEdge(always, decoratedTypeAnnotation('int f').node, hard: false);
+  }
+
+  test_invocation_function() async {
+    await analyze('''
+int f(Function g) => g();
+''');
+    assertEdge(always, decoratedTypeAnnotation('int f').node, hard: false);
+    assertNullCheck(
+        checkExpression('g('),
+        assertEdge(decoratedTypeAnnotation('Function g').node, never,
+            hard: true));
+  }
+
+  test_invocation_function_parenthesized() async {
+    await analyze('''
+int f(Function g) => (g)();
+''');
+    assertEdge(always, decoratedTypeAnnotation('int f').node, hard: false);
+    assertNullCheck(
+        checkExpression('g)('),
+        assertEdge(decoratedTypeAnnotation('Function g').node, never,
+            hard: true));
+  }
+
+  test_invocation_type_arguments() async {
+    await analyze('''
+int f(Function g) => g<C<int>>();
+class C<T extends num> {}
+''');
+    // Make sure the appropriate edge gets created for the instantiation of C.
+    assertEdge(decoratedTypeAnnotation('int>').node,
+        decoratedTypeAnnotation('num>').node,
+        hard: true);
+  }
+
+  test_invocation_type_arguments_parenthesized() async {
+    await analyze('''
+int f(Function g) => (g)<C<int>>();
+class C<T extends num> {}
+''');
+    // Make sure the appropriate edge gets created for the instantiation of C.
+    assertEdge(decoratedTypeAnnotation('int>').node,
+        decoratedTypeAnnotation('num>').node,
+        hard: true);
+  }
+
   @failingTest
   test_isExpression_genericFunctionType() async {
     await analyze('''
@@ -2691,6 +2854,35 @@
     assertEdge(always, decoratedTypeAnnotation('int f').node, hard: false);
   }
 
+  test_methodInvocation_dynamic_arguments() async {
+    await analyze('''
+int f(dynamic d, int i, int j) {
+  return d.g(h(i), named: h(j));
+}
+int h(int x) => 0;
+''');
+    // Make sure the appropriate edges get created for the calls to h().
+    assertEdge(decoratedTypeAnnotation('int i').node,
+        decoratedTypeAnnotation('int x').node,
+        hard: true);
+    assertEdge(decoratedTypeAnnotation('int j').node,
+        decoratedTypeAnnotation('int x').node,
+        hard: true);
+  }
+
+  test_methodInvocation_dynamic_type_arguments() async {
+    await analyze('''
+int f(dynamic d, int i, int j) {
+  return d.g<C<int>>();
+}
+class C<T extends num> {}
+''');
+    // Make sure the appropriate edge gets created for the instantiation of C.
+    assertEdge(decoratedTypeAnnotation('int>').node,
+        decoratedTypeAnnotation('num>').node,
+        hard: true);
+  }
+
   test_methodInvocation_object_method() async {
     await analyze('''
 String f(int i) => i.toString();
@@ -4601,12 +4793,36 @@
 
   test_superExpression() async {
     await analyze('''
-class C {
-  C f() => super;
+class B {
+  void f(int/*1*/ i, int/*2*/ j) {}
+}
+class C extends B {
+  void f(int/*3*/ i, int/*4*/ j) => super.f(j, i);
 }
 ''');
+    assertEdge(decoratedTypeAnnotation('int/*3*/').node,
+        decoratedTypeAnnotation('int/*2*/').node,
+        hard: true);
+    assertEdge(decoratedTypeAnnotation('int/*4*/').node,
+        decoratedTypeAnnotation('int/*1*/').node,
+        hard: true);
+  }
 
-    assertNoUpstreamNullability(decoratedTypeAnnotation('C f').node);
+  test_superExpression_generic() async {
+    await analyze('''
+class B<U> {
+  U g() => null;
+}
+class C<T> extends B<T> {
+  T f() => super.g();
+}
+''');
+    assertEdge(
+        substitutionNode(
+            substitutionNode(never, decoratedTypeAnnotation('T> {').node),
+            decoratedTypeAnnotation('U g').node),
+        decoratedTypeAnnotation('T f').node,
+        hard: false);
   }
 
   test_symbolLiteral() async {
@@ -4624,10 +4840,19 @@
   C f() => this;
 }
 ''');
-
     assertNoUpstreamNullability(decoratedTypeAnnotation('C f').node);
   }
 
+  test_thisExpression_generic() async {
+    await analyze('''
+class C<T> {
+  C<T> f() => this;
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('C<T> f').node);
+    assertNoUpstreamNullability(decoratedTypeAnnotation('T> f').node);
+  }
+
   test_throwExpression() async {
     await analyze('''
 int f() {
diff --git a/pkg/smith/lib/configuration.dart b/pkg/smith/lib/configuration.dart
index fc7883a..07653eb 100644
--- a/pkg/smith/lib/configuration.dart
+++ b/pkg/smith/lib/configuration.dart
@@ -908,7 +908,7 @@
 
   /// Opted in to NNBD features, but only static checking and weak runtime
   /// checks.
-  static const optedIn = NnbdMode._('opted-in');
+  static const weak = NnbdMode._('weak');
 
   /// Opted in to NNBD features and with full sound runtime checks.
   static const strong = NnbdMode._('strong');
@@ -916,7 +916,7 @@
   static final List<String> names = _all.keys.toList();
 
   static final _all = {
-    for (var mode in [legacy, optedIn, strong]) mode.name: mode
+    for (var mode in [legacy, weak, strong]) mode.name: mode
   };
 
   static NnbdMode find(String name) {
diff --git a/pkg/smith/test/configuration_test.dart b/pkg/smith/test/configuration_test.dart
index fcbbebf..4f5736e 100644
--- a/pkg/smith/test/configuration_test.dart
+++ b/pkg/smith/test/configuration_test.dart
@@ -198,7 +198,7 @@
       test("other options from map", () {
         expect(
             Configuration.parse("dart2js", {
-              "nnbd": "opted-in",
+              "nnbd": "weak",
               "builder-tag": "the tag",
               "vm-options": ["vm stuff", "more vm stuff"],
               "dart2js-options": ["dart2js stuff", "more dart2js stuff"],
@@ -214,7 +214,7 @@
             }),
             equals(Configuration("dart2js", Architecture.x64, Compiler.dart2js,
                 Mode.release, Runtime.d8, System.host,
-                nnbdMode: NnbdMode.optedIn,
+                nnbdMode: NnbdMode.weak,
                 builderTag: "the tag",
                 vmOptions: ["vm stuff", "more vm stuff"],
                 dart2jsOptions: ["dart2js stuff", "more dart2js stuff"],
diff --git a/pkg/test_runner/bin/test_runner.dart b/pkg/test_runner/bin/test_runner.dart
index 491e10b..3f5e048 100644
--- a/pkg/test_runner/bin/test_runner.dart
+++ b/pkg/test_runner/bin/test_runner.dart
@@ -1,6 +1,7 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for 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';
 
 /// This file is the entrypoint of the Dart repository's custom test system.
 /// It is used to test:
@@ -28,11 +29,16 @@
 void main(List<String> arguments) {
   // Parse the command line arguments to a configuration.
   var parser = OptionsParser();
-  var configurations = parser.parse(arguments);
-  if (configurations == null || configurations.isEmpty) return;
+  try {
+    var configurations = parser.parse(arguments);
+    if (configurations == null || configurations.isEmpty) return;
 
-  // Run all of the configured tests.
-  // TODO(26372): Ensure that all tasks complete and return a future from this
-  // function.
-  testConfigurations(configurations);
+    // Run all of the configured tests.
+    // TODO(26372): Ensure that all tasks complete and return a future from this
+    // function.
+    testConfigurations(configurations);
+  } on OptionParseException catch (exception) {
+    print(exception.message);
+    exit(1);
+  }
 }
diff --git a/pkg/test_runner/lib/src/options.dart b/pkg/test_runner/lib/src/options.dart
index 9de4b81..ed972e7 100644
--- a/pkg/test_runner/lib/src/options.dart
+++ b/pkg/test_runner/lib/src/options.dart
@@ -37,11 +37,16 @@
   // TODO(rnystrom): Some string options use "" to mean "no value" and others
   // use null. Clean that up.
   _Option(this.name, this.description,
-      {String abbr, List<String> values, String defaultsTo, bool hide})
+      {String abbr,
+      List<String> values,
+      String defaultsTo,
+      bool allowMultiple,
+      bool hide})
       : abbreviation = abbr,
         values = values ?? [],
         defaultValue = defaultsTo,
         type = _OptionValueType.string,
+        allowMultiple = allowMultiple ?? true,
         verboseOnly = hide ?? false;
 
   _Option.bool(this.name, this.description, {String abbr, bool hide})
@@ -49,6 +54,7 @@
         values = [],
         defaultValue = false,
         type = _OptionValueType.bool,
+        allowMultiple = false,
         verboseOnly = hide ?? false;
 
   _Option.int(this.name, this.description,
@@ -57,6 +63,7 @@
         values = [],
         defaultValue = defaultsTo,
         type = _OptionValueType.int,
+        allowMultiple = false,
         verboseOnly = hide ?? false;
 
   final String name;
@@ -66,14 +73,16 @@
   final Object defaultValue;
   final _OptionValueType type;
 
+  /// Whether a comma-separated list of values is permitted.
+  final bool allowMultiple;
+
   /// Only show this option in the verbose help.
   final bool verboseOnly;
 
-  /// Gets the shortest command line argument used to refer to this option.
+  /// The shortest command line argument used to refer to this option.
   String get shortCommand => abbreviation != null ? "-$abbreviation" : command;
 
-  /// Gets the canonical long command line argument used to refer to this
-  /// option.
+  /// The canonical long command line argument used to refer to this option.
   String get command => "--${name.replaceAll('_', '-')}";
 }
 
@@ -151,7 +160,6 @@
 test options, specifying how tests should be run.''',
         abbr: 'n',
         hide: true),
-    _Option.bool('strong', 'Deprecated, no-op.', hide: true),
     // TODO(sigmund): rename flag once we migrate all dart2js bots to the test
     // matrix.
     _Option.bool('host_checked', 'Run compiler with assertions enabled.',
@@ -189,7 +197,8 @@
 compact, color, line, verbose, silent, status, buildbot, diff''',
         abbr: 'p',
         values: Progress.names,
-        defaultsTo: Progress.compact.name),
+        defaultsTo: Progress.compact.name,
+        allowMultiple: false),
     _Option('step_name', 'Step name for use by -pbuildbot.', hide: true),
     _Option.bool('report',
         'Print a summary report of the number of tests, by expectation.',
@@ -230,9 +239,14 @@
     _Option('chrome', 'Path to chrome browser executable.', hide: true),
     _Option('safari', 'Path to safari browser executable.', hide: true),
     _Option.bool('use_sdk', '''Use compiler or runtime from the SDK.'''),
-    _Option.bool('nnbd', '''Opt tests into non-nullable types.'''),
-    _Option.bool('nnbd_strong_checking',
-        '''Enable strong runtime checks of non-nullable types.'''),
+    _Option(
+        'nnbd',
+        '''Which set of non-nullable type features to use.
+
+Allowed values are: legacy, weak, strong''',
+        values: NnbdMode.names,
+        defaultsTo: NnbdMode.legacy.name,
+        allowMultiple: false),
     // TODO(rnystrom): This does not appear to be used. Remove?
     _Option('build_directory',
         'The name of the build directory, where products are placed.',
@@ -380,6 +394,7 @@
           verbose: arguments.contains("--verbose") || arguments.contains("-v"));
       return null;
     }
+
     if (arguments.contains("--list-configurations")) {
       var testMatrixFile = "tools/bots/test_matrix.json";
       var testMatrix = TestMatrix.fromPath(testMatrixFile);
@@ -476,11 +491,20 @@
         case _OptionValueType.string:
           // Validate against the allowed values.
           if (!option.values.isEmpty) {
-            for (var v in value.split(",")) {
-              if (!option.values.contains(v)) {
-                _fail('Unknown value "$v" for command line option "$command".');
+            validate(String value) {
+              if (!option.values.contains(value)) {
+                _fail('Unknown value "$value" for option "$command".');
               }
             }
+
+            if (option.allowMultiple) {
+              value.split(",").forEach(validate);
+            } else {
+              if (value.contains(",")) {
+                _fail('Only a single value is allowed for option "$command".');
+              }
+              validate(value);
+            }
           }
 
           // TODO(rnystrom): Store as a list instead of a comma-delimited
@@ -493,9 +517,9 @@
     // If a named configuration was specified ensure no other options, which are
     // implied by the named configuration, were specified.
     if (configuration['named_configuration'] is String) {
-      for (final optionName in _namedConfigurationOptions) {
+      for (var optionName in _namedConfigurationOptions) {
         if (configuration.containsKey(optionName)) {
-          final namedConfig = configuration['named_configuration'];
+          var namedConfig = configuration['named_configuration'];
           _fail("The named configuration '$namedConfig' implies "
               "'$optionName'. Try removing '$optionName'.");
         }
@@ -654,6 +678,9 @@
       compilers.addAll(runtimes.map((runtime) => runtime.defaultCompiler));
     }
 
+    var progress = Progress.find(data["progress"] as String);
+    var nnbdMode = NnbdMode.find(data["nnbd"] as String);
+
     // Expand runtimes.
     for (var runtime in runtimes) {
       // Start installing the runtime if needed.
@@ -676,10 +703,11 @@
             var mode = Mode.find(modeName);
             var system = System.find(data["system"] as String);
             var namedConfiguration =
-                getNamedConfiguration(data["named_configuration"] as String);
+                _namedConfiguration(data["named_configuration"] as String);
             var innerConfiguration = namedConfiguration ??
                 Configuration("custom configuration", architecture, compiler,
                     mode, runtime, system,
+                    nnbdMode: nnbdMode,
                     timeout: data["timeout"] as int,
                     enableAsserts: data["enable_asserts"] as bool,
                     useAnalyzerCfe: data["use_cfe"] as bool,
@@ -700,7 +728,7 @@
                     builderTag: data["builder_tag"] as String);
             var configuration = TestConfiguration(
                 configuration: innerConfiguration,
-                progress: Progress.find(data["progress"] as String),
+                progress: progress,
                 selectors: selectors,
                 testList: data["test_list_contents"] as List<String>,
                 repeat: data["repeat"] as int,
@@ -903,14 +931,22 @@
   }
 }
 
-Configuration getNamedConfiguration(String template) {
+/// Exception thrown when the arguments could not be parsed.
+class OptionParseException implements Exception {
+  final String message;
+
+  OptionParseException(this.message);
+}
+
+Configuration _namedConfiguration(String template) {
   if (template == null) return null;
-  final testMatrixFile = "tools/bots/test_matrix.json";
-  TestMatrix testMatrix = TestMatrix.fromPath(testMatrixFile);
-  final configuration = testMatrix.configurations
+
+  var testMatrixFile = "tools/bots/test_matrix.json";
+  var testMatrix = TestMatrix.fromPath(testMatrixFile);
+  var configuration = testMatrix.configurations
       .singleWhere((c) => c.name == template, orElse: () => null);
   if (configuration == null) {
-    final names = testMatrix.configurations
+    var names = testMatrix.configurations
         .map((configuration) => configuration.name)
         .toList();
     names.sort();
@@ -921,8 +957,7 @@
   return configuration;
 }
 
-/// Prints [message] and exits with a non-zero exit code.
+/// Throws an [OptionParseException] with [message].
 void _fail(String message) {
-  print(message);
-  exit(1);
+  throw OptionParseException(message);
 }
diff --git a/pkg/test_runner/lib/src/process_queue.dart b/pkg/test_runner/lib/src/process_queue.dart
index 72ab4c2..01a2fb1 100644
--- a/pkg/test_runner/lib/src/process_queue.dart
+++ b/pkg/test_runner/lib/src/process_queue.dart
@@ -1131,7 +1131,7 @@
     }
     var processFuture =
         io.Process.start(executable, arguments, environment: environment);
-    processFuture.then((io.Process p) {
+    processFuture.then<dynamic>((io.Process p) {
       _process = p;
 
       Stream<String> _stdoutStream = _process.stdout
diff --git a/pkg/test_runner/lib/src/static_error.dart b/pkg/test_runner/lib/src/static_error.dart
index 518d91b..e339a5e 100644
--- a/pkg/test_runner/lib/src/static_error.dart
+++ b/pkg/test_runner/lib/src/static_error.dart
@@ -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.
 
+// Only needed so that [TestFile] can be referenced in doc comments.
+import 'test_file.dart';
+
 /// Describes a static error.
 ///
 /// These can be parsed from comments in [TestFile]s, in which case they
diff --git a/pkg/test_runner/lib/src/test_case.dart b/pkg/test_runner/lib/src/test_case.dart
index 4e7e080..2b153eaa 100644
--- a/pkg/test_runner/lib/src/test_case.dart
+++ b/pkg/test_runner/lib/src/test_case.dart
@@ -269,7 +269,7 @@
       var processFuture = io.Process.start(command.executable, args,
           environment: processEnvironment,
           workingDirectory: command.workingDirectory);
-      processFuture.then((io.Process process) {
+      processFuture.then<dynamic>((io.Process process) {
         var stdoutFuture = process.stdout.pipe(stdout);
         var stderrFuture = process.stderr.pipe(stderr);
         pid = process.pid;
diff --git a/pkg/test_runner/test/options_test.dart b/pkg/test_runner/test/options_test.dart
new file mode 100644
index 0000000..cf1b98e
--- /dev/null
+++ b/pkg/test_runner/test/options_test.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 'package:test_runner/src/configuration.dart';
+import 'package:test_runner/src/options.dart';
+
+void main() {
+  testDefaults();
+  testOptions();
+  testValidation();
+}
+
+void testDefaults() {
+  // TODO(rnystrom): Test other options.
+  var configuration = parseConfiguration([]);
+  Expect.equals(Progress.compact, configuration.progress);
+  Expect.equals(NnbdMode.legacy, configuration.nnbdMode);
+}
+
+void testOptions() {
+  // TODO(rnystrom): Test other options.
+  var configurations = parseConfigurations(['--mode=debug,release']);
+  Expect.equals(2, configurations.length);
+  Expect.equals(Mode.debug, configurations[0].mode);
+  Expect.equals(Mode.release, configurations[1].mode);
+
+  var configuration = parseConfiguration(['--nnbd=weak']);
+  Expect.equals(NnbdMode.weak, configuration.nnbdMode);
+}
+
+void testValidation() {
+  // TODO(rnystrom): Test other options.
+  expectValidationError(
+      ['--timeout=notint'], 'Integer value expected for option "--timeout".');
+  expectValidationError(
+      ['--timeout=1,2'], 'Integer value expected for option "--timeout".');
+
+  expectValidationError(['--progress=unknown'],
+      'Unknown value "unknown" for option "--progress".');
+  // Don't allow multiple.
+  expectValidationError(['--progress=compact,silent'],
+      'Only a single value is allowed for option "--progress".');
+
+  expectValidationError(
+      ['--nnbd=unknown'], 'Unknown value "unknown" for option "--nnbd".');
+  // Don't allow multiple.
+  expectValidationError(['--nnbd=weak,strong'],
+      'Only a single value is allowed for option "--nnbd".');
+}
+
+TestConfiguration parseConfiguration(List<String> arguments) {
+  var configurations = parseConfigurations(arguments);
+  Expect.equals(1, configurations.length);
+  return configurations.first;
+}
+
+List<TestConfiguration> parseConfigurations(List<String> arguments) {
+  var parser = OptionsParser();
+  var configurations = parser.parse(arguments);
+
+  // By default, without an explicit selector, you get two configurations, one
+  // for observatory_ui, and one for all the other selectors. Discard the
+  // observatory one to keep things simpler.
+  configurations
+      .removeWhere((config) => config.selectors.containsKey('observatory_ui'));
+  return configurations;
+}
+
+void expectValidationError(List<String> arguments, String error) {
+  try {
+    OptionsParser().parse(arguments);
+    Expect.fail('Should have thrown an exception, but did not.');
+  } on OptionParseException catch (exception) {
+    Expect.equals(error, exception.message);
+  } catch (exception) {
+    Expect.fail('Wrong exception: $exception');
+  }
+}
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index f23de40..2ff8888 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -1154,7 +1154,7 @@
 
   char* error = nullptr;
   if (!dart::embedder::InitOnce(&error)) {
-    Syslog::PrintErr("Stanalone embedder initialization failed: %s\n", error);
+    Syslog::PrintErr("Standalone embedder initialization failed: %s\n", error);
     free(error);
     Platform::Exit(kErrorExitCode);
   }
diff --git a/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart b/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart
index 3157090..4feafac 100644
--- a/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart
+++ b/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart
@@ -145,7 +145,7 @@
       completions.forEach((complete) => complete());
 
       final errors = await Future.wait(results.map((future) {
-        return future.then((_) {
+        return future.then<dynamic>((_) {
           expect(false, isTrue, reason: 'shouldn\'t get here');
         }).catchError((e) => e);
       }));
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index 3c70570..4a4cf8f 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -35,7 +35,6 @@
 rewind_optimized_out_test: SkipByDesign # No incremental compiler available.
 rewind_test: SkipByDesign # No incremental compiler available.
 simple_reload_test: RuntimeError, Timeout # Issue 35506
-unused_changes_in_last_reload_test: RuntimeError
 
 [ $compiler == dartkp ]
 *: SkipByDesign # Non-kernel also skips precompiled mode.
@@ -157,7 +156,6 @@
 rewind_test: Pass, RuntimeError
 set_name_rpc_test: RuntimeError # Please triage.
 simple_reload_test: RuntimeError, Timeout
-unused_changes_in_last_reload_test: Skip # Times out on sim architectures.
 valid_source_locations_test: Pass, Slow, Timeout # Issue 34736
 
 # Kernel works slightly different. There are kernel specific versions.
@@ -171,4 +169,3 @@
 evaluate_activation_test/scope: RuntimeError # http://dartbug.com/20047
 get_source_report_test: RuntimeError # Should pass again when constant evaluation is relanded, see http://dartbug.com/36600
 pause_on_unhandled_async_exceptions2_test: Pass, Slow
-unused_changes_in_last_reload_test: RuntimeError
diff --git a/runtime/observatory/tests/service/unused_changes_in_last_reload/v1/main.dart b/runtime/observatory/tests/service/unused_changes_in_last_reload/v1/main.dart
deleted file mode 100644
index 28f600c..0000000
--- a/runtime/observatory/tests/service/unused_changes_in_last_reload/v1/main.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for 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:isolate';
-
-unchangedFunction() => "unchanged";
-var unchangedField = "unchanged".toString();
-
-removedFunction() => "removed";
-var removedField = "removed".toString();
-
-function() => "original value";
-var uninitializedField = "original initializer".toString();
-var fieldLiteralInitializer = "original initializer";
-var initializedField = "original initializer".toString();
-var neverReferencedField = "original initializer".toString();
-
-// Not initially finalized.
-class C {
-  function() => "original value";
-}
-
-class S {}
-class M {}
-class MA1 extends S with M {}
-class MA2 = S with M;
-
-main() {
-  new RawReceivePort();  // Keep alive.
-  print(function());
-  print(initializedField);
-  print(new MA1());
-  print(new MA2());
-}
diff --git a/runtime/observatory/tests/service/unused_changes_in_last_reload/v2/main.dart b/runtime/observatory/tests/service/unused_changes_in_last_reload/v2/main.dart
deleted file mode 100644
index 910904f..0000000
--- a/runtime/observatory/tests/service/unused_changes_in_last_reload/v2/main.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-unchangedFunction() => "unchanged";
-var unchangedField = "unchanged".toString();
-
-function() => "new value";
-var uninitializedField = "new initializer".toString();
-var fieldLiteralInitializer = "new initializer";
-var initializedField = "new initializer".toString();
-var neverReferencedField = "new initializer".toString();
-
-// Not initially finalized.
-class C {
-  function() => "new value";
-}
-
-class S {}
-class M {
-  newFunction() => "new value";
-}
-class MA1 extends S with M {
-  newFunction2() => "new value";
-}
-class MA2 = S with M;
-
-class NewClass {
-  function() => "new value";
-}
-
-typedef bool NewTypedef(Object obj);
-
-main2() {
-  print(function());
-  print(uninitializedField);
-  print(initializedField);
-  print(new C().function());
-  print(new NewClass().function());
-  print(new MA1().newFunction());
-  print(new MA1().newFunction2());
-}
diff --git a/runtime/observatory/tests/service/unused_changes_in_last_reload_test.dart b/runtime/observatory/tests/service/unused_changes_in_last_reload_test.dart
deleted file mode 100644
index 223ac40..0000000
--- a/runtime/observatory/tests/service/unused_changes_in_last_reload_test.dart
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for 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 'test_helper.dart';
-import 'dart:developer';
-import 'dart:isolate' as I;
-import 'dart:io';
-import 'service_test_common.dart';
-import 'package:observatory/service.dart';
-import 'package:path/path.dart' as path;
-import 'package:unittest/unittest.dart';
-
-// Chop off the file name.
-String baseDirectory = path.dirname(Platform.script.path) + '/';
-
-Uri baseUri = Platform.script.replace(path: baseDirectory);
-Uri v1Uri = baseUri.resolveUri(Uri.parse('unused_changes_in_last_reload/v1/main.dart'));
-Uri v2Uri = baseUri.resolveUri(Uri.parse('unused_changes_in_last_reload/v2/main.dart'));
-
-testMain() async {
-  print(baseUri);
-  debugger(); // Stop here.
-  // Spawn the child isolate.
-  I.Isolate isolate = await I.Isolate.spawnUri(v1Uri, [], null);
-  print(isolate);
-  debugger();
-}
-
-var tests = <IsolateTest>[
-  // Stopped at 'debugger' statement.
-  hasStoppedAtBreakpoint,
-  // Resume the isolate into the while loop.
-  resumeIsolate,
-  // Stop at 'debugger' statement.
-  hasStoppedAtBreakpoint,
-  (Isolate mainIsolate) async {
-    // Grab the VM.
-    VM vm = mainIsolate.vm;
-    await vm.reloadIsolates();
-    expect(vm.isolates.length, 2);
-
-    // Find the child isolate.
-    Isolate childIsolate =
-        vm.isolates.firstWhere((Isolate i) => i != mainIsolate);
-    expect(childIsolate, isNotNull);
-
-    // Fetch unused.
-    await childIsolate.invokeRpc("_getUnusedChangesInLastReload", {}).then((v) {
-      print(v);
-      throw "MissingError";
-    }, onError: (e) {
-      print(e);
-    });
-
-    // Reload to v1 (null change).
-    var response = await childIsolate.reloadSources(
-      rootLibUri: v1Uri.toString(),
-    );
-    print(response);
-    expect(response['success'], isTrue);
-
-    // Fetch unused.
-    response = await childIsolate.invokeRpc("_getUnusedChangesInLastReload", {});
-    print(response);
-    var unused = response['unused'].map((ea) => ea.toString());
-    expect(unused, unorderedEquals([]));
-
-    // Reload to v2.
-    response = await childIsolate.reloadSources(
-      rootLibUri: v2Uri.toString(),
-    );
-    print(response);
-    expect(response['success'], isTrue);
-
-    // Fetch unused.
-    response = await childIsolate.invokeRpc("_getUnusedChangesInLastReload", {});
-    print(response);
-    unused = response['unused'].map((ea) => ea.toString());
-    expect(unused, unorderedEquals([
-      'Class(C)',
-      'Class(NewClass)',
-      'Field(main.dart.uninitializedField)',
-      'Field(main.dart.fieldLiteralInitializer)',
-      'Field(main.dart.initializedField)',
-      'Field(main.dart.neverReferencedField)',
-      'ServiceFunction(M.newFunction)',
-      'ServiceFunction(MA1.newFunction2)',
-      'ServiceFunction(function)',
-      'ServiceFunction(main2)',
-    ]));
-
-    // Invoke next main.
-    Library lib = childIsolate.rootLibrary;
-    await lib.load();
-    Instance result = await lib.evaluate('main2()');
-    expect(result.valueAsString, equals('null'));
-
-    // Fetch unused.
-    response = await childIsolate.invokeRpc("_getUnusedChangesInLastReload", {});
-    print(response);
-    unused = response['unused'].map((ea) => ea.toString());
-    expect(unused, unorderedEquals([
-      'Field(main.dart.fieldLiteralInitializer)',
-      'Field(main.dart.initializedField)',
-      'Field(main.dart.neverReferencedField)',
-      // TODO(31265): M.newFunction should be considered used.
-      'ServiceFunction(M.newFunction)',
-    ]));
-
-    // Reload to v2 again.
-    response = await childIsolate.reloadSources(
-      rootLibUri: v2Uri.toString(),
-    );
-    print(response);
-    expect(response['success'], isTrue);
-
-    // Fetch unused.
-    response = await childIsolate.invokeRpc("_getUnusedChangesInLastReload", {});
-    print(response);
-    unused = response['unused'].map((ea) => ea.toString());
-    expect(unused, unorderedEquals([]));
-  }
-];
-
-main(args) => runIsolateTests(args, tests, testeeConcurrent: testMain);
diff --git a/runtime/tools/bin_to_coff.py b/runtime/tools/bin_to_coff.py
index c8a8ebc..1925bcd 100644
--- a/runtime/tools/bin_to_coff.py
+++ b/runtime/tools/bin_to_coff.py
@@ -4,8 +4,6 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-# See also "PE Format" at https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
-
 import argparse
 from ctypes import create_string_buffer
 from struct import *
@@ -21,7 +19,6 @@
 SECTION_HEADER_TEXT = 0x20  # Contains executable code
 SECTION_HEADER_DATA = 0x40  # Contains only initialized data
 SECTION_HEADER_BSS = 0x80  # Contains uninitialized data
-SECTION_HEADER_ALIGN_32BYTES = 0x600000
 
 # FILE HEADER FORMAT
 # typedef struct {
@@ -179,18 +176,17 @@
     offset += FILE_HEADER_SIZE
 
     section_name = SECTION_NAME_RODATA
-    section_flags = SECTION_HEADER_DATA
+    section_type = SECTION_HEADER_DATA
     if args.executable:
         section_name = SECTION_NAME_TEXT
-        section_flags = SECTION_HEADER_TEXT
-    section_flags |= SECTION_HEADER_ALIGN_32BYTES
+        section_type = SECTION_HEADER_TEXT
 
     # Populate the section header for a single section.
     pack_into(SECTION_HEADER_FORMAT, buff, offset, section_name, SECTION_PADDR,
               SECTION_VADDR, section_size + size_symbol_size,
               SECTION_RAW_DATA_PTR, SECTION_RELOCATION_PTR,
               SECTION_LINE_NUMS_PTR, SECTION_NUM_RELOCATION,
-              SECTION_NUM_LINE_NUMS, section_flags)
+              SECTION_NUM_LINE_NUMS, section_type)
     offset += SECTION_HEADER_SIZE
 
     # Copy the binary data.
diff --git a/runtime/tools/dartfuzz/collect_data.py b/runtime/tools/dartfuzz/collect_data.py
index 25b5f5d..6ce118f 100755
--- a/runtime/tools/dartfuzz/collect_data.py
+++ b/runtime/tools/dartfuzz/collect_data.py
@@ -87,8 +87,8 @@
         for i in range(len(s)):
             s[i] += int(test[i])
     print(
-        "Tests: %d Success: %d (Rerun: %d) Skipped: %d Timeout: %d Divergences: %d"
-        "(failing shards: %s)    \r" %
+        "Tests: %d Success: %d (Rerun: %d) Skipped: %d Timeout: %d "
+        "Divergences: %d (failing shards: %s)    \r" %
         tuple(s + [", ".join(divs) if divs else "none"]),
         end="")
 
diff --git a/runtime/tools/dartfuzz/dartfuzz.dart b/runtime/tools/dartfuzz/dartfuzz.dart
index cc97ad8..8a02ff3 100644
--- a/runtime/tools/dartfuzz/dartfuzz.dart
+++ b/runtime/tools/dartfuzz/dartfuzz.dart
@@ -14,7 +14,7 @@
 // Version of DartFuzz. Increase this each time changes are made
 // to preserve the property that a given version of DartFuzz yields
 // the same fuzzed program for a deterministic random seed.
-const String version = '1.39';
+const String version = '1.42';
 
 // Restriction on statements and expressions.
 const int stmtLength = 2;
@@ -167,45 +167,74 @@
     emitLn(').cast<ffi.NativeFunction<${typeName}>>().asFunction();');
   }
 
+  void emitMethod(
+      String name, int index, List<DartType> method, bool isFfiMethod) {
+    if (isFfiMethod) {
+      emitFfiTypedef("${name}Ffi${index}Type", method);
+      emitLn('${method[0].name} ${name}Ffi$index(', newline: false);
+    } else {
+      emitLn('${method[0].name} $name$index(', newline: false);
+    }
+    emitParDecls(method);
+    if (!isFfiMethod && rand.nextInt(10) == 0) {
+      // Emit a method using "=>" syntax.
+      emit(') => ');
+      emitExpr(0, method[0]);
+      emit(';', newline: true);
+      return;
+    }
+    emit(') {', newline: true);
+    indent += 2;
+    assert(localVars.isEmpty);
+    if (emitStatements(0)) {
+      emitReturn();
+    }
+    assert(localVars.isEmpty);
+    indent -= 2;
+    emitLn('}');
+    if (isFfiMethod) {
+      emitFfiCast("${name}${index}", "${name}Ffi${index}",
+          "${name}Ffi${index}Type", method);
+    }
+    emit('', newline: true);
+  }
+
   void emitMethods(String name, List<List<DartType>> methods,
       [List<bool> ffiStatus]) {
     for (int i = 0; i < methods.length; i++) {
       List<DartType> method = methods[i];
       currentMethod = i;
       final bool isFfiMethod = ffiStatus != null && ffiStatus[i];
-      if (isFfiMethod) {
-        emitFfiTypedef("${name}Ffi${i}Type", method);
-        emitLn('${method[0].name} ${name}Ffi$i(', newline: false);
-      } else {
-        emitLn('${method[0].name} $name$i(', newline: false);
-      }
-      emitParDecls(method);
-      if (!isFfiMethod && rand.nextInt(10) == 0) {
-        // Emit a method using "=>" syntax.
-        emit(') => ');
-        emitExpr(0, method[0]);
-        emit(';', newline: true);
-        currentMethod = null;
-        continue;
-      }
-      emit(') {', newline: true);
-      indent += 2;
-      assert(localVars.isEmpty);
-      if (emitStatements(0)) {
-        emitReturn();
-      }
-      assert(localVars.isEmpty);
-      indent -= 2;
-      emitLn('}');
-      if (isFfiMethod) {
-        emitFfiCast(
-            "${name}${i}", "${name}Ffi${i}", "${name}Ffi${i}Type", method);
-      }
-      emit('', newline: true);
+      emitMethod(name, i, method, isFfiMethod);
       currentMethod = null;
     }
   }
 
+  // Randomly overwrite some methods from the parent classes.
+  void emitVirtualMethods() {
+    final currentClassTmp = currentClass;
+    int parentClass = classParents[currentClass];
+    // Chase randomly up in class hierarchy.
+    while (parentClass >= 0) {
+      for (int j = 0, n = classMethods[parentClass].length; j < n; j++) {
+        if (rand.nextInt(8) == 0) {
+          currentClass = parentClass;
+          currentMethod = j;
+          emitMethod('$methodName${parentClass}_', j,
+              classMethods[parentClass][j], false);
+          currentMethod = null;
+          currentClass = null;
+        }
+      }
+      if (rand.nextInt(2) == 0 || classParents.length > parentClass) {
+        break;
+      } else {
+        parentClass = classParents[parentClass];
+      }
+    }
+    currentClass = currentClassTmp;
+  }
+
   void emitClasses() {
     assert(classFields.length == classMethods.length);
     for (int i = 0; i < classFields.length; i++) {
@@ -231,6 +260,7 @@
       indent += 2;
       emitVarDecls('$fieldName${i}_', classFields[i]);
       currentClass = i;
+      emitVirtualMethods();
       emitMethods('$methodName${i}_', classMethods[i]);
       emitLn('void run() {');
       indent += 2;
@@ -768,12 +798,16 @@
 
   void emitCollectionElement(int depth, DartType tp) {
     int r = depth <= exprDepth ? rand.nextInt(10) : 10;
-    // TODO(ajcbik): renable, https://github.com/dart-lang/sdk/issues/38231
-    switch (r + 3) {
+    switch (r) {
       // Favors elements over control-flow collections.
       case 0:
-        emit('...'); // spread
-        emitCollection(depth + 1, tp);
+        // TODO (ajcbik): Remove restriction once compiler is fixed.
+        if (depth < 2) {
+          emit('...'); // spread
+          emitCollection(depth + 1, tp);
+        } else {
+          emitElement(depth, tp);
+        }
         break;
       case 1:
         emit('if (');
diff --git a/runtime/tools/dartfuzz/dartfuzz_test.dart b/runtime/tools/dartfuzz/dartfuzz_test.dart
index e5cce1d..3dc78e3 100644
--- a/runtime/tools/dartfuzz/dartfuzz_test.dart
+++ b/runtime/tools/dartfuzz/dartfuzz_test.dart
@@ -239,8 +239,10 @@
   }
 
   void printReproductionCommand() {
-    print(
-        [generate, '--gen-bytecode', platform, '-o', dill, fileName].join(" "));
+    if (generate != null) {
+      print([generate, '--gen-bytecode', platform, '-o', dill, fileName]
+          .join(" "));
+    }
     print(cmd.join(" "));
   }
 
@@ -485,7 +487,7 @@
 
   void showReproduce() {
     print("\n-- BEGIN REPRODUCE  --\n");
-    print("dartfuzz.dart --${ffi ? "" : "no-"}ffi --${fp ? "" : "no-"}fp"
+    print("dartfuzz.dart --${ffi ? "" : "no-"}ffi --${fp ? "" : "no-"}fp "
         "--seed ${seed} $fileName");
     print("\n-- RUN 1 --\n");
     runner1.printReproductionCommand();
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index db49703..a95642a 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -511,13 +511,25 @@
   return reinterpret_cast<uint8_t*>(realloc(ptr, new_size));
 }
 
-// Start an Isolate, load a script and create a full snapshot.
-static void BenchmarkSnapshotSize(Benchmark* benchmark, const char* script) {
+BENCHMARK_SIZE(CoreSnapshotSize) {
+  const char* kScriptChars =
+      "import 'dart:async';\n"
+      "import 'dart:core';\n"
+      "import 'dart:collection';\n"
+      "import 'dart:_internal';\n"
+      "import 'dart:math';\n"
+      "import 'dart:isolate';\n"
+      "import 'dart:mirrors';\n"
+      "import 'dart:typed_data';\n"
+      "\n";
+
+  // Start an Isolate, load a script and create a full snapshot.
+  uint8_t* vm_snapshot_data_buffer;
+  uint8_t* isolate_snapshot_data_buffer;
   // Need to load the script into the dart: core library due to
   // the import of dart:_internal.
-  TestCase::LoadCoreTestScript(script, nullptr);
+  TestCase::LoadCoreTestScript(kScriptChars, NULL);
 
-  Thread* thread = Thread::Current();
   TransitionNativeToVM transition(thread);
   StackZone zone(thread);
   HANDLESCOPE(thread);
@@ -525,63 +537,58 @@
   Api::CheckAndFinalizePendingClasses(thread);
 
   // Write snapshot with object content.
-  uint8_t* vm_snapshot_data_buffer = nullptr;
-  uint8_t* isolate_snapshot_data_buffer = nullptr;
-  uint8_t* vm_snapshot_text_buffer = nullptr;
-  uint8_t* isolate_snapshot_text_buffer = nullptr;
-  BlobImageWriter vm_image_writer(thread, &vm_snapshot_text_buffer,
-                                  &malloc_allocator, 2 * MB /* initial_size */,
-                                  /*shared_objects=*/nullptr,
-                                  /*shared_instructions=*/nullptr,
-                                  /*reused_instructions=*/nullptr);
-  BlobImageWriter isolate_image_writer(thread, &isolate_snapshot_text_buffer,
-                                       &malloc_allocator,
-                                       2 * MB /* initial_size */,
-                                       /*shared_objects=*/nullptr,
-                                       /*shared_instructions=*/nullptr,
-                                       /*reused_instructions=*/nullptr);
   FullSnapshotWriter writer(Snapshot::kFull, &vm_snapshot_data_buffer,
                             &isolate_snapshot_data_buffer, &malloc_allocator,
-                            &vm_image_writer, &isolate_image_writer);
+                            NULL, NULL /* image_writer */);
   writer.WriteFullSnapshot();
   const Snapshot* snapshot =
       Snapshot::SetupFromBuffer(isolate_snapshot_data_buffer);
   ASSERT(snapshot->kind() == Snapshot::kFull);
-  benchmark->set_score(writer.IsolateSnapshotSize() +
-                       isolate_image_writer.data_size());
+  benchmark->set_score(snapshot->length());
 
   free(vm_snapshot_data_buffer);
-  free(vm_snapshot_text_buffer);
   free(isolate_snapshot_data_buffer);
-  free(isolate_snapshot_text_buffer);
-}
-
-BENCHMARK_SIZE(CoreSnapshotSize) {
-  BenchmarkSnapshotSize(benchmark,
-                        "import 'dart:async';\n"
-                        "import 'dart:core';\n"
-                        "import 'dart:collection';\n"
-                        "import 'dart:_internal';\n"
-                        "import 'dart:math';\n"
-                        "import 'dart:isolate';\n"
-                        "import 'dart:mirrors';\n"
-                        "import 'dart:typed_data';\n"
-                        "\n");
 }
 
 BENCHMARK_SIZE(StandaloneSnapshotSize) {
-  BenchmarkSnapshotSize(benchmark,
-                        "import 'dart:async';\n"
-                        "import 'dart:core';\n"
-                        "import 'dart:collection';\n"
-                        "import 'dart:convert';\n"
-                        "import 'dart:math';\n"
-                        "import 'dart:isolate';\n"
-                        "import 'dart:mirrors';\n"
-                        "import 'dart:typed_data';\n"
-                        "import 'dart:io';\n"
-                        "import 'dart:cli';\n"
-                        "\n");
+  const char* kScriptChars =
+      "import 'dart:async';\n"
+      "import 'dart:core';\n"
+      "import 'dart:collection';\n"
+      "import 'dart:convert';\n"
+      "import 'dart:math';\n"
+      "import 'dart:isolate';\n"
+      "import 'dart:mirrors';\n"
+      "import 'dart:typed_data';\n"
+      "import 'dart:io';\n"
+      "import 'dart:cli';\n"
+      "\n";
+
+  // Start an Isolate, load a script and create a full snapshot.
+  uint8_t* vm_snapshot_data_buffer;
+  uint8_t* isolate_snapshot_data_buffer;
+  // Need to load the script into the dart: core library due to
+  // the import of dart:_internal.
+  TestCase::LoadCoreTestScript(kScriptChars, NULL);
+
+  TransitionNativeToVM transition(thread);
+  StackZone zone(thread);
+  HANDLESCOPE(thread);
+
+  Api::CheckAndFinalizePendingClasses(thread);
+
+  // Write snapshot with object content.
+  FullSnapshotWriter writer(Snapshot::kFull, &vm_snapshot_data_buffer,
+                            &isolate_snapshot_data_buffer, &malloc_allocator,
+                            NULL, NULL /* image_writer */);
+  writer.WriteFullSnapshot();
+  const Snapshot* snapshot =
+      Snapshot::SetupFromBuffer(isolate_snapshot_data_buffer);
+  ASSERT(snapshot->kind() == Snapshot::kFull);
+  benchmark->set_score(snapshot->length());
+
+  free(vm_snapshot_data_buffer);
+  free(isolate_snapshot_data_buffer);
 }
 
 BENCHMARK(CreateMirrorSystem) {
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index 7a7f898..a9d7943 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -16,58 +16,99 @@
 
 DEFINE_FLAG(bool, print_class_table, false, "Print initial class table.");
 
-ClassTable::ClassTable()
+SharedClassTable::SharedClassTable()
     : top_(kNumPredefinedCids),
       capacity_(0),
       table_(NULL),
-      old_tables_(new MallocGrowableArray<ClassAndSize*>()) {
-  NOT_IN_PRODUCT(class_heap_stats_table_ = NULL);
+      old_tables_(new MallocGrowableArray<intptr_t*>()) {
   if (Dart::vm_isolate() == NULL) {
-    capacity_ = initial_capacity_;
-    table_ = reinterpret_cast<ClassAndSize*>(
-        calloc(capacity_, sizeof(ClassAndSize)));  // NOLINT
+    ASSERT(kInitialCapacity >= kNumPredefinedCids);
+    capacity_ = kInitialCapacity;
+    // Note that [calloc] will zero-initialize the memory.
+    table_ = static_cast<intptr_t*>(calloc(capacity_, sizeof(intptr_t)));
   } else {
     // Duplicate the class table from the VM isolate.
-    ClassTable* vm_class_table = Dart::vm_isolate()->class_table();
-    capacity_ = vm_class_table->capacity_;
-    table_ = reinterpret_cast<ClassAndSize*>(
-        calloc(capacity_, sizeof(ClassAndSize)));  // NOLINT
+    auto vm_shared_class_table = Dart::vm_isolate()->shared_class_table();
+    capacity_ = vm_shared_class_table->capacity_;
+    // Note that [calloc] will zero-initialize the memory.
+    table_ = static_cast<intptr_t*>(calloc(capacity_, sizeof(RawClass*)));
+    // The following cids don't have a corresponding class object in Dart code.
+    // We therefore need to initialize them eagerly.
     for (intptr_t i = kObjectCid; i < kInstanceCid; i++) {
-      table_[i] = vm_class_table->PairAt(i);
+      table_[i] = vm_shared_class_table->SizeAt(i);
     }
-    table_[kTypeArgumentsCid] = vm_class_table->PairAt(kTypeArgumentsCid);
-    table_[kFreeListElement] = vm_class_table->PairAt(kFreeListElement);
-    table_[kForwardingCorpse] = vm_class_table->PairAt(kForwardingCorpse);
-    table_[kDynamicCid] = vm_class_table->PairAt(kDynamicCid);
-    table_[kVoidCid] = vm_class_table->PairAt(kVoidCid);
+    table_[kTypeArgumentsCid] =
+        vm_shared_class_table->SizeAt(kTypeArgumentsCid);
+    table_[kFreeListElement] = vm_shared_class_table->SizeAt(kFreeListElement);
+    table_[kForwardingCorpse] =
+        vm_shared_class_table->SizeAt(kForwardingCorpse);
+    table_[kDynamicCid] = vm_shared_class_table->SizeAt(kDynamicCid);
+    table_[kVoidCid] = vm_shared_class_table->SizeAt(kVoidCid);
   }
 #ifndef PRODUCT
-  class_heap_stats_table_ = reinterpret_cast<ClassHeapStats*>(
-      calloc(capacity_, sizeof(ClassHeapStats)));  // NOLINT
+  class_heap_stats_table_ = static_cast<ClassHeapStats*>(
+      malloc(capacity_ * sizeof(ClassHeapStats)));  // NOLINT
   for (intptr_t i = 0; i < capacity_; i++) {
     class_heap_stats_table_[i].Initialize();
   }
 #endif  // !PRODUCT
 }
-
-ClassTable::ClassTable(ClassTable* original)
-    : top_(original->top_),
-      capacity_(original->top_),
-      table_(original->table_),
-      old_tables_(NULL) {
-  NOT_IN_PRODUCT(class_heap_stats_table_ = NULL);
-}
-
-ClassTable::~ClassTable() {
+SharedClassTable::~SharedClassTable() {
   if (old_tables_ != NULL) {
     FreeOldTables();
     delete old_tables_;
     free(table_);
-    NOT_IN_PRODUCT(free(class_heap_stats_table_));
-  } else {
-    // This instance was a shallow copy. It doesn't own any memory.
-    NOT_IN_PRODUCT(ASSERT(class_heap_stats_table_ == NULL));
   }
+  NOT_IN_PRODUCT(free(class_heap_stats_table_));
+}
+
+ClassTable::ClassTable(SharedClassTable* shared_class_table)
+    : top_(kNumPredefinedCids),
+      capacity_(0),
+      table_(NULL),
+      old_tables_(new MallocGrowableArray<ClassAndSize*>()),
+      old_class_tables_(new MallocGrowableArray<RawClass**>()),
+      shared_class_table_(shared_class_table) {
+  if (Dart::vm_isolate() == NULL) {
+    ASSERT(kInitialCapacity >= kNumPredefinedCids);
+    capacity_ = kInitialCapacity;
+    // Note that [calloc] will zero-initialize the memory.
+    table_ = static_cast<RawClass**>(calloc(capacity_, sizeof(RawClass*)));
+  } else {
+    // Duplicate the class table from the VM isolate.
+    ClassTable* vm_class_table = Dart::vm_isolate()->class_table();
+    capacity_ = vm_class_table->capacity_;
+    // Note that [calloc] will zero-initialize the memory.
+    table_ = static_cast<RawClass**>(calloc(capacity_, sizeof(RawClass*)));
+    // The following cids don't have a corresponding class object in Dart code.
+    // We therefore need to initialize them eagerly.
+    for (intptr_t i = kObjectCid; i < kInstanceCid; i++) {
+      table_[i] = vm_class_table->At(i);
+    }
+    table_[kTypeArgumentsCid] = vm_class_table->At(kTypeArgumentsCid);
+    table_[kFreeListElement] = vm_class_table->At(kFreeListElement);
+    table_[kForwardingCorpse] = vm_class_table->At(kForwardingCorpse);
+    table_[kDynamicCid] = vm_class_table->At(kDynamicCid);
+    table_[kVoidCid] = vm_class_table->At(kVoidCid);
+  }
+}
+
+ClassTable::ClassTable(ClassTable* original,
+                       SharedClassTable* shared_class_table)
+    : top_(original->top_),
+      capacity_(original->top_),
+      table_(original->table_),
+      old_tables_(nullptr),
+      old_class_tables_(nullptr),
+      shared_class_table_(shared_class_table) {}
+
+ClassTable::~ClassTable() {
+  if (old_tables_ != nullptr || old_class_tables_ != nullptr) {
+    FreeOldTables();
+    delete old_tables_;
+    delete old_class_tables_;
+  }
+  free(table_);
 }
 
 void ClassTable::AddOldTable(ClassAndSize* old_table) {
@@ -79,17 +120,32 @@
   while (old_tables_->length() > 0) {
     free(old_tables_->RemoveLast());
   }
+  while (old_class_tables_->length() > 0) {
+    free(old_class_tables_->RemoveLast());
+  }
+}
+
+void SharedClassTable::FreeOldTables() {
+  while (old_tables_->length() > 0) {
+    free(old_tables_->RemoveLast());
+  }
 }
 
 void ClassTable::Register(const Class& cls) {
   ASSERT(Thread::Current()->IsMutatorThread());
-  intptr_t index = cls.id();
+
+  const intptr_t index = cls.id();
+
+  // During the transition period we would like [SharedClassTable] to operate in
+  // parallel to [ClassTable].
+  const intptr_t expected_cid =
+      shared_class_table_->Register(index, Class::instance_size(cls.raw()));
+
   if (index != kIllegalCid) {
-    ASSERT(index > 0);
-    ASSERT(index < kNumPredefinedCids);
-    ASSERT(table_[index].class_ == NULL);
-    ASSERT(index < capacity_);
-    table_[index] = ClassAndSize(cls.raw(), Class::instance_size(cls.raw()));
+    ASSERT(index > 0 && index < kNumPredefinedCids && index < top_);
+    ASSERT(table_[index] == nullptr);
+    table_[index] = cls.raw();
+
     // Add the vtable for this predefined class into the static vtable registry
     // if it has not been setup yet.
     cpp_vtable cls_vtable = cls.handle_vtable();
@@ -100,95 +156,141 @@
     }
   } else {
     if (top_ == capacity_) {
-      // Grow the capacity of the class table.
-      // TODO(koda): Add ClassTable::Grow to share code.
-
-#ifndef PRODUCT
-      // Wait for any marking tasks to complete. Allocation stats in the
-      // marker rely on the class table size not changing.
-      Thread* thread = Thread::Current();
-      thread->heap()->WaitForMarkerTasks(thread);
-#endif
-
-      intptr_t new_capacity = capacity_ + capacity_increment_;
-      ClassAndSize* new_table = reinterpret_cast<ClassAndSize*>(
-          malloc(new_capacity * sizeof(ClassAndSize)));  // NOLINT
-      memmove(new_table, table_, capacity_ * sizeof(ClassAndSize));
-#ifndef PRODUCT
-      ClassHeapStats* new_stats_table = reinterpret_cast<ClassHeapStats*>(
-          realloc(class_heap_stats_table_,
-                  new_capacity * sizeof(ClassHeapStats)));  // NOLINT
-#endif
-      for (intptr_t i = capacity_; i < new_capacity; i++) {
-        new_table[i] = ClassAndSize(NULL, 0);
-        NOT_IN_PRODUCT(new_stats_table[i].Initialize());
-      }
-      capacity_ = new_capacity;
-      old_tables_->Add(table_);
-      table_ = new_table;  // TODO(koda): This should use atomics.
-      NOT_IN_PRODUCT(class_heap_stats_table_ = new_stats_table);
+      const intptr_t new_capacity = capacity_ + kCapacityIncrement;
+      Grow(new_capacity);
     }
     ASSERT(top_ < capacity_);
-    if (!Class::is_valid_id(top_)) {
-      FATAL1("Fatal error in ClassTable::Register: invalid index %" Pd "\n",
-             top_);
-    }
     cls.set_id(top_);
-    table_[top_] = ClassAndSize(cls.raw());
+    table_[top_] = cls.raw();
     top_++;  // Increment next index.
   }
+  ASSERT(expected_cid == cls.id());
+}
+
+intptr_t SharedClassTable::Register(intptr_t index, intptr_t size) {
+  if (!Class::is_valid_id(top_)) {
+    FATAL1("Fatal error in SharedClassTable::Register: invalid index %" Pd "\n",
+           top_);
+  }
+
+  ASSERT(Thread::Current()->IsMutatorThread());
+  if (index != kIllegalCid) {
+    // We are registring the size of a predefined class.
+    ASSERT(index > 0 && index < kNumPredefinedCids);
+    SetSizeAt(index, size);
+    return index;
+  } else {
+    if (top_ == capacity_) {
+      const intptr_t new_capacity = capacity_ + kCapacityIncrement;
+      Grow(new_capacity);
+    }
+    ASSERT(top_ < capacity_);
+    table_[top_] = size;
+    return top_++;  // Increment next index.
+  }
 }
 
 void ClassTable::AllocateIndex(intptr_t index) {
+  // This is called by a snapshot reader.
+  shared_class_table_->AllocateIndex(index);
+  ASSERT(Class::is_valid_id(index));
+
   if (index >= capacity_) {
-    // Grow the capacity of the class table.
-    // TODO(koda): Add ClassTable::Grow to share code.
-
-#ifndef PRODUCT
-    // Wait for any marking tasks to complete. Allocation stats in the
-    // marker rely on the class table size not changing.
-    Thread* thread = Thread::Current();
-    thread->heap()->WaitForMarkerTasks(thread);
-#endif
-
-    intptr_t new_capacity = index + capacity_increment_;
-    if (!Class::is_valid_id(index) || new_capacity < capacity_) {
-      FATAL1("Fatal error in ClassTable::Register: invalid index %" Pd "\n",
-             index);
-    }
-    ClassAndSize* new_table = reinterpret_cast<ClassAndSize*>(
-        malloc(new_capacity * sizeof(ClassAndSize)));  // NOLINT
-    memmove(new_table, table_, capacity_ * sizeof(ClassAndSize));
-#ifndef PRODUCT
-    ClassHeapStats* new_stats_table = reinterpret_cast<ClassHeapStats*>(
-        realloc(class_heap_stats_table_,
-                new_capacity * sizeof(ClassHeapStats)));  // NOLINT
-#endif
-    for (intptr_t i = capacity_; i < new_capacity; i++) {
-      new_table[i] = ClassAndSize(NULL);
-      NOT_IN_PRODUCT(new_stats_table[i].Initialize());
-    }
-    capacity_ = new_capacity;
-    old_tables_->Add(table_);
-    table_ = new_table;  // TODO(koda): This should use atomics.
-    NOT_IN_PRODUCT(class_heap_stats_table_ = new_stats_table);
-    ASSERT(capacity_increment_ >= 1);
+    const intptr_t new_capacity = index + kCapacityIncrement;
+    Grow(new_capacity);
   }
 
-  ASSERT(table_[index].class_ == NULL);
+  ASSERT(table_[index] == nullptr);
+  if (index >= top_) {
+    top_ = index + 1;
+  }
+
+  ASSERT(top_ == shared_class_table_->top_);
+  ASSERT(capacity_ == shared_class_table_->capacity_);
+}
+
+void ClassTable::Grow(intptr_t new_capacity) {
+  ASSERT(new_capacity > capacity_);
+
+  auto new_table = static_cast<RawClass**>(
+      malloc(new_capacity * sizeof(RawClass*)));  // NOLINT
+  memmove(new_table, table_, top_ * sizeof(RawClass*));
+  memset(new_table + top_, 0, (new_capacity - top_) * sizeof(RawClass*));
+  capacity_ = new_capacity;
+  old_class_tables_->Add(table_);
+  table_ = new_table;  // TODO(koda): This should use atomics.
+}
+
+void SharedClassTable::AllocateIndex(intptr_t index) {
+  // This is called by a snapshot reader.
+  ASSERT(Class::is_valid_id(index));
+
+  if (index >= capacity_) {
+    const intptr_t new_capacity = index + kCapacityIncrement;
+    Grow(new_capacity);
+  }
+
+  ASSERT(table_[index] == 0);
   if (index >= top_) {
     top_ = index + 1;
   }
 }
 
+void SharedClassTable::Grow(intptr_t new_capacity) {
+  ASSERT(new_capacity >= capacity_);
+
+#ifndef PRODUCT
+  // Wait for any marking tasks to complete. Allocation stats in the
+  // marker rely on the class table size not changing.
+  Thread* thread = Thread::Current();
+  thread->heap()->WaitForMarkerTasks(thread);
+#endif
+
+  intptr_t* new_table = static_cast<intptr_t*>(
+      malloc(new_capacity * sizeof(intptr_t)));  // NOLINT
+  memmove(new_table, table_, top_ * sizeof(intptr_t));
+  memset(new_table + top_, 0, (new_capacity - top_) * sizeof(intptr_t));
+#ifndef PRODUCT
+  auto new_stats_table = static_cast<ClassHeapStats*>(
+      realloc(class_heap_stats_table_,
+              new_capacity * sizeof(ClassHeapStats)));  // NOLINT
+#endif
+  for (intptr_t i = capacity_; i < new_capacity; i++) {
+    new_table[i] = 0;
+    NOT_IN_PRODUCT(new_stats_table[i].Initialize());
+  }
+  capacity_ = new_capacity;
+  old_tables_->Add(table_);
+  table_ = new_table;  // TODO(koda): This should use atomics.
+  NOT_IN_PRODUCT(class_heap_stats_table_ = new_stats_table);
+}
+
 void ClassTable::Unregister(intptr_t index) {
-  table_[index] = ClassAndSize(NULL);
+  shared_class_table_->Unregister(index);
+  table_[index] = nullptr;
+}
+
+void SharedClassTable::Unregister(intptr_t index) {
+  table_[index] = 0;
 }
 
 void ClassTable::Remap(intptr_t* old_to_new_cid) {
   ASSERT(Thread::Current()->IsAtSafepoint());
-  intptr_t num_cids = NumCids();
-  ClassAndSize* cls_by_old_cid = new ClassAndSize[num_cids];
+  shared_class_table_->Remap(old_to_new_cid);
+
+  const intptr_t num_cids = NumCids();
+  auto cls_by_old_cid = new RawClass*[num_cids];
+  memmove(cls_by_old_cid, table_, sizeof(RawClass*) * num_cids);
+  for (intptr_t i = 0; i < num_cids; i++) {
+    table_[old_to_new_cid[i]] = cls_by_old_cid[i];
+  }
+  delete[] cls_by_old_cid;
+}
+
+void SharedClassTable::Remap(intptr_t* old_to_new_cid) {
+  ASSERT(Thread::Current()->IsAtSafepoint());
+  const intptr_t num_cids = NumCids();
+  intptr_t* cls_by_old_cid = new intptr_t[num_cids];
   for (intptr_t i = 0; i < num_cids; i++) {
     cls_by_old_cid[i] = table_[i];
   }
@@ -202,7 +304,7 @@
   ASSERT(visitor != NULL);
   visitor->set_gc_root_type("class table");
   for (intptr_t i = 0; i < top_; i++) {
-    visitor->VisitPointer(reinterpret_cast<RawObject**>(&(table_[i].class_)));
+    visitor->VisitPointer(reinterpret_cast<RawObject**>(&(table_[i])));
   }
   visitor->clear_gc_root_type();
 }
@@ -249,17 +351,11 @@
 }
 
 void ClassTable::SetAt(intptr_t index, RawClass* raw_cls) {
+  // This is called by snapshot reader and class finalizer.
   ASSERT(index < capacity_);
-  if (raw_cls == NULL) {
-    table_[index] = ClassAndSize(raw_cls, 0);
-  } else {
-    // Ensure we never change size for a given cid from one non-zero size to
-    // another non-zero size.
-    const intptr_t old_size = table_[index].size_;
-    const intptr_t new_size = Class::instance_size(raw_cls);
-    ASSERT(old_size == 0 || old_size == new_size);
-    table_[index] = ClassAndSize(raw_cls, new_size);
-  }
+  const intptr_t size = raw_cls == nullptr ? 0 : Class::instance_size(raw_cls);
+  shared_class_table_->SetSizeAt(index, size);
+  table_[index] = raw_cls;
 }
 
 ClassAndSize::ClassAndSize(RawClass* clazz) : class_(clazz) {
@@ -437,32 +533,32 @@
   obj->AddProperty64("bytesCurrent", bytes_current);
 }
 
-void ClassTable::UpdateAllocatedOldGC(intptr_t cid, intptr_t size) {
+void SharedClassTable::UpdateAllocatedOldGC(intptr_t cid, intptr_t size) {
   ClassHeapStats* stats = PreliminaryStatsAt(cid);
   ASSERT(stats != NULL);
   ASSERT(size != 0);
   stats->recent.AddOldGC(size);
 }
 
-void ClassTable::UpdateAllocatedExternalNew(intptr_t cid, intptr_t size) {
+void SharedClassTable::UpdateAllocatedExternalNew(intptr_t cid, intptr_t size) {
   ClassHeapStats* stats = PreliminaryStatsAt(cid);
   ASSERT(stats != NULL);
   stats->recent.AddNewExternal(size);
 }
 
-void ClassTable::UpdateAllocatedExternalOld(intptr_t cid, intptr_t size) {
+void SharedClassTable::UpdateAllocatedExternalOld(intptr_t cid, intptr_t size) {
   ClassHeapStats* stats = PreliminaryStatsAt(cid);
   ASSERT(stats != NULL);
   stats->recent.AddOldExternal(size);
 }
 
-bool ClassTable::ShouldUpdateSizeForClassId(intptr_t cid) {
+bool SharedClassTable::ShouldUpdateSizeForClassId(intptr_t cid) {
   return !RawObject::IsVariableSizeClassId(cid);
 }
 
 ClassHeapStats* ClassTable::StatsWithUpdatedSize(intptr_t cid) {
-  if (!HasValidClassAt(cid) || (cid == kFreeListElement) ||
-      (cid == kForwardingCorpse) || (cid == kSmiCid)) {
+  if (!HasValidClassAt(cid) || cid == kFreeListElement ||
+      cid == kForwardingCorpse || cid == kSmiCid) {
     return NULL;
   }
   Class& cls = Class::Handle(At(cid));
@@ -470,48 +566,53 @@
     // Not finalized.
     return NULL;
   }
+  return shared_class_table_->StatsWithUpdatedSize(cid, cls.instance_size());
+}
+
+ClassHeapStats* SharedClassTable::StatsWithUpdatedSize(intptr_t cid,
+                                                       intptr_t size) {
   ClassHeapStats* stats = PreliminaryStatsAt(cid);
   if (ShouldUpdateSizeForClassId(cid)) {
-    stats->UpdateSize(cls.instance_size());
+    stats->UpdateSize(size);
   }
   stats->Verify();
   return stats;
 }
 
-void ClassTable::ResetCountersOld() {
+void SharedClassTable::ResetCountersOld() {
   for (intptr_t i = 0; i < top_; i++) {
     class_heap_stats_table_[i].ResetAtOldGC();
   }
 }
 
-void ClassTable::ResetCountersNew() {
+void SharedClassTable::ResetCountersNew() {
   for (intptr_t i = 0; i < top_; i++) {
     class_heap_stats_table_[i].ResetAtNewGC();
   }
 }
 
-void ClassTable::UpdatePromoted() {
+void SharedClassTable::UpdatePromoted() {
   for (intptr_t i = 0; i < top_; i++) {
     class_heap_stats_table_[i].UpdatePromotedAfterNewGC();
   }
 }
 
-intptr_t ClassTable::ClassOffsetFor(intptr_t cid) {
+intptr_t SharedClassTable::ClassOffsetFor(intptr_t cid) {
   return cid * sizeof(ClassHeapStats);  // NOLINT
 }
 
-intptr_t ClassTable::NewSpaceCounterOffsetFor(intptr_t cid) {
+intptr_t SharedClassTable::NewSpaceCounterOffsetFor(intptr_t cid) {
   const intptr_t class_offset = ClassOffsetFor(cid);
   const intptr_t count_field_offset =
       ClassHeapStats::allocated_since_gc_new_space_offset();
   return class_offset + count_field_offset;
 }
 
-intptr_t ClassTable::StateOffsetFor(intptr_t cid) {
+intptr_t SharedClassTable::StateOffsetFor(intptr_t cid) {
   return ClassOffsetFor(cid) + ClassHeapStats::state_offset();
 }
 
-intptr_t ClassTable::NewSpaceSizeOffsetFor(intptr_t cid) {
+intptr_t SharedClassTable::NewSpaceSizeOffsetFor(intptr_t cid) {
   const uword class_offset = ClassOffsetFor(cid);
   const uword size_field_offset =
       ClassHeapStats::allocated_size_since_gc_new_space_offset();
@@ -563,16 +664,21 @@
   }
 }
 
-void ClassTable::ResetAllocationAccumulators() {
+void SharedClassTable::ResetAllocationAccumulators() {
   for (intptr_t i = 1; i < top_; i++) {
-    ClassHeapStats* stats = StatsWithUpdatedSize(i);
-    if (stats != NULL) {
-      stats->ResetAccumulator();
+    if (HasValidClassAt(i)) {
+      const intptr_t size = table_[i];
+      ClassHeapStats* stats = StatsWithUpdatedSize(i, size);
+      if (stats != NULL) {
+        stats->ResetAccumulator();
+      }
     }
   }
 }
 
-void ClassTable::UpdateLiveOld(intptr_t cid, intptr_t size, intptr_t count) {
+void SharedClassTable::UpdateLiveOld(intptr_t cid,
+                                     intptr_t size,
+                                     intptr_t count) {
   ClassHeapStats* stats = PreliminaryStatsAt(cid);
   ASSERT(stats != NULL);
   ASSERT(size >= 0);
@@ -580,28 +686,28 @@
   stats->post_gc.AddOld(size, count);
 }
 
-void ClassTable::UpdateLiveNew(intptr_t cid, intptr_t size) {
+void SharedClassTable::UpdateLiveNew(intptr_t cid, intptr_t size) {
   ClassHeapStats* stats = PreliminaryStatsAt(cid);
   ASSERT(stats != NULL);
   ASSERT(size >= 0);
   stats->post_gc.AddNew(size);
 }
 
-void ClassTable::UpdateLiveNewGC(intptr_t cid, intptr_t size) {
+void SharedClassTable::UpdateLiveNewGC(intptr_t cid, intptr_t size) {
   ClassHeapStats* stats = PreliminaryStatsAt(cid);
   ASSERT(stats != NULL);
   ASSERT(size >= 0);
   stats->post_gc.AddNewGC(size);
 }
 
-void ClassTable::UpdateLiveOldExternal(intptr_t cid, intptr_t size) {
+void SharedClassTable::UpdateLiveOldExternal(intptr_t cid, intptr_t size) {
   ClassHeapStats* stats = PreliminaryStatsAt(cid);
   ASSERT(stats != NULL);
   ASSERT(size >= 0);
   stats->post_gc.AddOldExternal(size);
 }
 
-void ClassTable::UpdateLiveNewExternal(intptr_t cid, intptr_t size) {
+void SharedClassTable::UpdateLiveNewExternal(intptr_t cid, intptr_t size) {
   ClassHeapStats* stats = PreliminaryStatsAt(cid);
   ASSERT(stats != NULL);
   ASSERT(size >= 0);
diff --git a/runtime/vm/class_table.h b/runtime/vm/class_table.h
index 3de2d46..19b13ce 100644
--- a/runtime/vm/class_table.h
+++ b/runtime/vm/class_table.h
@@ -7,7 +7,9 @@
 
 #include "platform/assert.h"
 #include "platform/atomic.h"
+
 #include "vm/bitfield.h"
+#include "vm/class_id.h"
 #include "vm/globals.h"
 
 namespace dart {
@@ -15,6 +17,8 @@
 class Class;
 class ClassStats;
 class ClassTable;
+class Isolate;
+class IsolateGroup;
 class JSONArray;
 class JSONObject;
 class JSONStream;
@@ -185,21 +189,180 @@
 };
 #endif  // !PRODUCT
 
+// Registry of all known classes and their sizes.
+//
+// The GC will only need the information in this shared class table to scan
+// object pointers.
+class SharedClassTable {
+ public:
+  SharedClassTable();
+  ~SharedClassTable();
+
+  // Thread-safe.
+  intptr_t SizeAt(intptr_t index) const {
+    ASSERT(IsValidIndex(index));
+    return table_[index];
+  }
+
+  bool HasValidClassAt(intptr_t index) const {
+    ASSERT(IsValidIndex(index));
+    ASSERT(table_[index] >= 0);
+    return table_[index] != 0;
+  }
+
+  void SetSizeAt(intptr_t index, intptr_t size) {
+    ASSERT(IsValidIndex(index));
+    // Ensure we never change size for a given cid from one non-zero size to
+    // another non-zero size.
+    RELEASE_ASSERT(table_[index] == 0 || table_[index] == size);
+    table_[index] = size;
+  }
+
+  bool IsValidIndex(intptr_t index) const { return index > 0 && index < top_; }
+
+  intptr_t NumCids() const { return top_; }
+  intptr_t Capacity() const { return capacity_; }
+
+  // Used to drop recently added classes.
+  void SetNumCids(intptr_t num_cids) {
+    ASSERT(num_cids <= top_);
+    top_ = num_cids;
+  }
+
+  // Called whenever a old GC occurs.
+  void ResetCountersOld();
+  // Called whenever a new GC occurs.
+  void ResetCountersNew();
+  // Called immediately after a new GC.
+  void UpdatePromoted();
+
+#if !defined(PRODUCT)
+  // Called whenever a class is allocated in the runtime.
+  void UpdateAllocatedNew(intptr_t cid, intptr_t size) {
+    ClassHeapStats* stats = PreliminaryStatsAt(cid);
+    ASSERT(stats != NULL);
+    ASSERT(size != 0);
+    stats->recent.AddNew(size);
+  }
+  void UpdateAllocatedOld(intptr_t cid, intptr_t size) {
+    ClassHeapStats* stats = PreliminaryStatsAt(cid);
+    ASSERT(stats != NULL);
+    ASSERT(size != 0);
+    stats->recent.AddOld(size);
+  }
+  void UpdateAllocatedOldGC(intptr_t cid, intptr_t size);
+  void UpdateAllocatedExternalNew(intptr_t cid, intptr_t size);
+  void UpdateAllocatedExternalOld(intptr_t cid, intptr_t size);
+
+  void ResetAllocationAccumulators();
+
+  void SetTraceAllocationFor(intptr_t cid, bool trace) {
+    ClassHeapStats* stats = PreliminaryStatsAt(cid);
+    stats->set_trace_allocation(trace);
+  }
+  bool TraceAllocationFor(intptr_t cid) {
+    ClassHeapStats* stats = PreliminaryStatsAt(cid);
+    return stats->trace_allocation();
+  }
+
+  ClassHeapStats* StatsWithUpdatedSize(intptr_t cid, intptr_t size);
+#endif  // !defined(PRODUCT)
+
+  // Returns the newly allocated cid.
+  //
+  // [index] is kIllegalCid or a predefined cid.
+  intptr_t Register(intptr_t index, intptr_t size);
+  void AllocateIndex(intptr_t index);
+  void Unregister(intptr_t index);
+
+  void Remap(intptr_t* old_to_new_cids);
+
+  void FreeOldTables();
+
+  // Used by the generated code.
+#ifndef PRODUCT
+  static intptr_t class_heap_stats_table_offset() {
+    return OFFSET_OF(SharedClassTable, class_heap_stats_table_);
+  }
+#endif
+
+  // Used by the generated code.
+  static intptr_t ClassOffsetFor(intptr_t cid);
+
+  // Used by the generated code.
+  static intptr_t NewSpaceCounterOffsetFor(intptr_t cid);
+
+  // Used by the generated code.
+  static intptr_t StateOffsetFor(intptr_t cid);
+
+  // Used by the generated code.
+  static intptr_t NewSpaceSizeOffsetFor(intptr_t cid);
+
+  static const int kInitialCapacity = 512;
+  static const int kCapacityIncrement = 256;
+
+ private:
+  friend class ClassTable;
+  friend class GCMarker;
+  friend class MarkingWeakVisitor;
+  friend class Scavenger;
+  friend class ScavengerWeakVisitor;
+  friend class ClassHeapStatsTestHelper;
+  friend class HeapTestsHelper;
+
+  static bool ShouldUpdateSizeForClassId(intptr_t cid);
+
+#ifndef PRODUCT
+  // May not have updated size for variable size classes.
+  ClassHeapStats* PreliminaryStatsAt(intptr_t cid) {
+    ASSERT(cid > 0);
+    ASSERT(cid < top_);
+    return &class_heap_stats_table_[cid];
+  }
+  void UpdateLiveOld(intptr_t cid, intptr_t size, intptr_t count = 1);
+  void UpdateLiveNew(intptr_t cid, intptr_t size);
+  void UpdateLiveNewGC(intptr_t cid, intptr_t size);
+  void UpdateLiveOldExternal(intptr_t cid, intptr_t size);
+  void UpdateLiveNewExternal(intptr_t cid, intptr_t size);
+
+  ClassHeapStats* class_heap_stats_table_ = nullptr;
+#endif  // !PRODUCT
+
+  void Grow(intptr_t new_capacity);
+
+  intptr_t top_;
+  intptr_t capacity_;
+
+  // Copy-on-write is used for table_, with old copies stored in old_tables_.
+  intptr_t* table_;  // Maps the cid to the instance size.
+  MallocGrowableArray<intptr_t*>* old_tables_;
+
+  DISALLOW_COPY_AND_ASSIGN(SharedClassTable);
+};
+
 class ClassTable {
  public:
-  ClassTable();
+  explicit ClassTable(SharedClassTable* shared_class_table_);
+
   // Creates a shallow copy of the original class table for some read-only
   // access, without support for stats data.
-  explicit ClassTable(ClassTable* original);
+  ClassTable(ClassTable* original, SharedClassTable* shared_class_table);
   ~ClassTable();
 
+  SharedClassTable* shared_class_table() const { return shared_class_table_; }
+
   void CopyBeforeHotReload(ClassAndSize** copy, intptr_t* copy_num_cids) {
     // The [IsolateReloadContext] will need to maintain a copy of the old class
     // table until instances have been morphed.
-    const intptr_t bytes = sizeof(ClassAndSize) * NumCids();
-    *copy_num_cids = NumCids();
-    *copy = static_cast<ClassAndSize*>(malloc(bytes));
-    memmove(*copy, table_, bytes);
+    const intptr_t num_cids = NumCids();
+    const intptr_t bytes = sizeof(ClassAndSize) * num_cids;
+    auto class_and_size = static_cast<ClassAndSize*>(malloc(bytes));
+    for (intptr_t i = 0; i < num_cids; ++i) {
+      class_and_size[i] =
+          ClassAndSize(table_[i], shared_class_table_->table_[i]);
+    }
+    *copy_num_cids = num_cids;
+    *copy = class_and_size;
   }
 
   void ResetBeforeHotReload() {
@@ -211,7 +374,7 @@
     // to find the super class (e.g. `cls.SuperClass` will cause us to come
     // here).
     for (intptr_t i = 0; i < top_; ++i) {
-      table_[i].size_ = 0;
+      shared_class_table_->table_[i] = 0;
     }
   }
 
@@ -222,7 +385,10 @@
     // return, so we restore size information for all classes.
     if (is_rollback) {
       SetNumCids(num_old_cids);
-      memmove(table_, old_table, num_old_cids * sizeof(ClassAndSize));
+      for (intptr_t i = 0; i < num_old_cids; ++i) {
+        shared_class_table_->table_[i] = old_table[i].size_;
+        table_[i] = old_table[i].class_;
+      }
     } else {
       CopySizesFromClassObjects();
     }
@@ -237,43 +403,37 @@
   // Thread-safe.
   RawClass* At(intptr_t index) const {
     ASSERT(IsValidIndex(index));
-    return table_[index].class_;
+    return table_[index];
   }
 
   intptr_t SizeAt(intptr_t index) const {
-    ASSERT(IsValidIndex(index));
-    return table_[index].size_;
-  }
-
-  ClassAndSize PairAt(intptr_t index) const {
-    ASSERT(IsValidIndex(index));
-    return table_[index];
+    return shared_class_table_->SizeAt(index);
   }
 
   void SetAt(intptr_t index, RawClass* raw_cls);
 
   bool IsValidIndex(intptr_t index) const {
-    return (index > 0) && (index < top_);
+    return shared_class_table_->IsValidIndex(index);
   }
 
   bool HasValidClassAt(intptr_t index) const {
     ASSERT(IsValidIndex(index));
-    return table_[index].class_ != NULL;
+    return table_[index] != nullptr;
   }
 
-  intptr_t NumCids() const { return top_; }
-  intptr_t Capacity() const { return capacity_; }
+  intptr_t NumCids() const { return shared_class_table_->NumCids(); }
+  intptr_t Capacity() const { return shared_class_table_->Capacity(); }
 
   // Used to drop recently added classes.
   void SetNumCids(intptr_t num_cids) {
+    shared_class_table_->SetNumCids(num_cids);
+
     ASSERT(num_cids <= top_);
     top_ = num_cids;
   }
 
   void Register(const Class& cls);
-
   void AllocateIndex(intptr_t index);
-
   void Unregister(intptr_t index);
 
   void Remap(intptr_t* old_to_new_cids);
@@ -293,7 +453,9 @@
   static intptr_t table_offset() { return OFFSET_OF(ClassTable, table_); }
 
   // Used by the generated code.
-  static intptr_t ClassOffsetFor(intptr_t cid);
+  static intptr_t shared_class_table_offset() {
+    return OFFSET_OF(ClassTable, shared_class_table_);
+  }
 
 #ifndef PRODUCT
   // Describes layout of heap stats for code generation. See offset_extractor.cc
@@ -304,76 +466,19 @@
   };
 #endif
 
-#if defined(ARCH_IS_32_BIT)
-  static constexpr int kSizeOfClassPairLog2 = 3;
-#else
-  static constexpr int kSizeOfClassPairLog2 = 4;
-#endif
-  static_assert(
-      (1 << kSizeOfClassPairLog2) == sizeof(ClassAndSize),
-      "Mismatch between sizeof(ClassAndSize) and kSizeOfClassPairLog2");
-
 #ifndef PRODUCT
-  // Called whenever a class is allocated in the runtime.
-  void UpdateAllocatedNew(intptr_t cid, intptr_t size) {
-    ClassHeapStats* stats = PreliminaryStatsAt(cid);
-    ASSERT(stats != NULL);
-    ASSERT(size != 0);
-    stats->recent.AddNew(size);
-  }
-  void UpdateAllocatedOld(intptr_t cid, intptr_t size) {
-    ClassHeapStats* stats = PreliminaryStatsAt(cid);
-    ASSERT(stats != NULL);
-    ASSERT(size != 0);
-    stats->recent.AddOld(size);
-  }
-  void UpdateAllocatedOldGC(intptr_t cid, intptr_t size);
-  void UpdateAllocatedExternalNew(intptr_t cid, intptr_t size);
-  void UpdateAllocatedExternalOld(intptr_t cid, intptr_t size);
-
-  // Called whenever a old GC occurs.
-  void ResetCountersOld();
-  // Called whenever a new GC occurs.
-  void ResetCountersNew();
-  // Called immediately after a new GC.
-  void UpdatePromoted();
-
-  // Used by the generated code.
-  static intptr_t class_heap_stats_table_offset() {
-    return OFFSET_OF(ClassTable, class_heap_stats_table_);
-  }
-
-  // Used by the generated code.
-  static intptr_t NewSpaceCounterOffsetFor(intptr_t cid);
-
-  // Used by the generated code.
-  static intptr_t StateOffsetFor(intptr_t cid);
-
-  // Used by the generated code.
-  static intptr_t NewSpaceSizeOffsetFor(intptr_t cid);
 
   ClassHeapStats* StatsWithUpdatedSize(intptr_t cid);
 
   void AllocationProfilePrintJSON(JSONStream* stream, bool internal);
-  void ResetAllocationAccumulators();
 
   void PrintToJSONObject(JSONObject* object);
-
-  void SetTraceAllocationFor(intptr_t cid, bool trace) {
-    ClassHeapStats* stats = PreliminaryStatsAt(cid);
-    stats->set_trace_allocation(trace);
-  }
-  bool TraceAllocationFor(intptr_t cid) {
-    ClassHeapStats* stats = PreliminaryStatsAt(cid);
-    return stats->trace_allocation();
-  }
 #endif  // !PRODUCT
 
   void AddOldTable(ClassAndSize* old_table);
   // Deallocates table copies. Do not call during concurrent access to table.
   void FreeOldTables();
 
-
  private:
   friend class GCMarker;
   friend class MarkingWeakVisitor;
@@ -381,33 +486,19 @@
   friend class ScavengerWeakVisitor;
   friend class ClassHeapStatsTestHelper;
   friend class HeapTestsHelper;
-  static const int initial_capacity_ = 512;
-  static const int capacity_increment_ = 256;
+  static const int kInitialCapacity = SharedClassTable::kInitialCapacity;
+  static const int kCapacityIncrement = SharedClassTable::kCapacityIncrement;
 
-  static bool ShouldUpdateSizeForClassId(intptr_t cid);
+  void Grow(intptr_t index);
 
   intptr_t top_;
   intptr_t capacity_;
 
   // Copy-on-write is used for table_, with old copies stored in old_tables_.
-  ClassAndSize* table_;
+  RawClass** table_;
   MallocGrowableArray<ClassAndSize*>* old_tables_;
-
-#ifndef PRODUCT
-  ClassHeapStats* class_heap_stats_table_;
-
-  // May not have updated size for variable size classes.
-  ClassHeapStats* PreliminaryStatsAt(intptr_t cid) {
-    ASSERT(cid > 0);
-    ASSERT(cid < top_);
-    return &class_heap_stats_table_[cid];
-  }
-  void UpdateLiveOld(intptr_t cid, intptr_t size, intptr_t count = 1);
-  void UpdateLiveNew(intptr_t cid, intptr_t size);
-  void UpdateLiveNewGC(intptr_t cid, intptr_t size);
-  void UpdateLiveOldExternal(intptr_t cid, intptr_t size);
-  void UpdateLiveNewExternal(intptr_t cid, intptr_t size);
-#endif  // !PRODUCT
+  MallocGrowableArray<RawClass**>* old_class_tables_;
+  SharedClassTable* shared_class_table_;
 
   DISALLOW_COPY_AND_ASSIGN(ClassTable);
 };
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 1939554..a5958d6 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -3305,6 +3305,19 @@
   }
 
   void ReadFill(Deserializer* d) {}
+
+  void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
+    const Class& mint_cls =
+        Class::Handle(zone, Isolate::Current()->object_store()->mint_class());
+    mint_cls.set_constants(Object::empty_array());
+    Object& number = Object::Handle(zone);
+    for (intptr_t i = start_index_; i < stop_index_; i++) {
+      number = refs.At(i);
+      if (number.IsMint() && number.IsCanonical()) {
+        mint_cls.InsertCanonicalMint(zone, Mint::Cast(number));
+      }
+    }
+  }
 };
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -4086,6 +4099,159 @@
 };
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
+class OneByteStringSerializationCluster : public SerializationCluster {
+ public:
+  OneByteStringSerializationCluster() : SerializationCluster("OneByteString") {}
+  ~OneByteStringSerializationCluster() {}
+
+  void Trace(Serializer* s, RawObject* object) {
+    RawOneByteString* str = reinterpret_cast<RawOneByteString*>(object);
+    objects_.Add(str);
+  }
+
+  void WriteAlloc(Serializer* s) {
+    s->WriteCid(kOneByteStringCid);
+    intptr_t count = objects_.length();
+    s->WriteUnsigned(count);
+    for (intptr_t i = 0; i < count; i++) {
+      RawOneByteString* str = objects_[i];
+      s->AssignRef(str);
+      AutoTraceObject(str);
+      intptr_t length = Smi::Value(str->ptr()->length_);
+      s->WriteUnsigned(length);
+    }
+  }
+
+  void WriteFill(Serializer* s) {
+    intptr_t count = objects_.length();
+    for (intptr_t i = 0; i < count; i++) {
+      RawOneByteString* str = objects_[i];
+      AutoTraceObject(str);
+      intptr_t length = Smi::Value(str->ptr()->length_);
+      s->WriteUnsigned(length);
+      s->Write<bool>(str->IsCanonical());
+      intptr_t hash = String::GetCachedHash(str);
+      s->Write<int32_t>(hash);
+      s->WriteBytes(str->ptr()->data(), length);
+    }
+  }
+
+ private:
+  GrowableArray<RawOneByteString*> objects_;
+};
+#endif  // !DART_PRECOMPILED_RUNTIME
+
+class OneByteStringDeserializationCluster : public DeserializationCluster {
+ public:
+  OneByteStringDeserializationCluster() {}
+  ~OneByteStringDeserializationCluster() {}
+
+  void ReadAlloc(Deserializer* d) {
+    start_index_ = d->next_index();
+    PageSpace* old_space = d->heap()->old_space();
+    intptr_t count = d->ReadUnsigned();
+    for (intptr_t i = 0; i < count; i++) {
+      intptr_t length = d->ReadUnsigned();
+      d->AssignRef(AllocateUninitialized(old_space,
+                                         OneByteString::InstanceSize(length)));
+    }
+    stop_index_ = d->next_index();
+  }
+
+  void ReadFill(Deserializer* d) {
+    for (intptr_t id = start_index_; id < stop_index_; id++) {
+      RawOneByteString* str = reinterpret_cast<RawOneByteString*>(d->Ref(id));
+      intptr_t length = d->ReadUnsigned();
+      bool is_canonical = d->Read<bool>();
+      Deserializer::InitializeHeader(str, kOneByteStringCid,
+                                     OneByteString::InstanceSize(length),
+                                     is_canonical);
+      str->ptr()->length_ = Smi::New(length);
+      String::SetCachedHash(str, d->Read<int32_t>());
+      for (intptr_t j = 0; j < length; j++) {
+        str->ptr()->data()[j] = d->Read<uint8_t>();
+      }
+    }
+  }
+};
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+class TwoByteStringSerializationCluster : public SerializationCluster {
+ public:
+  TwoByteStringSerializationCluster() : SerializationCluster("TwoByteString") {}
+  ~TwoByteStringSerializationCluster() {}
+
+  void Trace(Serializer* s, RawObject* object) {
+    RawTwoByteString* str = reinterpret_cast<RawTwoByteString*>(object);
+    objects_.Add(str);
+  }
+
+  void WriteAlloc(Serializer* s) {
+    s->WriteCid(kTwoByteStringCid);
+    intptr_t count = objects_.length();
+    s->WriteUnsigned(count);
+    for (intptr_t i = 0; i < count; i++) {
+      RawTwoByteString* str = objects_[i];
+      s->AssignRef(str);
+      AutoTraceObject(str);
+      intptr_t length = Smi::Value(str->ptr()->length_);
+      s->WriteUnsigned(length);
+    }
+  }
+
+  void WriteFill(Serializer* s) {
+    intptr_t count = objects_.length();
+    for (intptr_t i = 0; i < count; i++) {
+      RawTwoByteString* str = objects_[i];
+      AutoTraceObject(str);
+      intptr_t length = Smi::Value(str->ptr()->length_);
+      s->WriteUnsigned(length);
+      s->Write<bool>(str->IsCanonical());
+      intptr_t hash = String::GetCachedHash(str);
+      s->Write<int32_t>(hash);
+      s->WriteBytes(reinterpret_cast<uint8_t*>(str->ptr()->data()), length * 2);
+    }
+  }
+
+ private:
+  GrowableArray<RawTwoByteString*> objects_;
+};
+#endif  // !DART_PRECOMPILED_RUNTIME
+
+class TwoByteStringDeserializationCluster : public DeserializationCluster {
+ public:
+  TwoByteStringDeserializationCluster() {}
+  ~TwoByteStringDeserializationCluster() {}
+
+  void ReadAlloc(Deserializer* d) {
+    start_index_ = d->next_index();
+    PageSpace* old_space = d->heap()->old_space();
+    intptr_t count = d->ReadUnsigned();
+    for (intptr_t i = 0; i < count; i++) {
+      intptr_t length = d->ReadUnsigned();
+      d->AssignRef(AllocateUninitialized(old_space,
+                                         TwoByteString::InstanceSize(length)));
+    }
+    stop_index_ = d->next_index();
+  }
+
+  void ReadFill(Deserializer* d) {
+    for (intptr_t id = start_index_; id < stop_index_; id++) {
+      RawTwoByteString* str = reinterpret_cast<RawTwoByteString*>(d->Ref(id));
+      intptr_t length = d->ReadUnsigned();
+      bool is_canonical = d->Read<bool>();
+      Deserializer::InitializeHeader(str, kTwoByteStringCid,
+                                     TwoByteString::InstanceSize(length),
+                                     is_canonical);
+      str->ptr()->length_ = Smi::New(length);
+      String::SetCachedHash(str, d->Read<int32_t>());
+      uint8_t* cdata = reinterpret_cast<uint8_t*>(str->ptr()->data());
+      d->ReadBytes(cdata, length * 2);
+    }
+  }
+};
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
 class FakeSerializationCluster : public SerializationCluster {
  public:
   FakeSerializationCluster(const char* name, intptr_t size)
@@ -4205,10 +4371,16 @@
 
   if (Snapshot::IncludesCode(kind_)) {
     switch (cid) {
+      case kPcDescriptorsCid:
+        return new (Z) RODataSerializationCluster("(RO)PcDescriptors", cid);
       case kCodeSourceMapCid:
         return new (Z) RODataSerializationCluster("(RO)CodeSourceMap", cid);
       case kStackMapCid:
         return new (Z) RODataSerializationCluster("(RO)StackMap", cid);
+      case kOneByteStringCid:
+        return new (Z) RODataSerializationCluster("(RO)OneByteString", cid);
+      case kTwoByteStringCid:
+        return new (Z) RODataSerializationCluster("(RO)TwoByteString", cid);
     }
   }
 
@@ -4247,8 +4419,6 @@
 #endif  // !DART_PRECOMPILED_RUNTIME
     case kObjectPoolCid:
       return new (Z) ObjectPoolSerializationCluster();
-    case kPcDescriptorsCid:
-      return new (Z) RODataSerializationCluster("(RO)PcDescriptors", cid);
     case kExceptionHandlersCid:
       return new (Z) ExceptionHandlersSerializationCluster();
     case kContextCid:
@@ -4298,9 +4468,9 @@
     case kImmutableArrayCid:
       return new (Z) ArraySerializationCluster(kImmutableArrayCid);
     case kOneByteStringCid:
-      return new (Z) RODataSerializationCluster("(RO)OneByteString", cid);
+      return new (Z) OneByteStringSerializationCluster();
     case kTwoByteStringCid:
-      return new (Z) RODataSerializationCluster("(RO)TwoByteString", cid);
+      return new (Z) TwoByteStringSerializationCluster();
     default:
       break;
   }
@@ -4794,15 +4964,17 @@
       zone_(thread->zone()),
       kind_(kind),
       stream_(buffer, size),
-      image_reader_(nullptr),
-      refs_(nullptr),
+      image_reader_(NULL),
+      refs_(NULL),
       next_ref_index_(1),
-      clusters_(nullptr) {
-  ASSERT((instructions_buffer != nullptr) || !Snapshot::IncludesCode(kind));
-  ASSERT(data_buffer != nullptr);
-  image_reader_ =
-      new (zone_) ImageReader(data_buffer, instructions_buffer,
-                              shared_data_buffer, shared_instructions_buffer);
+      clusters_(NULL) {
+  if (Snapshot::IncludesCode(kind)) {
+    ASSERT(instructions_buffer != NULL);
+    ASSERT(data_buffer != NULL);
+    image_reader_ =
+        new (zone_) ImageReader(data_buffer, instructions_buffer,
+                                shared_data_buffer, shared_instructions_buffer);
+  }
   stream_.SetPosition(offset);
 }
 
@@ -4915,14 +5087,25 @@
       return new (Z) ArrayDeserializationCluster(kArrayCid);
     case kImmutableArrayCid:
       return new (Z) ArrayDeserializationCluster(kImmutableArrayCid);
-    case kOneByteStringCid:
-    case kTwoByteStringCid:
-      return new (Z) RODataDeserializationCluster();
+    case kOneByteStringCid: {
+      if (Snapshot::IncludesCode(kind_)) {
+        return new (Z) RODataDeserializationCluster();
+      } else {
+        return new (Z) OneByteStringDeserializationCluster();
+      }
+    }
+    case kTwoByteStringCid: {
+      if (Snapshot::IncludesCode(kind_)) {
+        return new (Z) RODataDeserializationCluster();
+      } else {
+        return new (Z) TwoByteStringDeserializationCluster();
+      }
+    }
     default:
       break;
   }
   FATAL1("No cluster defined for cid %" Pd, cid);
-  return nullptr;
+  return NULL;
 }
 
 RawApiError* Deserializer::VerifyImageAlignment() {
@@ -5309,8 +5492,7 @@
 intptr_t FullSnapshotWriter::WriteVMSnapshot() {
   TIMELINE_DURATION(thread(), Isolate, "WriteVMSnapshot");
 
-  ASSERT(vm_snapshot_data_buffer_ != nullptr);
-  ASSERT(vm_image_writer_ != nullptr);
+  ASSERT(vm_snapshot_data_buffer_ != NULL);
   Serializer serializer(thread(), kind_, vm_snapshot_data_buffer_, alloc_,
                         kInitialSize, vm_image_writer_, /*vm=*/true,
                         profile_writer_);
@@ -5327,12 +5509,14 @@
   serializer.FillHeader(serializer.kind());
   clustered_vm_size_ = serializer.bytes_written();
 
-  vm_image_writer_->SetProfileWriter(profile_writer_);
-  vm_image_writer_->Write(serializer.stream(), true);
-  mapped_data_size_ += vm_image_writer_->data_size();
-  mapped_text_size_ += vm_image_writer_->text_size();
-  vm_image_writer_->ResetOffsets();
-  vm_image_writer_->ClearProfileWriter();
+  if (Snapshot::IncludesCode(kind_)) {
+    vm_image_writer_->SetProfileWriter(profile_writer_);
+    vm_image_writer_->Write(serializer.stream(), true);
+    mapped_data_size_ += vm_image_writer_->data_size();
+    mapped_text_size_ += vm_image_writer_->text_size();
+    vm_image_writer_->ResetOffsets();
+    vm_image_writer_->ClearProfileWriter();
+  }
 
   // The clustered part + the direct mapped data part.
   vm_isolate_snapshot_size_ = serializer.bytes_written();
@@ -5342,13 +5526,11 @@
 void FullSnapshotWriter::WriteIsolateSnapshot(intptr_t num_base_objects) {
   TIMELINE_DURATION(thread(), Isolate, "WriteIsolateSnapshot");
 
-  ASSERT(isolate_snapshot_data_buffer_ != nullptr);
-  ASSERT(isolate_image_writer_ != nullptr);
   Serializer serializer(thread(), kind_, isolate_snapshot_data_buffer_, alloc_,
                         kInitialSize, isolate_image_writer_, /*vm=*/false,
                         profile_writer_);
   ObjectStore* object_store = isolate()->object_store();
-  ASSERT(object_store != nullptr);
+  ASSERT(object_store != NULL);
 
   serializer.ReserveHeader();
   serializer.WriteVersionAndFeatures(false);
@@ -5358,16 +5540,18 @@
   serializer.FillHeader(serializer.kind());
   clustered_isolate_size_ = serializer.bytes_written();
 
-  isolate_image_writer_->SetProfileWriter(profile_writer_);
-  isolate_image_writer_->Write(serializer.stream(), false);
+  if (Snapshot::IncludesCode(kind_)) {
+    isolate_image_writer_->SetProfileWriter(profile_writer_);
+    isolate_image_writer_->Write(serializer.stream(), false);
 #if defined(DART_PRECOMPILER)
-  isolate_image_writer_->DumpStatistics();
+    isolate_image_writer_->DumpStatistics();
 #endif
 
-  mapped_data_size_ += isolate_image_writer_->data_size();
-  mapped_text_size_ += isolate_image_writer_->text_size();
-  isolate_image_writer_->ResetOffsets();
-  isolate_image_writer_->ClearProfileWriter();
+    mapped_data_size_ += isolate_image_writer_->data_size();
+    mapped_text_size_ += isolate_image_writer_->text_size();
+    isolate_image_writer_->ResetOffsets();
+    isolate_image_writer_->ClearProfileWriter();
+  }
 
   // The clustered part + the direct mapped data part.
   isolate_snapshot_size_ = serializer.bytes_written();
@@ -5488,11 +5672,11 @@
     return api_error;
   }
 
-  ASSERT(data_image_ != nullptr);
-  thread_->isolate()->SetupImagePage(data_image_,
-                                     /* is_executable */ false);
   if (Snapshot::IncludesCode(kind_)) {
-    ASSERT(instructions_image_ != nullptr);
+    ASSERT(data_image_ != NULL);
+    thread_->isolate()->SetupImagePage(data_image_,
+                                       /* is_executable */ false);
+    ASSERT(instructions_image_ != NULL);
     thread_->isolate()->SetupImagePage(instructions_image_,
                                        /* is_executable */ true);
   }
@@ -5519,18 +5703,18 @@
     return api_error;
   }
 
-  ASSERT(data_image_ != nullptr);
-  thread_->isolate()->SetupImagePage(data_image_,
-                                     /* is_executable */ false);
   if (Snapshot::IncludesCode(kind_)) {
-    ASSERT(instructions_image_ != nullptr);
+    ASSERT(data_image_ != NULL);
+    thread_->isolate()->SetupImagePage(data_image_,
+                                       /* is_executable */ false);
+    ASSERT(instructions_image_ != NULL);
     thread_->isolate()->SetupImagePage(instructions_image_,
                                        /* is_executable */ true);
-    if (shared_data_image_ != nullptr) {
+    if (shared_data_image_ != NULL) {
       thread_->isolate()->SetupImagePage(shared_data_image_,
                                          /* is_executable */ false);
     }
-    if (shared_instructions_image_ != nullptr) {
+    if (shared_instructions_image_ != NULL) {
       thread_->isolate()->SetupImagePage(shared_instructions_image_,
                                          /* is_executable */ true);
     }
diff --git a/runtime/vm/clustered_snapshot.h b/runtime/vm/clustered_snapshot.h
index f62744a..ad04810 100644
--- a/runtime/vm/clustered_snapshot.h
+++ b/runtime/vm/clustered_snapshot.h
@@ -635,7 +635,6 @@
   ReAlloc alloc_;
   intptr_t vm_isolate_snapshot_size_;
   intptr_t isolate_snapshot_size_;
-  ForwardList* forward_list_;
   ImageWriter* vm_image_writer_;
   ImageWriter* isolate_image_writer_;
 
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm.cc b/runtime/vm/compiler/asm_intrinsifier_arm.cc
index bb2cb37..ae216fa 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm.cc
@@ -1607,7 +1607,7 @@
   __ Ret();
 
   __ Bind(&use_declaration_type);
-  __ LoadClassById(R2, R1);  // Overwrites R1.
+  __ LoadClassById(R2, R1);
   __ ldrh(R3, FieldAddress(R2, target::Class::num_type_arguments_offset()));
   __ CompareImmediate(R3, 0);
   __ b(normal_ir_body, NE);
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm64.cc b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
index 1551dfc..d96d9fc 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -1668,7 +1668,7 @@
   __ ret();
 
   __ Bind(&use_declaration_type);
-  __ LoadClassById(R2, R1);  // Overwrites R1.
+  __ LoadClassById(R2, R1);
   __ ldr(R3, FieldAddress(R2, target::Class::num_type_arguments_offset()),
          kHalfword);
   __ CompareImmediate(R3, 0);
@@ -1704,7 +1704,7 @@
   // Objects have the same class and neither is a closure.
   // Check if there are no type arguments. In this case we can return true.
   // Otherwise fall through into the runtime to handle comparison.
-  __ LoadClassById(R3, R1);  // Overwrites R1.
+  __ LoadClassById(R3, R1);
   __ ldr(R3, FieldAddress(R3, target::Class::num_type_arguments_offset()),
          kHalfword);
   __ CompareImmediate(R3, 0);
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index 0e6e40c..6958b22 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -1984,12 +1984,13 @@
 
 void Assembler::LoadClassById(Register result, Register class_id) {
   ASSERT(result != class_id);
+
+  const intptr_t table_offset = target::Isolate::class_table_offset() +
+                                target::ClassTable::table_offset();
+
   LoadIsolate(result);
-  const intptr_t offset = target::Isolate::class_table_offset() +
-                          target::ClassTable::table_offset();
-  LoadFromOffset(kWord, result, result, offset);
-  ldr(result,
-      Address(result, class_id, LSL, target::ClassTable::kSizeOfClassPairLog2));
+  LoadFromOffset(kWord, result, result, table_offset);
+  ldr(result, Address(result, class_id, LSL, target::kWordSizeLog2));
 }
 
 void Assembler::CompareClassId(Register object,
@@ -3511,10 +3512,16 @@
   ASSERT(dest != kNoRegister);
   ASSERT(dest != TMP);
   ASSERT(cid > 0);
+
+  const intptr_t shared_table_offset =
+      target::Isolate::class_table_offset() +
+      target::ClassTable::shared_class_table_offset();
+  const intptr_t table_offset =
+      target::SharedClassTable::class_heap_stats_table_offset();
   const intptr_t class_offset = target::ClassTable::ClassOffsetFor(cid);
+
   LoadIsolate(dest);
-  intptr_t table_offset = target::Isolate::class_table_offset() +
-                          target::ClassTable::class_heap_stats_table_offset();
+  ldr(dest, Address(dest, shared_table_offset));
   ldr(dest, Address(dest, table_offset));
   AddImmediate(dest, class_offset);
 }
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index 6321133..e75fcc9 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -1116,12 +1116,12 @@
 
 void Assembler::LoadClassById(Register result, Register class_id) {
   ASSERT(result != class_id);
+
+  const intptr_t table_offset = target::Isolate::class_table_offset() +
+                                target::ClassTable::table_offset();
+
   LoadIsolate(result);
-  const intptr_t offset = target::Isolate::class_table_offset() +
-                          target::ClassTable::table_offset();
-  LoadFromOffset(result, result, offset);
-  ASSERT(target::ClassTable::kSizeOfClassPairLog2 == 4);
-  add(class_id, class_id, Operand(class_id));
+  LoadFromOffset(result, result, table_offset);
   ldr(result, Address(result, class_id, UXTX, Address::Scaled));
 }
 
@@ -1553,10 +1553,16 @@
                                      Register temp_reg,
                                      Label* trace) {
   ASSERT(cid > 0);
-  intptr_t state_offset = target::ClassTable::StateOffsetFor(cid);
+
+  const intptr_t shared_table_offset =
+      target::Isolate::class_table_offset() +
+      target::ClassTable::shared_class_table_offset();
+  const intptr_t table_offset =
+      target::SharedClassTable::class_heap_stats_table_offset();
+  const intptr_t state_offset = target::ClassTable::StateOffsetFor(cid);
+
   LoadIsolate(temp_reg);
-  intptr_t table_offset = target::Isolate::class_table_offset() +
-                          target::ClassTable::class_heap_stats_table_offset();
+  ldr(temp_reg, Address(temp_reg, shared_table_offset));
   ldr(temp_reg, Address(temp_reg, table_offset));
   AddImmediate(temp_reg, state_offset);
   ldr(temp_reg, Address(temp_reg, 0));
@@ -1566,10 +1572,17 @@
 
 void Assembler::UpdateAllocationStats(intptr_t cid) {
   ASSERT(cid > 0);
-  intptr_t counter_offset = target::ClassTable::NewSpaceCounterOffsetFor(cid);
+
+  const intptr_t shared_table_offset =
+      target::Isolate::class_table_offset() +
+      target::ClassTable::shared_class_table_offset();
+  const intptr_t table_offset =
+      target::SharedClassTable::class_heap_stats_table_offset();
+  const intptr_t counter_offset =
+      target::ClassTable::NewSpaceCounterOffsetFor(cid);
+
   LoadIsolate(TMP2);
-  intptr_t table_offset = target::Isolate::class_table_offset() +
-                          target::ClassTable::class_heap_stats_table_offset();
+  ldr(TMP2, Address(TMP2, shared_table_offset));
   ldr(TMP, Address(TMP2, table_offset));
   AddImmediate(TMP2, TMP, counter_offset);
   ldr(TMP, Address(TMP2, 0));
@@ -1579,14 +1592,21 @@
 
 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, Register size_reg) {
   ASSERT(cid > 0);
+
+  const intptr_t shared_table_offset =
+      target::Isolate::class_table_offset() +
+      target::ClassTable::shared_class_table_offset();
+  const intptr_t table_offset =
+      target::SharedClassTable::class_heap_stats_table_offset();
+
   const uword class_offset = target::ClassTable::ClassOffsetFor(cid);
   const uword count_field_offset =
       target::ClassHeapStats::allocated_since_gc_new_space_offset();
   const uword size_field_offset =
       target::ClassHeapStats::allocated_size_since_gc_new_space_offset();
+
   LoadIsolate(TMP2);
-  intptr_t table_offset = target::Isolate::class_table_offset() +
-                          target::ClassTable::class_heap_stats_table_offset();
+  ldr(TMP2, Address(TMP2, shared_table_offset));
   ldr(TMP, Address(TMP2, table_offset));
   AddImmediate(TMP2, TMP, class_offset);
   ldr(TMP, Address(TMP2, count_field_offset));
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index d945c0e..315e72f 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -1526,7 +1526,6 @@
   void CompareObject(Register reg, const Object& object);
 
   void LoadClassId(Register result, Register object);
-  // Overwrites class_id register (it will be tagged afterwards).
   void LoadClassById(Register result, Register class_id);
   void CompareClassId(Register object,
                       intptr_t class_id,
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index 5834616..4943f780 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -2362,11 +2362,17 @@
                                      bool near_jump) {
   ASSERT(cid > 0);
   Address state_address(kNoRegister, 0);
-  intptr_t state_offset = target::ClassTable::StateOffsetFor(cid);
+
+  const intptr_t shared_table_offset =
+      target::Isolate::class_table_offset() +
+      target::ClassTable::shared_class_table_offset();
+  const intptr_t table_offset =
+      target::SharedClassTable::class_heap_stats_table_offset();
+  const intptr_t state_offset = target::ClassTable::StateOffsetFor(cid);
+
   ASSERT(temp_reg != kNoRegister);
   LoadIsolate(temp_reg);
-  intptr_t table_offset = target::Isolate::class_table_offset() +
-                          target::ClassTable::class_heap_stats_table_offset();
+  movl(temp_reg, Address(temp_reg, shared_table_offset));
   movl(temp_reg, Address(temp_reg, table_offset));
   state_address = Address(temp_reg, state_offset);
   testb(state_address,
@@ -2378,11 +2384,17 @@
 
 void Assembler::UpdateAllocationStats(intptr_t cid, Register temp_reg) {
   ASSERT(cid > 0);
-  intptr_t counter_offset = target::ClassTable::NewSpaceCounterOffsetFor(cid);
+  const intptr_t shared_table_offset =
+      target::Isolate::class_table_offset() +
+      target::ClassTable::shared_class_table_offset();
+  const intptr_t table_offset =
+      target::SharedClassTable::class_heap_stats_table_offset();
+  const intptr_t counter_offset =
+      target::ClassTable::NewSpaceCounterOffsetFor(cid);
+
   ASSERT(temp_reg != kNoRegister);
   LoadIsolate(temp_reg);
-  intptr_t table_offset = target::Isolate::class_table_offset() +
-                          target::ClassTable::class_heap_stats_table_offset();
+  movl(temp_reg, Address(temp_reg, shared_table_offset));
   movl(temp_reg, Address(temp_reg, table_offset));
   incl(Address(temp_reg, counter_offset));
 }
@@ -2617,12 +2629,12 @@
 
 void Assembler::LoadClassById(Register result, Register class_id) {
   ASSERT(result != class_id);
+
+  const intptr_t table_offset = target::Isolate::class_table_offset() +
+                                target::ClassTable::table_offset();
   LoadIsolate(result);
-  const intptr_t offset = target::Isolate::class_table_offset() +
-                          target::ClassTable::table_offset();
-  movl(result, Address(result, offset));
-  ASSERT(target::ClassTable::kSizeOfClassPairLog2 == 3);
-  movl(result, Address(result, class_id, TIMES_8, 0));
+  movl(result, Address(result, table_offset));
+  movl(result, Address(result, class_id, TIMES_4, 0));
 }
 
 void Assembler::CompareClassId(Register object,
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index 8bc626a..9c1cb4f 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -1851,11 +1851,16 @@
                                      Label* trace,
                                      bool near_jump) {
   ASSERT(cid > 0);
-  intptr_t state_offset = target::ClassTable::StateOffsetFor(cid);
+  const intptr_t shared_table_offset =
+      target::Isolate::class_table_offset() +
+      target::ClassTable::shared_class_table_offset();
+  const intptr_t table_offset =
+      target::SharedClassTable::class_heap_stats_table_offset();
+  const intptr_t state_offset = target::ClassTable::StateOffsetFor(cid);
+
   Register temp_reg = TMP;
   LoadIsolate(temp_reg);
-  intptr_t table_offset = target::Isolate::class_table_offset() +
-                          target::ClassTable::class_heap_stats_table_offset();
+  movq(temp_reg, Address(temp_reg, shared_table_offset));
   movq(temp_reg, Address(temp_reg, table_offset));
   testb(Address(temp_reg, state_offset),
         Immediate(target::ClassHeapStats::TraceAllocationMask()));
@@ -1866,11 +1871,17 @@
 
 void Assembler::UpdateAllocationStats(intptr_t cid) {
   ASSERT(cid > 0);
-  intptr_t counter_offset = target::ClassTable::NewSpaceCounterOffsetFor(cid);
+  const intptr_t shared_table_offset =
+      target::Isolate::class_table_offset() +
+      target::ClassTable::shared_class_table_offset();
+  const intptr_t table_offset =
+      target::SharedClassTable::class_heap_stats_table_offset();
+  const intptr_t counter_offset =
+      target::ClassTable::NewSpaceCounterOffsetFor(cid);
+
   Register temp_reg = TMP;
   LoadIsolate(temp_reg);
-  intptr_t table_offset = target::Isolate::class_table_offset() +
-                          target::ClassTable::class_heap_stats_table_offset();
+  movq(temp_reg, Address(temp_reg, shared_table_offset));
   movq(temp_reg, Address(temp_reg, table_offset));
   incq(Address(temp_reg, counter_offset));
 }
@@ -2125,14 +2136,11 @@
 
 void Assembler::LoadClassById(Register result, Register class_id) {
   ASSERT(result != class_id);
+  const intptr_t table_offset = target::Isolate::class_table_offset() +
+                                target::ClassTable::table_offset();
+
   LoadIsolate(result);
-  const intptr_t offset = target::Isolate::class_table_offset() +
-                          target::ClassTable::table_offset();
-  movq(result, Address(result, offset));
-  ASSERT(target::ClassTable::kSizeOfClassPairLog2 == 4);
-  // TIMES_16 is not a real scale factor on x64, so we double the class id
-  // and use TIMES_8.
-  addq(class_id, class_id);
+  movq(result, Address(result, table_offset));
   movq(result, Address(result, class_id, TIMES_8, 0));
 }
 
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 9e69dc8..4065bdd 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -803,8 +803,6 @@
 
   // Loading and comparing classes of objects.
   void LoadClassId(Register result, Register object);
-
-  // Overwrites class_id register (it will be tagged afterwards).
   void LoadClassById(Register result, Register class_id);
 
   void CompareClassId(Register object,
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index b49dc6e..3359f05 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -5419,6 +5419,55 @@
                                  Register out) {
   ASSERT(op_kind == Token::kMOD || op_kind == Token::kTRUNCDIV);
 
+  // Special case 64-bit div/mod by compile-time constant. Note that various
+  // special constants (such as powers of two) should have been optimized
+  // earlier in the pipeline. Div or mod by zero falls into general code
+  // to implement the exception.
+  if (FLAG_optimization_level <= 2) {
+    // We only consider magic operations under O3.
+  } else if (auto c = instruction->right()->definition()->AsConstant()) {
+    if (c->value().IsInteger()) {
+      const int64_t divisor = Integer::Cast(c->value()).AsInt64Value();
+      if (divisor <= -2 || divisor >= 2) {
+        // For x DIV c or x MOD c: use magic operations.
+        compiler::Label pos;
+        int64_t magic = 0;
+        int64_t shift = 0;
+        Utils::CalculateMagicAndShiftForDivRem(divisor, &magic, &shift);
+        // Compute tmp = high(magic * numerator).
+        __ LoadImmediate(TMP2, magic);
+        __ smulh(TMP2, TMP2, left);
+        // Compute tmp +/-= numerator.
+        if (divisor > 0 && magic < 0) {
+          __ add(TMP2, TMP2, compiler::Operand(left));
+        } else if (divisor < 0 && magic > 0) {
+          __ sub(TMP2, TMP2, compiler::Operand(left));
+        }
+        // Shift if needed.
+        if (shift != 0) {
+          __ add(TMP2, ZR, compiler::Operand(TMP2, ASR, shift));
+        }
+        // Finalize DIV or MOD.
+        if (op_kind == Token::kTRUNCDIV) {
+          __ sub(out, TMP2, compiler::Operand(TMP2, ASR, 63));
+        } else {
+          __ sub(TMP2, TMP2, compiler::Operand(TMP2, ASR, 63));
+          __ LoadImmediate(TMP, divisor);
+          __ msub(out, TMP2, TMP, left);
+          // Compensate for Dart's Euclidean view of MOD.
+          __ CompareRegisters(out, ZR);
+          if (divisor > 0) {
+            __ add(TMP2, out, compiler::Operand(TMP));
+          } else {
+            __ sub(TMP2, out, compiler::Operand(TMP));
+          }
+          __ csel(out, TMP2, out, LT);
+        }
+        return;
+      }
+    }
+  }
+
   // Prepare a slow path.
   Range* right_range = instruction->right()->definition()->range();
   Int64DivideSlowPath* slow_path = new (Z) Int64DivideSlowPath(
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 7068b74..1cfab97 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -44,8 +44,7 @@
     UNREACHABLE();
   }
 
-  B->graph_entry_ =
-      new (Z) GraphEntryInstr(*parsed_function(), Compiler::kNoOSRDeoptId);
+  B->graph_entry_ = new (Z) GraphEntryInstr(*parsed_function(), B->osr_id_);
 
   auto normal_entry = B->BuildFunctionEntry(B->graph_entry_);
   B->graph_entry_->set_normal_entry(normal_entry);
@@ -63,6 +62,9 @@
   body += Return(TokenPosition::kNoSource);
 
   PrologueInfo prologue_info(-1, -1);
+  if (B->IsCompiledForOsr()) {
+    B->graph_entry_->RelinkToOsrEntry(Z, B->last_used_block_id_ + 1);
+  }
   return new (Z) FlowGraph(*parsed_function(), B->graph_entry_,
                            B->last_used_block_id_, prologue_info);
 }
diff --git a/runtime/vm/compiler/method_recognizer.cc b/runtime/vm/compiler/method_recognizer.cc
index 9dda8a1..07f910f 100644
--- a/runtime/vm/compiler/method_recognizer.cc
+++ b/runtime/vm/compiler/method_recognizer.cc
@@ -317,10 +317,10 @@
 static struct {
   intptr_t symbol_id;
   intptr_t cid;
-  intptr_t finger_print;
+  uint32_t finger_print;
   const char* name;
 } factory_recognizer_list[] = {RECOGNIZED_LIST_FACTORY_LIST(RECOGNIZE_FACTORY){
-    Symbols::kIllegal, -1, -1, NULL}};
+    Symbols::kIllegal, -1, 0, NULL}};
 
 #undef RECOGNIZE_FACTORY
 
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h
index 27e1bb1..3af03f5 100644
--- a/runtime/vm/compiler/recognized_methods_list.h
+++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -9,337 +9,335 @@
 
 // clang-format off
 // (class-name, function-name, recognized enum, fingerprint).
-// When adding a new function add a 0 as fingerprint, build and run with
-// `tools/test.py vm/dart/reused_instructions_test` to get the correct
-// fingerprint from the mismatch error (or use Library::GetFunction() and print
-// func.SourceFingerprint()).
-// TODO(36376): Restore checking fingerprints of recognized methods.
+// When adding a new function, add a 0 as the fingerprint and run the build in
+// debug mode to get the correct fingerprint from the mismatch error.
 #define OTHER_RECOGNIZED_LIST(V)                                               \
-  V(::, identical, ObjectIdentical, 0x49c6e96a)                                \
-  V(ClassID, getID, ClassIDgetID, 0x7b18b257)                                  \
-  V(Object, Object., ObjectConstructor, 0x681617fe)                            \
-  V(List, ., ListFactory, 0x629f8324)                                          \
-  V(_List, ., ObjectArrayAllocate, 0x2121902f)                                 \
-  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 0x7041895a)                    \
-  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 0x336fa3ea)                  \
-  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 0x231bbe2e)                  \
-  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 0x0371785f)                \
-  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 0x65ab3a20)                  \
-  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 0x0cb0fcf6)                \
-  V(_TypedList, _getInt64, ByteArrayBaseGetInt64, 0x7db75d78)                  \
-  V(_TypedList, _getUint64, ByteArrayBaseGetUint64, 0x1487cfc6)                \
-  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 0x6674ea6f)              \
-  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 0x236c6e7a)              \
-  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 0x5c367ffb)          \
-  V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 0x772d1c0f)              \
-  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 0x12bae36a)                    \
-  V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 0x15821cc9)                  \
-  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 0x1f8237fa)                  \
-  V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 0x181e5d16)                \
-  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 0x7ddb9f87)                  \
-  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 0x74094f8d)                \
-  V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 0x4741396e)                  \
-  V(_TypedList, _setUint64, ByteArrayBaseSetUint64, 0x3b398ae4)                \
-  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 0x03db087b)              \
-  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 0x38a80b0d)              \
-  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 0x40052c4e)          \
-  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 0x07b89f54)              \
-  V(ByteData, ., ByteDataFactory, 0x0)                                         \
-  V(_ByteDataView, get:offsetInBytes, ByteDataViewOffsetInBytes, 0x0)          \
-  V(_ByteDataView, get:_typedData, ByteDataViewTypedData, 0x0)                 \
-  V(_TypedListView, get:offsetInBytes, TypedDataViewOffsetInBytes, 0x0)        \
-  V(_TypedListView, get:_typedData, TypedDataViewTypedData, 0x0)               \
-  V(_ByteDataView, ._, TypedData_ByteDataView_factory, 0x0)                    \
-  V(_Int8ArrayView, ._, TypedData_Int8ArrayView_factory, 0x0)                  \
-  V(_Uint8ArrayView, ._, TypedData_Uint8ArrayView_factory, 0x0)                \
-  V(_Uint8ClampedArrayView, ._, TypedData_Uint8ClampedArrayView_factory, 0x0)  \
-  V(_Int16ArrayView, ._, TypedData_Int16ArrayView_factory, 0x0)                \
-  V(_Uint16ArrayView, ._, TypedData_Uint16ArrayView_factory, 0x0)              \
-  V(_Int32ArrayView, ._, TypedData_Int32ArrayView_factory, 0x0)                \
-  V(_Uint32ArrayView, ._, TypedData_Uint32ArrayView_factory, 0x0)              \
-  V(_Int64ArrayView, ._, TypedData_Int64ArrayView_factory, 0x0)                \
-  V(_Uint64ArrayView, ._, TypedData_Uint64ArrayView_factory, 0x0)              \
-  V(_Float32ArrayView, ._, TypedData_Float32ArrayView_factory, 0x0)            \
-  V(_Float64ArrayView, ._, TypedData_Float64ArrayView_factory, 0x0)            \
-  V(_Float32x4ArrayView, ._, TypedData_Float32x4ArrayView_factory, 0x0)        \
-  V(_Int32x4ArrayView, ._, TypedData_Int32x4ArrayView_factory, 0x0)            \
-  V(_Float64x2ArrayView, ._, TypedData_Float64x2ArrayView_factory, 0x0)        \
-  V(::, _toClampedUint8, ConvertIntToClampedUint8, 0x564b0435)                 \
-  V(_StringBase, _interpolate, StringBaseInterpolate, 0x01ecb15a)              \
-  V(_IntegerImplementation, toDouble, IntegerToDouble, 0x05da96ed)             \
-  V(_Double, _add, DoubleAdd, 0x2a38277b)                                      \
-  V(_Double, _sub, DoubleSub, 0x4f466391)                                      \
-  V(_Double, _mul, DoubleMul, 0x175e4f66)                                      \
-  V(_Double, _div, DoubleDiv, 0x0854181b)                                      \
-  V(::, min, MathMin, 0x32ebc57d)                                              \
-  V(::, max, MathMax, 0x377e8889)                                              \
-  V(::, _doublePow, MathDoublePow, 0x5add0ec1)                                 \
-  V(::, _intPow, MathIntPow, 0x11b45569)                                       \
-  V(Float32x4, Float32x4., Float32x4Constructor, 0x26ea459b)                   \
-  V(Float32x4, Float32x4.zero, Float32x4Zero, 0x16eca604)                      \
-  V(Float32x4, Float32x4.splat, Float32x4Splat, 0x694e83e3)                    \
-  V(Float32x4, Float32x4.fromInt32x4Bits, Int32x4ToFloat32x4, 0x2f62ebd3)      \
-  V(Float32x4, Float32x4.fromFloat64x2, Float64x2ToFloat32x4, 0x50ed6910)      \
-  V(_Float32x4, shuffle, Float32x4Shuffle, 0x7829101f)                         \
-  V(_Float32x4, shuffleMix, Float32x4ShuffleMix, 0x4182c06b)                   \
-  V(_Float32x4, get:signMask, Float32x4GetSignMask, 0x1d08b351)                \
-  V(_Float32x4, equal, Float32x4Equal, 0x11adb239)                             \
-  V(_Float32x4, greaterThan, Float32x4GreaterThan, 0x48adaf58)                 \
-  V(_Float32x4, greaterThanOrEqual, Float32x4GreaterThanOrEqual, 0x32db94ca)   \
-  V(_Float32x4, lessThan, Float32x4LessThan, 0x425b000c)                       \
-  V(_Float32x4, lessThanOrEqual, Float32x4LessThanOrEqual, 0x0278c2f8)         \
-  V(_Float32x4, notEqual, Float32x4NotEqual, 0x2987cd26)                       \
-  V(_Float32x4, min, Float32x4Min, 0x5ed74b6f)                                 \
-  V(_Float32x4, max, Float32x4Max, 0x68696442)                                 \
-  V(_Float32x4, scale, Float32x4Scale, 0x704e4122)                             \
-  V(_Float32x4, sqrt, Float32x4Sqrt, 0x2c967a6f)                               \
-  V(_Float32x4, reciprocalSqrt, Float32x4ReciprocalSqrt, 0x6264bfe8)           \
-  V(_Float32x4, reciprocal, Float32x4Reciprocal, 0x3cd7e819)                   \
-  V(_Float32x4, unary-, Float32x4Negate, 0x37accb52)                           \
-  V(_Float32x4, abs, Float32x4Abs, 0x471cdd87)                                 \
-  V(_Float32x4, clamp, Float32x4Clamp, 0x2cb30492)                             \
-  V(_Float32x4, withX, Float32x4WithX, 0x4e336aff)                             \
-  V(_Float32x4, withY, Float32x4WithY, 0x0a72b910)                             \
-  V(_Float32x4, withZ, Float32x4WithZ, 0x31e93658)                             \
-  V(_Float32x4, withW, Float32x4WithW, 0x60ddc105)                             \
-  V(Float64x2, Float64x2., Float64x2Constructor, 0x43054b9f)                   \
-  V(Float64x2, Float64x2.zero, Float64x2Zero, 0x4af12f9d)                      \
-  V(Float64x2, Float64x2.splat, Float64x2Splat, 0x134edef0)                    \
-  V(Float64x2, Float64x2.fromFloat32x4, Float32x4ToFloat64x2, 0x17d6b5e4)      \
-  V(_Float64x2, get:x, Float64x2GetX, 0x58c09c58)                              \
-  V(_Float64x2, get:y, Float64x2GetY, 0x3cf5e5b8)                              \
-  V(_Float64x2, unary-, Float64x2Negate, 0x415ca009)                           \
-  V(_Float64x2, abs, Float64x2Abs, 0x031f9e47)                                 \
-  V(_Float64x2, sqrt, Float64x2Sqrt, 0x77f711dd)                               \
-  V(_Float64x2, get:signMask, Float64x2GetSignMask, 0x27deda4b)                \
-  V(_Float64x2, scale, Float64x2Scale, 0x26830a61)                             \
-  V(_Float64x2, withX, Float64x2WithX, 0x1d2bcaf5)                             \
-  V(_Float64x2, withY, Float64x2WithY, 0x383ed6ac)                             \
-  V(_Float64x2, min, Float64x2Min,  0x28d7ddf6)                                \
-  V(_Float64x2, max, Float64x2Max,  0x0bd74e5b)                                \
-  V(Int32x4, Int32x4., Int32x4Constructor, 0x480555a9)                         \
-  V(Int32x4, Int32x4.bool, Int32x4BoolConstructor, 0x36aa6963)                 \
-  V(Int32x4, Int32x4.fromFloat32x4Bits, Float32x4ToInt32x4, 0x6715388a)        \
-  V(_Int32x4, get:flagX, Int32x4GetFlagX, 0x56396c82)                          \
-  V(_Int32x4, get:flagY, Int32x4GetFlagY, 0x44704738)                          \
-  V(_Int32x4, get:flagZ, Int32x4GetFlagZ, 0x20d6ff37)                          \
-  V(_Int32x4, get:flagW, Int32x4GetFlagW, 0x5045616a)                          \
-  V(_Int32x4, get:signMask, Int32x4GetSignMask, 0x2c1fb2a3)                    \
-  V(_Int32x4, shuffle, Int32x4Shuffle, 0x20bc0b16)                             \
-  V(_Int32x4, shuffleMix, Int32x4ShuffleMix, 0x5c7056e1)                       \
-  V(_Int32x4, select, Int32x4Select, 0x6b49654f)                               \
-  V(_Int32x4, withFlagX, Int32x4WithFlagX, 0x0ef58fcf)                         \
-  V(_Int32x4, withFlagY, Int32x4WithFlagY, 0x6485a9c4)                         \
-  V(_Int32x4, withFlagZ, Int32x4WithFlagZ, 0x267acdfa)                         \
-  V(_Int32x4, withFlagW, Int32x4WithFlagW, 0x345ac675)                         \
-  V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 0x02477157)               \
-  V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 0x4fc8d5e0)               \
-  V(_HashVMBase, get:_data, LinkedHashMap_getData, 0x2d7a70ac)                 \
-  V(_HashVMBase, set:_data, LinkedHashMap_setData, 0x0ec032e8)                 \
-  V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 0x088599ed)         \
-  V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 0x5f42ca86)         \
-  V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 0x32f3b13b)         \
-  V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 0x7219c45b)         \
-  V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 0x558481c2)   \
-  V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 0x5aa9888d)   \
-  V(::, _classRangeCheck, ClassRangeCheck, 0x2ae76b84)                         \
-  V(::, _asyncStackTraceHelper, AsyncStackTraceHelper, 0)                      \
-  V(::, _abi, FfiAbi, 0x0)                                                     \
-  V(::, _asFunctionInternal, FfiAsFunctionInternal, 0x0)                       \
-  V(::, _nativeCallbackFunction, FfiNativeCallbackFunction, 0x0)               \
+  V(::, identical, ObjectIdentical, 0xc6e9467a)                                \
+  V(ClassID, getID, ClassIDgetID, 0xf0376ced)                                  \
+  V(Object, Object., ObjectConstructor, 0x8f3ae7ea)                            \
+  V(List, ., ListFactory, 0xd834242d)                                          \
+  V(_List, ., ObjectArrayAllocate, 0xe9c6d2be)                                 \
+  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 0xa24c2704)                    \
+  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 0xa491df3e)                  \
+  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 0xb65ae1fc)                  \
+  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 0xb4b776e5)                \
+  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 0xb460abe4)                  \
+  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 0x8c066c71)                \
+  V(_TypedList, _getInt64, ByteArrayBaseGetInt64, 0xacf2f222)                  \
+  V(_TypedList, _getUint64, ByteArrayBaseGetUint64, 0xa74b200b)                \
+  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 0xa33a9f77)              \
+  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 0x87d86b60)              \
+  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 0x3e76086e)          \
+  V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 0xfea5f17f)              \
+  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 0xd2c4e74b)                    \
+  V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 0xec62b082)                  \
+  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 0xc3566903)                  \
+  V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 0xdb50780f)                \
+  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 0xbeeeea8a)                  \
+  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 0xca02f10a)                \
+  V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 0xcf587ccf)                  \
+  V(_TypedList, _setUint64, ByteArrayBaseSetUint64, 0xe01a1df0)                \
+  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 0xb6a6294f)              \
+  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 0xce7dad17)              \
+  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 0x4b773b59)          \
+  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 0xfa2a6f88)              \
+  V(ByteData, ., ByteDataFactory, 0x0d31f187)                                  \
+  V(_ByteDataView, get:offsetInBytes, ByteDataViewOffsetInBytes, 0x0d956c6d)   \
+  V(_ByteDataView, get:_typedData, ByteDataViewTypedData, 0x28cc4efc)          \
+  V(_TypedListView, get:offsetInBytes, TypedDataViewOffsetInBytes, 0x0d956c6d) \
+  V(_TypedListView, get:_typedData, TypedDataViewTypedData, 0x28cc4efc)        \
+  V(_ByteDataView, ._, TypedData_ByteDataView_factory, 0xb839ff59)             \
+  V(_Int8ArrayView, ._, TypedData_Int8ArrayView_factory, 0x3d000a8d)           \
+  V(_Uint8ArrayView, ._, TypedData_Uint8ArrayView_factory, 0xff69de0f)         \
+  V(_Uint8ClampedArrayView, ._, TypedData_Uint8ClampedArrayView_factory,       \
+    0xdff11b9a)                                                                \
+  V(_Int16ArrayView, ._, TypedData_Int16ArrayView_factory, 0x1635c91e)         \
+  V(_Uint16ArrayView, ._, TypedData_Uint16ArrayView_factory, 0x287cbc66)       \
+  V(_Int32ArrayView, ._, TypedData_Int32ArrayView_factory, 0xf5270227)         \
+  V(_Uint32ArrayView, ._, TypedData_Uint32ArrayView_factory, 0xbb74a021)       \
+  V(_Int64ArrayView, ._, TypedData_Int64ArrayView_factory, 0xf348a583)         \
+  V(_Uint64ArrayView, ._, TypedData_Uint64ArrayView_factory, 0x10589491)       \
+  V(_Float32ArrayView, ._, TypedData_Float32ArrayView_factory, 0xbb4124b3)     \
+  V(_Float64ArrayView, ._, TypedData_Float64ArrayView_factory, 0x5f0b81e9)     \
+  V(_Float32x4ArrayView, ._, TypedData_Float32x4ArrayView_factory, 0xd8c71a39) \
+  V(_Int32x4ArrayView, ._, TypedData_Int32x4ArrayView_factory, 0x9bfbd6d5)     \
+  V(_Float64x2ArrayView, ._, TypedData_Float64x2ArrayView_factory, 0x1a383408) \
+  V(::, _toClampedUint8, ConvertIntToClampedUint8, 0x59765a4a)                 \
+  V(_StringBase, _interpolate, StringBaseInterpolate, 0xe5a934d2)              \
+  V(_IntegerImplementation, toDouble, IntegerToDouble, 0x22a26db3)             \
+  V(_Double, _add, DoubleAdd, 0x2f5c036a)                                      \
+  V(_Double, _sub, DoubleSub, 0x6d3cec71)                                      \
+  V(_Double, _mul, DoubleMul, 0x648e67af)                                      \
+  V(_Double, _div, DoubleDiv, 0x6d72d7d4)                                      \
+  V(::, min, MathMin, 0x07168bf9)                                              \
+  V(::, max, MathMax, 0xc7dbc9a0)                                              \
+  V(::, _doublePow, MathDoublePow, 0x5ae04e61)                                 \
+  V(::, _intPow, MathIntPow, 0x569ffd3f)                                       \
+  V(Float32x4, Float32x4., Float32x4Constructor, 0xdf9f0693)                   \
+  V(Float32x4, Float32x4.zero, Float32x4Zero, 0x9b875c7f)                      \
+  V(Float32x4, Float32x4.splat, Float32x4Splat, 0xf584a639)                    \
+  V(Float32x4, Float32x4.fromInt32x4Bits, Int32x4ToFloat32x4, 0x7339b2bd)      \
+  V(Float32x4, Float32x4.fromFloat64x2, Float64x2ToFloat32x4, 0x5de0e788)      \
+  V(_Float32x4, shuffle, Float32x4Shuffle, 0x5bc2446e)                         \
+  V(_Float32x4, shuffleMix, Float32x4ShuffleMix, 0x61887391)                   \
+  V(_Float32x4, get:signMask, Float32x4GetSignMask, 0x2931936f)                \
+  V(_Float32x4, equal, Float32x4Equal, 0x63e87fb9)                             \
+  V(_Float32x4, greaterThan, Float32x4GreaterThan, 0x71db0fc2)                 \
+  V(_Float32x4, greaterThanOrEqual, Float32x4GreaterThanOrEqual, 0x6dfbf3fa)   \
+  V(_Float32x4, lessThan, Float32x4LessThan, 0x69a60360)                       \
+  V(_Float32x4, lessThanOrEqual, Float32x4LessThanOrEqual, 0x6604e583)         \
+  V(_Float32x4, notEqual, Float32x4NotEqual, 0x83dcc786)                       \
+  V(_Float32x4, min, Float32x4Min, 0xf70ed6d5)                                 \
+  V(_Float32x4, max, Float32x4Max, 0xd93e58a6)                                 \
+  V(_Float32x4, scale, Float32x4Scale, 0xea28b605)                             \
+  V(_Float32x4, sqrt, Float32x4Sqrt, 0xacff17f7)                               \
+  V(_Float32x4, reciprocalSqrt, Float32x4ReciprocalSqrt, 0xa5e00f7d)           \
+  V(_Float32x4, reciprocal, Float32x4Reciprocal, 0x9c5a3fb7)                   \
+  V(_Float32x4, unary-, Float32x4Negate, 0xae8af7f1)                           \
+  V(_Float32x4, abs, Float32x4Abs, 0xb34e9b8d)                                 \
+  V(_Float32x4, clamp, Float32x4Clamp, 0xbed4ce62)                             \
+  V(_Float32x4, withX, Float32x4WithX, 0xe204ec19)                             \
+  V(_Float32x4, withY, Float32x4WithY, 0xff17a63f)                             \
+  V(_Float32x4, withZ, Float32x4WithZ, 0x0e7144f2)                             \
+  V(_Float32x4, withW, Float32x4WithW, 0x0802b80f)                             \
+  V(Float64x2, Float64x2., Float64x2Constructor, 0xb0bb0109)                   \
+  V(Float64x2, Float64x2.zero, Float64x2Zero, 0x5e70f315)                      \
+  V(Float64x2, Float64x2.splat, Float64x2Splat, 0xb86e3ccf)                    \
+  V(Float64x2, Float64x2.fromFloat32x4, Float32x4ToFloat64x2, 0x956c2161)      \
+  V(_Float64x2, get:x, Float64x2GetX, 0x00b83193)                              \
+  V(_Float64x2, get:y, Float64x2GetY, 0xee498cb6)                              \
+  V(_Float64x2, unary-, Float64x2Negate, 0x71748e87)                           \
+  V(_Float64x2, abs, Float64x2Abs, 0x76383223)                                 \
+  V(_Float64x2, sqrt, Float64x2Sqrt, 0x6fe8ae8d)                               \
+  V(_Float64x2, get:signMask, Float64x2GetSignMask, 0x2931936f)                \
+  V(_Float64x2, scale, Float64x2Scale, 0xad124c9b)                             \
+  V(_Float64x2, withX, Float64x2WithX, 0xa4ee82af)                             \
+  V(_Float64x2, withY, Float64x2WithY, 0xc2013cd5)                             \
+  V(_Float64x2, min, Float64x2Min,  0x57938495)                                \
+  V(_Float64x2, max, Float64x2Max,  0x39c30666)                                \
+  V(Int32x4, Int32x4., Int32x4Constructor, 0xa77aeafb)                         \
+  V(Int32x4, Int32x4.bool, Int32x4BoolConstructor, 0x51ae2c0c)                 \
+  V(Int32x4, Int32x4.fromFloat32x4Bits, Float32x4ToInt32x4, 0x64c906dc)        \
+  V(_Int32x4, get:flagX, Int32x4GetFlagX, 0x9f8da5bb)                          \
+  V(_Int32x4, get:flagY, Int32x4GetFlagY, 0xbafddc9b)                          \
+  V(_Int32x4, get:flagZ, Int32x4GetFlagZ, 0xc8a777ee)                          \
+  V(_Int32x4, get:flagW, Int32x4GetFlagW, 0xd1c78a2f)                          \
+  V(_Int32x4, get:signMask, Int32x4GetSignMask, 0x2931936f)                    \
+  V(_Int32x4, shuffle, Int32x4Shuffle, 0x00cff856)                             \
+  V(_Int32x4, shuffleMix, Int32x4ShuffleMix, 0x57a21961)                       \
+  V(_Int32x4, select, Int32x4Select, 0xafd1fc25)                               \
+  V(_Int32x4, withFlagX, Int32x4WithFlagX, 0x7a1fe4b5)                         \
+  V(_Int32x4, withFlagY, Int32x4WithFlagY, 0x8c658940)                         \
+  V(_Int32x4, withFlagZ, Int32x4WithFlagZ, 0x97d3a01c)                         \
+  V(_Int32x4, withFlagW, Int32x4WithFlagW, 0x80e3723b)                         \
+  V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 0x09db1d9d)               \
+  V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 0xb643fb19)               \
+  V(_HashVMBase, get:_data, LinkedHashMap_getData, 0x9a54182a)                 \
+  V(_HashVMBase, set:_data, LinkedHashMap_setData, 0x8bc58326)                 \
+  V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 0xf3cf0e2e)         \
+  V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 0x75261d2a)         \
+  V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 0xfbd541dd)         \
+  V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 0x7d2c50d9)         \
+  V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 0xfdd43ee1)   \
+  V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 0x7f2b4ddd)   \
+  V(::, _classRangeCheck, ClassRangeCheck, 0xca52e30a)                         \
+  V(::, _asyncStackTraceHelper, AsyncStackTraceHelper, 0xaeaed5cb)             \
+  V(::, _abi, FfiAbi, 0xf2e89620)                                              \
+  V(::, _asFunctionInternal, FfiAsFunctionInternal, 0x82525e9e)                \
+  V(::, _nativeCallbackFunction, FfiNativeCallbackFunction, 0x591fb33c)        \
 
 // List of intrinsics:
 // (class-name, function-name, intrinsification method, fingerprint).
 #define CORE_LIB_INTRINSIC_LIST(V)                                             \
-  V(_Smi, ~, Smi_bitNegate, 0x67299f4f)                                        \
-  V(_Smi, get:bitLength, Smi_bitLength, 0x25b3cb0a)                            \
-  V(_Smi, _bitAndFromSmi, Smi_bitAndFromSmi, 0x562d5047)                       \
-  V(_BigIntImpl, _lsh, Bigint_lsh, 0x5b6cfc8b)                                 \
-  V(_BigIntImpl, _rsh, Bigint_rsh, 0x6ff14a49)                                 \
-  V(_BigIntImpl, _absAdd, Bigint_absAdd, 0x5bf14238)                           \
-  V(_BigIntImpl, _absSub, Bigint_absSub, 0x1de5bd32)                           \
-  V(_BigIntImpl, _mulAdd, Bigint_mulAdd, 0x6f277966)                           \
-  V(_BigIntImpl, _sqrAdd, Bigint_sqrAdd, 0x68e4c8ea)                           \
+  V(_Smi, ~, Smi_bitNegate, 0x2f002cba)                                        \
+  V(_Smi, get:bitLength, Smi_bitLength, 0x277b8ace)                            \
+  V(_Smi, _bitAndFromSmi, Smi_bitAndFromSmi, 0x90b94dd3)                       \
+  V(_BigIntImpl, _lsh, Bigint_lsh, 0x776e33c7)                                 \
+  V(_BigIntImpl, _rsh, Bigint_rsh, 0x2bf277fc)                                 \
+  V(_BigIntImpl, _absAdd, Bigint_absAdd, 0x147eb8ec)                           \
+  V(_BigIntImpl, _absSub, Bigint_absSub, 0xed4c4e74)                           \
+  V(_BigIntImpl, _mulAdd, Bigint_mulAdd, 0xc8dcc37e)                           \
+  V(_BigIntImpl, _sqrAdd, Bigint_sqrAdd, 0x45be1228)                           \
   V(_BigIntImpl, _estimateQuotientDigit, Bigint_estimateQuotientDigit,         \
-    0x35456d91)                                                                \
-  V(_BigIntMontgomeryReduction, _mulMod, Montgomery_mulMod, 0x0f7b0375)        \
-  V(_Double, >, Double_greaterThan, 0x4f1375a3)                                \
-  V(_Double, >=, Double_greaterEqualThan, 0x4260c184)                          \
-  V(_Double, <, Double_lessThan, 0x365d1eba)                                   \
-  V(_Double, <=, Double_lessEqualThan, 0x74b5eb64)                             \
-  V(_Double, ==, Double_equal, 0x613492fc)                                     \
-  V(_Double, +, Double_add, 0x53994370)                                        \
-  V(_Double, -, Double_sub, 0x3b69d466)                                        \
-  V(_Double, *, Double_mul, 0x2bb9bd5d)                                        \
-  V(_Double, /, Double_div, 0x483eee28)                                        \
-  V(_Double, get:hashCode, Double_hashCode, 0x702b77b7)                        \
-  V(_Double, get:_identityHashCode, Double_identityHash, 0x7bda5549)           \
-  V(_Double, get:isNaN, Double_getIsNaN, 0x0af9d4a9)                           \
-  V(_Double, get:isInfinite, Double_getIsInfinite, 0x0f7acb47)                 \
-  V(_Double, get:isNegative, Double_getIsNegative, 0x3a59e7f4)                 \
-  V(_Double, _mulFromInteger, Double_mulFromInteger, 0x2017fcf6)               \
-  V(_Double, .fromInteger, DoubleFromInteger, 0x6d234f4b)                      \
-  V(_GrowableList, ._withData, GrowableArray_Allocate, 0x28b2138e)             \
-  V(_RegExp, _ExecuteMatch, RegExp_ExecuteMatch, 0x380184b1)                   \
-  V(_RegExp, _ExecuteMatchSticky, RegExp_ExecuteMatchSticky, 0x79b8f955)       \
-  V(Object, ==, ObjectEquals, 0x7b32a55a)                                      \
-  V(Object, get:runtimeType, ObjectRuntimeType, 0x00e8ab29)                    \
-  V(Object, _haveSameRuntimeType, ObjectHaveSameRuntimeType, 0x4dc50799)       \
-  V(_StringBase, get:hashCode, String_getHashCode, 0x78c3d446)                 \
-  V(_StringBase, get:_identityHashCode, String_identityHash, 0x0472b1d8)       \
-  V(_StringBase, get:isEmpty, StringBaseIsEmpty, 0x4a8b29c8)                   \
-  V(_StringBase, _substringMatches, StringBaseSubstringMatches, 0x46de4f10)    \
-  V(_StringBase, [], StringBaseCharAt, 0x7cbb8603)                             \
-  V(_OneByteString, get:hashCode, OneByteString_getHashCode, 0x78c3d446)       \
+    0xd7c44af1)                                                                \
+  V(_BigIntMontgomeryReduction, _mulMod, Montgomery_mulMod, 0xa1a5caf3)        \
+  V(_Double, >, Double_greaterThan, 0x682a02bc)                                \
+  V(_Double, >=, Double_greaterEqualThan, 0x2961f8ee)                          \
+  V(_Double, <, Double_lessThan, 0xcbff42e5)                                   \
+  V(_Double, <=, Double_lessEqualThan, 0xd2253d90)                             \
+  V(_Double, ==, Double_equal, 0xa7dfa02b)                                     \
+  V(_Double, +, Double_add, 0xf7d8da94)                                        \
+  V(_Double, -, Double_sub, 0xc8dda725)                                        \
+  V(_Double, *, Double_mul, 0x2dac85a2)                                        \
+  V(_Double, /, Double_div, 0x6cf1f09e)                                        \
+  V(_Double, get:hashCode, Double_hashCode, 0x22a75218)                        \
+  V(_Double, get:_identityHashCode, Double_identityHash, 0xf46be6d6)           \
+  V(_Double, get:isNaN, Double_getIsNaN, 0xb177a8f6)                           \
+  V(_Double, get:isInfinite, Double_getIsInfinite, 0xa1e96db5)                 \
+  V(_Double, get:isNegative, Double_getIsNegative, 0xb15ff274)                 \
+  V(_Double, _mulFromInteger, Double_mulFromInteger, 0xe2853768)               \
+  V(_Double, .fromInteger, DoubleFromInteger, 0x89504536)                      \
+  V(_GrowableList, ._withData, GrowableArray_Allocate, 0x55981e03)             \
+  V(_RegExp, _ExecuteMatch, RegExp_ExecuteMatch, 0xb961fc8d)                   \
+  V(_RegExp, _ExecuteMatchSticky, RegExp_ExecuteMatchSticky, 0xb22daf53)       \
+  V(Object, ==, ObjectEquals, 0x91ead0d6)                                      \
+  V(Object, get:runtimeType, ObjectRuntimeType, 0x8cdba093)                    \
+  V(Object, _haveSameRuntimeType, ObjectHaveSameRuntimeType, 0xcee5d65a)       \
+  V(_StringBase, get:hashCode, String_getHashCode, 0x22a75237)                 \
+  V(_StringBase, get:_identityHashCode, String_identityHash, 0xf46be6f5)       \
+  V(_StringBase, get:isEmpty, StringBaseIsEmpty, 0xd7218394)                   \
+  V(_StringBase, _substringMatches, StringBaseSubstringMatches, 0x46fc3731)    \
+  V(_StringBase, [], StringBaseCharAt, 0xe67164fe)                             \
+  V(_OneByteString, get:hashCode, OneByteString_getHashCode, 0x22a75237)       \
   V(_OneByteString, _substringUncheckedNative,                                 \
-    OneByteString_substringUnchecked,  0x3538ad86)                             \
-  V(_OneByteString, _setAt, OneByteStringSetAt, 0x11ffddd1)                    \
-  V(_OneByteString, _allocate, OneByteString_allocate,          0x74933376)    \
-  V(_OneByteString, ==, OneByteString_equality, 0x4eda197e)                    \
-  V(_TwoByteString, ==, TwoByteString_equality, 0x4eda197e)                    \
-  V(_Type, get:hashCode, Type_getHashCode, 0x18d1523f)                         \
-  V(::, _getHash, Object_getHash, 0x2827856d)                                  \
-  V(::, _setHash, Object_setHash, 0x690faebd)                                  \
+    OneByteString_substringUnchecked,  0x94c41563)                             \
+  V(_OneByteString, _setAt, OneByteStringSetAt, 0xc6c7e75d)                    \
+  V(_OneByteString, _allocate, OneByteString_allocate,          0xbe472ce0)    \
+  V(_OneByteString, ==, OneByteString_equality, 0xe1ea0c11)                    \
+  V(_TwoByteString, ==, TwoByteString_equality, 0xe1ea0c11)                    \
+  V(_Type, get:hashCode, Type_getHashCode, 0x22a75237)                         \
+  V(::, _getHash, Object_getHash, 0xb05aa13f)                                  \
+  V(::, _setHash, Object_setHash, 0xcb404dd2)                                  \
 
 
 #define CORE_INTEGER_LIB_INTRINSIC_LIST(V)                                     \
   V(_IntegerImplementation, _addFromInteger, Integer_addFromInteger,           \
-    0x6a10c54a)                                                                \
-  V(_IntegerImplementation, +, Integer_add, 0x43d53af7)                        \
+    0xc7bd74ae)                                                                \
+  V(_IntegerImplementation, +, Integer_add, 0x49774600)                        \
   V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger,           \
-    0x3fa4b1ed)                                                                \
-  V(_IntegerImplementation, -, Integer_sub, 0x2dc22e03)                        \
+    0x8e0de2a2)                                                                \
+  V(_IntegerImplementation, -, Integer_sub, 0x1a853bf1)                        \
   V(_IntegerImplementation, _mulFromInteger, Integer_mulFromInteger,           \
-    0x3216e299)                                                                \
-  V(_IntegerImplementation, *, Integer_mul, 0x4e7a1c24)                        \
+    0x95751a41)                                                                \
+  V(_IntegerImplementation, *, Integer_mul, 0xefe7fbce)                        \
   V(_IntegerImplementation, _moduloFromInteger, Integer_moduloFromInteger,     \
-     0x6348b974)                                                               \
-  V(_IntegerImplementation, ~/, Integer_truncDivide, 0x4efb2d39)               \
-  V(_IntegerImplementation, unary-, Integer_negate, 0x428bf6fa)                \
+    0xbc75fece)                                                                \
+  V(_IntegerImplementation, ~/, Integer_truncDivide, 0xfb066107)               \
+  V(_IntegerImplementation, unary-, Integer_negate, 0xdb5f0d70)                \
   V(_IntegerImplementation, _bitAndFromInteger, Integer_bitAndFromInteger,     \
-    0x395b1678)                                                                \
-  V(_IntegerImplementation, &, Integer_bitAnd, 0x5ab35f30)                     \
+    0xb7e724d2)                                                                \
+  V(_IntegerImplementation, &, Integer_bitAnd, 0xd9888ca4)                     \
   V(_IntegerImplementation, _bitOrFromInteger, Integer_bitOrFromInteger,       \
-    0x6a36b395)                                                                \
-  V(_IntegerImplementation, |, Integer_bitOr, 0x267fa107)                      \
+    0xa97501aa)                                                                \
+  V(_IntegerImplementation, |, Integer_bitOr, 0xc82cc85c)                      \
   V(_IntegerImplementation, _bitXorFromInteger, Integer_bitXorFromInteger,     \
-    0x72da93f0)                                                                \
-  V(_IntegerImplementation, ^, Integer_bitXor, 0x0c7b0230)                     \
+    0x9ab4d16e)                                                                \
+  V(_IntegerImplementation, ^, Integer_bitXor, 0xc1ed9463)                     \
   V(_IntegerImplementation, _greaterThanFromInteger,                           \
-    Integer_greaterThanFromInt, 0x4a50ed58)                                    \
-  V(_IntegerImplementation, >, Integer_greaterThan, 0x6599a6e1)                \
-  V(_IntegerImplementation, ==, Integer_equal, 0x58abc487)                     \
+    Integer_greaterThanFromInt, 0x3366ff66)                                    \
+  V(_IntegerImplementation, >, Integer_greaterThan, 0xe74b678c)                \
+  V(_IntegerImplementation, ==, Integer_equal, 0xb6faea0e)                     \
   V(_IntegerImplementation, _equalToInteger, Integer_equalToInteger,           \
-    0x063be842)                                                                \
-  V(_IntegerImplementation, <, Integer_lessThan, 0x365d1eba)                   \
-  V(_IntegerImplementation, <=, Integer_lessEqualThan, 0x74b5eb64)             \
-  V(_IntegerImplementation, >=, Integer_greaterEqualThan, 0x4260c184)          \
-  V(_IntegerImplementation, <<, Integer_shl, 0x371c45fa)                       \
-  V(_IntegerImplementation, >>, Integer_sar, 0x2b630578)                       \
-  V(_Double, toInt, DoubleToInteger, 0x26ef344b)                               \
+    0x39d3cd05)                                                                \
+  V(_IntegerImplementation, <, Integer_lessThan, 0xcbff42e5)                   \
+  V(_IntegerImplementation, <=, Integer_lessEqualThan, 0xd2253d90)             \
+  V(_IntegerImplementation, >=, Integer_greaterEqualThan, 0x2961f8ee)          \
+  V(_IntegerImplementation, <<, Integer_shl, 0x972a7fd6)                       \
+  V(_IntegerImplementation, >>, Integer_sar, 0xfe022e7b)                       \
+  V(_Double, toInt, DoubleToInteger, 0x14433ded)                               \
 
 #define MATH_LIB_INTRINSIC_LIST(V)                                             \
-  V(::, sqrt, MathSqrt, 0x70482cf3)                                            \
-  V(_Random, _nextState, Random_nextState, 0x2842c4d5)                         \
+  V(::, sqrt, MathSqrt, 0x2c20a879)                                            \
+  V(_Random, _nextState, Random_nextState, 0x30682e3d)                         \
 
 #define GRAPH_MATH_LIB_INTRINSIC_LIST(V)                                       \
-  V(::, sin, MathSin, 0x6b7bd98c)                                              \
-  V(::, cos, MathCos, 0x459bf5fe)                                              \
-  V(::, tan, MathTan, 0x3bcd772a)                                              \
-  V(::, asin, MathAsin, 0x2ecc2fcd)                                            \
-  V(::, acos, MathAcos, 0x08cf2212)                                            \
-  V(::, atan, MathAtan, 0x1e2731d5)                                            \
-  V(::, atan2, MathAtan2, 0x39f1fa41)                                          \
+  V(::, sin, MathSin, 0x18e743c0)                                              \
+  V(::, cos, MathCos, 0x6623c0ce)                                              \
+  V(::, tan, MathTan, 0x3584ee62)                                              \
+  V(::, asin, MathAsin, 0xb023f0df)                                            \
+  V(::, acos, MathAcos, 0x165661fa)                                            \
+  V(::, atan, MathAtan, 0xc91eca17)                                            \
+  V(::, atan2, MathAtan2, 0x79b3a5e6)                                          \
 
 #define TYPED_DATA_LIB_INTRINSIC_LIST(V)                                       \
-  V(Int8List, ., TypedData_Int8Array_factory, 0x7e39a3a1)                      \
-  V(Uint8List, ., TypedData_Uint8Array_factory, 0x3a79adf7)                    \
-  V(Uint8ClampedList, ., TypedData_Uint8ClampedArray_factory, 0x67f38395)      \
-  V(Int16List, ., TypedData_Int16Array_factory, 0x6477bda8)                    \
-  V(Uint16List, ., TypedData_Uint16Array_factory, 0x5707c5a2)                  \
-  V(Int32List, ., TypedData_Int32Array_factory, 0x2b96ec0e)                    \
-  V(Uint32List, ., TypedData_Uint32Array_factory, 0x0c1c0d62)                  \
-  V(Int64List, ., TypedData_Int64Array_factory, 0x279ab485)                    \
-  V(Uint64List, ., TypedData_Uint64Array_factory, 0x7bcb89c2)                  \
-  V(Float32List, ., TypedData_Float32Array_factory, 0x43506c09)                \
-  V(Float64List, ., TypedData_Float64Array_factory, 0x1fde3eaf)                \
-  V(Float32x4List, ., TypedData_Float32x4Array_factory, 0x4a4030d6)            \
-  V(Int32x4List, ., TypedData_Int32x4Array_factory, 0x6dd02406)                \
-  V(Float64x2List, ., TypedData_Float64x2Array_factory, 0x688e4e97)            \
+  V(Int8List, ., TypedData_Int8Array_factory, 0x6ce2f102)                      \
+  V(Uint8List, ., TypedData_Uint8Array_factory, 0x1163d489)                    \
+  V(Uint8ClampedList, ., TypedData_Uint8ClampedArray_factory, 0x0b0e9f0f)      \
+  V(Int16List, ., TypedData_Int16Array_factory, 0x6addd02d)                    \
+  V(Uint16List, ., TypedData_Uint16Array_factory, 0x139a6464)                  \
+  V(Int32List, ., TypedData_Int32Array_factory, 0x40dad19a)                    \
+  V(Uint32List, ., TypedData_Uint32Array_factory, 0x988357c5)                  \
+  V(Int64List, ., TypedData_Int64Array_factory, 0xef0a3469)                    \
+  V(Uint64List, ., TypedData_Uint64Array_factory, 0xf49c0472)                  \
+  V(Float32List, ., TypedData_Float32Array_factory, 0x779b26f8)                \
+  V(Float64List, ., TypedData_Float64Array_factory, 0xf623554b)                \
+  V(Float32x4List, ., TypedData_Float32x4Array_factory, 0x9edf5402)            \
+  V(Int32x4List, ., TypedData_Int32x4Array_factory, 0x915e8e68)                \
+  V(Float64x2List, ., TypedData_Float64x2Array_factory, 0x0d206864)            \
 
 #define GRAPH_TYPED_DATA_INTRINSICS_LIST(V)                                    \
-  V(_Int8List, [], Int8ArrayGetIndexed, 0x49767a2c)                            \
-  V(_Int8List, []=, Int8ArraySetIndexed, 0x24f42cd0)                           \
-  V(_Uint8List, [], Uint8ArrayGetIndexed, 0x088d86d4)                          \
-  V(_Uint8List, []=, Uint8ArraySetIndexed, 0x12639541)                         \
-  V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, 0x088d86d4)         \
-  V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, 0x12639541)        \
-  V(_Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, 0x088d86d4)            \
-  V(_Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, 0x6790dba1)           \
+  V(_Int8List, [], Int8ArrayGetIndexed, 0xdab47d5d)                            \
+  V(_Int8List, []=, Int8ArraySetIndexed, 0x09ba0f32)                           \
+  V(_Uint8List, [], Uint8ArrayGetIndexed, 0xa9468b1d)                          \
+  V(_Uint8List, []=, Uint8ArraySetIndexed, 0xa6fd9dce)                         \
+  V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, 0xa9468b1d)         \
+  V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, 0xa6fd9dce)        \
+  V(_Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, 0xa9468b1d)            \
+  V(_Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, 0x7d60b42e)           \
   V(_ExternalUint8ClampedArray, [], ExternalUint8ClampedArrayGetIndexed,       \
-    0x088d86d4)                                                                \
+    0xa9468b1d)                                                                \
   V(_ExternalUint8ClampedArray, []=, ExternalUint8ClampedArraySetIndexed,      \
-    0x6790dba1)                                                                \
-  V(_Int16List, [], Int16ArrayGetIndexed, 0x5ec64948)                          \
-  V(_Int16List, []=, Int16ArraySetIndexed, 0x0e4e8221)                         \
-  V(_Uint16List, [], Uint16ArrayGetIndexed, 0x5f49d093)                        \
-  V(_Uint16List, []=, Uint16ArraySetIndexed, 0x2efbc90f)                       \
-  V(_Int32List, [], Int32ArrayGetIndexed, 0x4bc0d3dd)                          \
-  V(_Int32List, []=, Int32ArraySetIndexed, 0x1adf9823)                         \
-  V(_Uint32List, [], Uint32ArrayGetIndexed, 0x188658ce)                        \
-  V(_Uint32List, []=, Uint32ArraySetIndexed, 0x01f51a79)                       \
-  V(_Int64List, [], Int64ArrayGetIndexed, 0x51eafb97)                          \
-  V(_Int64List, []=, Int64ArraySetIndexed, 0x376181fb)                         \
-  V(_Uint64List, [], Uint64ArrayGetIndexed, 0x4b2a1ba2)                        \
-  V(_Uint64List, []=, Uint64ArraySetIndexed, 0x5f881bd4)                       \
-  V(_Float64List, [], Float64ArrayGetIndexed, 0x0a714486)                      \
-  V(_Float64List, []=, Float64ArraySetIndexed, 0x04937367)                     \
-  V(_Float32List, [], Float32ArrayGetIndexed, 0x5ade301f)                      \
-  V(_Float32List, []=, Float32ArraySetIndexed, 0x0d5c2e2b)                     \
-  V(_Float32x4List, [], Float32x4ArrayGetIndexed, 0x128cddeb)                  \
-  V(_Float32x4List, []=, Float32x4ArraySetIndexed, 0x7ad55c72)                 \
-  V(_Int32x4List, [], Int32x4ArrayGetIndexed, 0x4b78af9c)                      \
-  V(_Int32x4List, []=, Int32x4ArraySetIndexed, 0x31453dab)                     \
-  V(_Float64x2List, [], Float64x2ArrayGetIndexed, 0x644a0be1)                  \
-  V(_Float64x2List, []=, Float64x2ArraySetIndexed, 0x6b836b0b)                 \
-  V(_TypedList, get:length, TypedListLength, 0x0)                \
-  V(_TypedListView, get:length, TypedListViewLength, 0x0)        \
-  V(_ByteDataView, get:length, ByteDataViewLength, 0x0)          \
-  V(_Float32x4, get:x, Float32x4ShuffleX, 0x63d1a9fd)                          \
-  V(_Float32x4, get:y, Float32x4ShuffleY, 0x203523d9)                          \
-  V(_Float32x4, get:z, Float32x4ShuffleZ, 0x13190678)                          \
-  V(_Float32x4, get:w, Float32x4ShuffleW, 0x698a38de)                          \
-  V(_Float32x4, *, Float32x4Mul, 0x5dec68b2)                                   \
-  V(_Float32x4, -, Float32x4Sub, 0x3ea14461)                                   \
-  V(_Float32x4, +, Float32x4Add, 0x7ffcf301)                                   \
+    0x7d60b42e)                                                                \
+  V(_Int16List, [], Int16ArrayGetIndexed, 0x2b783e9d)                          \
+  V(_Int16List, []=, Int16ArraySetIndexed, 0x894edd67)                         \
+  V(_Uint16List, [], Uint16ArrayGetIndexed, 0x3d599bdd)                        \
+  V(_Uint16List, []=, Uint16ArraySetIndexed, 0x146065d0)                       \
+  V(_Int32List, [], Int32ArrayGetIndexed, 0x645ac57e)                          \
+  V(_Int32List, []=, Int32ArraySetIndexed, 0x58343408)                         \
+  V(_Uint32List, [], Uint32ArrayGetIndexed, 0xe6f6183e)                        \
+  V(_Uint32List, []=, Uint32ArraySetIndexed, 0x7ee99568)                       \
+  V(_Int64List, [], Int64ArrayGetIndexed, 0x57d917de)                          \
+  V(_Int64List, []=, Int64ArraySetIndexed, 0x94485c32)                         \
+  V(_Uint64List, [], Uint64ArrayGetIndexed, 0x7fb017de)                        \
+  V(_Uint64List, []=, Uint64ArraySetIndexed, 0x1c695796)                       \
+  V(_Float64List, [], Float64ArrayGetIndexed, 0x9e20a2c3)                      \
+  V(_Float64List, []=, Float64ArraySetIndexed, 0xcd01ec0c)                     \
+  V(_Float32List, [], Float32ArrayGetIndexed, 0x7c01bb83)                      \
+  V(_Float32List, []=, Float32ArraySetIndexed, 0xcb87f800)                     \
+  V(_Float32x4List, [], Float32x4ArrayGetIndexed, 0x5a2a83fc)                  \
+  V(_Float32x4List, []=, Float32x4ArraySetIndexed, 0x5ae5c9f3)                 \
+  V(_Int32x4List, [], Int32x4ArrayGetIndexed, 0x05ef16d4)                      \
+  V(_Int32x4List, []=, Int32x4ArraySetIndexed, 0x2e8437b1)                     \
+  V(_Float64x2List, [], Float64x2ArrayGetIndexed, 0xe7fbf246)                  \
+  V(_Float64x2List, []=, Float64x2ArraySetIndexed, 0xce826d19)                 \
+  V(_TypedList, get:length, TypedListLength, 0x05176aac)                       \
+  V(_TypedListView, get:length, TypedListViewLength, 0x05176aac)               \
+  V(_ByteDataView, get:length, ByteDataViewLength, 0x05176aac)                 \
+  V(_Float32x4, get:x, Float32x4ShuffleX, 0x00b83193)                          \
+  V(_Float32x4, get:y, Float32x4ShuffleY, 0xee498cb6)                          \
+  V(_Float32x4, get:z, Float32x4ShuffleZ, 0x2414f84c)                          \
+  V(_Float32x4, get:w, Float32x4ShuffleW, 0x06553cce)                          \
+  V(_Float32x4, *, Float32x4Mul, 0xf817cb64)                                   \
+  V(_Float32x4, -, Float32x4Sub, 0xeff9bb27)                                   \
+  V(_Float32x4, +, Float32x4Add, 0xcac0f0b6)                                   \
 
 #define GRAPH_CORE_INTRINSICS_LIST(V)                                          \
-  V(_List, get:length, ObjectArrayLength, 0x25952390)                          \
-  V(_List, [], ObjectArrayGetIndexed, 0x653da02e)                              \
-  V(_List, []=, ObjectArraySetIndexed, 0x16b3d2b0)                             \
-  V(_List, _setIndexed, ObjectArraySetIndexedUnchecked, 0x50d64c75)            \
-  V(_ImmutableList, get:length, ImmutableArrayLength, 0x25952390)              \
-  V(_ImmutableList, [], ImmutableArrayGetIndexed, 0x653da02e)                  \
-  V(_GrowableList, get:length, GrowableArrayLength, 0x18dd86b4)                \
-  V(_GrowableList, get:_capacity, GrowableArrayCapacity, 0x2e04be60)           \
-  V(_GrowableList, _setData, GrowableArraySetData, 0x3dbea348)                 \
-  V(_GrowableList, _setLength, GrowableArraySetLength, 0x753e55da)             \
-  V(_GrowableList, [], GrowableArrayGetIndexed, 0x446fe1f0)                    \
-  V(_GrowableList, []=, GrowableArraySetIndexed, 0x40a462ec)                   \
-  V(_GrowableList, _setIndexed, GrowableArraySetIndexedUnchecked, 0x297083df)  \
-  V(_StringBase, get:length, StringBaseLength, 0x2a2d03d1)                     \
-  V(_OneByteString, codeUnitAt, OneByteStringCodeUnitAt, 0x55a0a1f3)           \
-  V(_TwoByteString, codeUnitAt, TwoByteStringCodeUnitAt, 0x55a0a1f3)           \
+  V(_List, get:length, ObjectArrayLength, 0x05176aac)                          \
+  V(_List, [], ObjectArrayGetIndexed, 0x7e13418e)                              \
+  V(_List, []=, ObjectArraySetIndexed, 0x4d5e74cf)                             \
+  V(_List, _setIndexed, ObjectArraySetIndexedUnchecked, 0x91b2c203)            \
+  V(_ImmutableList, get:length, ImmutableArrayLength, 0x05176aac)              \
+  V(_ImmutableList, [], ImmutableArrayGetIndexed, 0x7e13418e)                  \
+  V(_GrowableList, get:length, GrowableArrayLength, 0x05176aac)                \
+  V(_GrowableList, get:_capacity, GrowableArrayCapacity, 0x2a661633)           \
+  V(_GrowableList, _setData, GrowableArraySetData, 0x9e2350fe)                 \
+  V(_GrowableList, _setLength, GrowableArraySetLength, 0x8d94d91d)             \
+  V(_GrowableList, [], GrowableArrayGetIndexed, 0x7e13418e)                    \
+  V(_GrowableList, []=, GrowableArraySetIndexed, 0x4d5e74cf)                   \
+  V(_GrowableList, _setIndexed, GrowableArraySetIndexedUnchecked, 0x91b2c203)  \
+  V(_StringBase, get:length, StringBaseLength, 0x05176aac)                     \
+  V(_OneByteString, codeUnitAt, OneByteStringCodeUnitAt, 0xb0959953)           \
+  V(_TwoByteString, codeUnitAt, TwoByteStringCodeUnitAt, 0xb0959953)           \
   V(_ExternalOneByteString, codeUnitAt, ExternalOneByteStringCodeUnitAt,       \
-    0x55a0a1f3)                                                                \
+    0xb0959953)                                                                \
   V(_ExternalTwoByteString, codeUnitAt, ExternalTwoByteStringCodeUnitAt,       \
-    0x55a0a1f3)                                                                \
-  V(_Double, unary-, DoubleFlipSignBit, 0x6db4674f)                            \
-  V(_Double, truncateToDouble, DoubleTruncate, 0x2f27e5d3)                     \
-  V(_Double, roundToDouble, DoubleRound, 0x2f89c512)                           \
-  V(_Double, floorToDouble, DoubleFloor, 0x6aa87a5f)                           \
-  V(_Double, ceilToDouble, DoubleCeil, 0x1b045e9e)                             \
-  V(_Double, _modulo, DoubleMod, 0x5b8ceed7)
+    0xb0959953)                                                                \
+  V(_Double, unary-, DoubleFlipSignBit, 0x039c6e4a)                            \
+  V(_Double, truncateToDouble, DoubleTruncate, 0x2960d21d)                     \
+  V(_Double, roundToDouble, DoubleRound, 0x1cd615c4)                           \
+  V(_Double, floorToDouble, DoubleFloor, 0x1b41170c)                           \
+  V(_Double, ceilToDouble, DoubleCeil, 0x25a81a9d)                             \
+  V(_Double, _modulo, DoubleMod, 0x42a93471)
 
 
 #define GRAPH_INTRINSICS_LIST(V)                                               \
@@ -348,14 +346,14 @@
   GRAPH_MATH_LIB_INTRINSIC_LIST(V)                                             \
 
 #define DEVELOPER_LIB_INTRINSIC_LIST(V)                                        \
-  V(_UserTag, makeCurrent, UserTag_makeCurrent, 0x0b3066fd)                    \
-  V(::, _getDefaultTag, UserTag_defaultTag, 0x69f3f1ad)                        \
-  V(::, _getCurrentTag, Profiler_getCurrentTag, 0x05fa99d2)                    \
-  V(::, _isDartStreamEnabled, Timeline_isDartStreamEnabled, 0x72f13f7a)        \
+  V(_UserTag, makeCurrent, UserTag_makeCurrent, 0x472d1eb5)                    \
+  V(::, _getDefaultTag, UserTag_defaultTag, 0x5c124271)                        \
+  V(::, _getCurrentTag, Profiler_getCurrentTag, 0x5d6d8a14)                    \
+  V(::, _isDartStreamEnabled, Timeline_isDartStreamEnabled, 0xcf6f3099)        \
 
 #define ASYNC_LIB_INTRINSIC_LIST(V)                                            \
-  V(::, _clearAsyncThreadStackTrace, ClearAsyncThreadStackTrace, 0x2edd4b25)   \
-  V(::, _setAsyncThreadStackTrace, SetAsyncThreadStackTrace, 0x04f429a7)       \
+  V(::, _clearAsyncThreadStackTrace, ClearAsyncThreadStackTrace, 0x341efd8e)   \
+  V(::, _setAsyncThreadStackTrace, SetAsyncThreadStackTrace, 0x5f29f453)       \
 
 #define ALL_INTRINSICS_NO_INTEGER_LIB_LIST(V)                                  \
   ASYNC_LIB_INTRINSIC_LIST(V)                                                  \
@@ -375,58 +373,58 @@
 
 // A list of core functions that internally dispatch based on received id.
 #define POLYMORPHIC_TARGET_LIST(V)                                             \
-  V(_StringBase, [], StringBaseCharAt, 0x7cbb8603)                             \
-  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 0x7041895a)                    \
-  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 0x336fa3ea)                  \
-  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 0x231bbe2e)                  \
-  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 0x0371785f)                \
-  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 0x65ab3a20)                  \
-  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 0x0cb0fcf6)                \
-  V(_TypedList, _getInt64, ByteArrayBaseGetInt64, 0x7db75d78)                  \
-  V(_TypedList, _getUint64, ByteArrayBaseGetUint64, 0x1487cfc6)                \
-  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 0x6674ea6f)              \
-  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 0x236c6e7a)              \
-  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 0x5c367ffb)          \
-  V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 0x772d1c0f)              \
-  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 0x12bae36a)                    \
-  V(_TypedList, _setUint8, ByteArrayBaseSetInt8, 0x15821cc9)                   \
-  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 0x1f8237fa)                  \
-  V(_TypedList, _setUint16, ByteArrayBaseSetInt16, 0x181e5d16)                 \
-  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 0x7ddb9f87)                  \
-  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 0x74094f8d)                \
-  V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 0x4741396e)                  \
-  V(_TypedList, _setUint64, ByteArrayBaseSetUint64, 0x3b398ae4)                \
-  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 0x03db087b)              \
-  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 0x38a80b0d)              \
-  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 0x40052c4e)          \
-  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 0x07b89f54)              \
-  V(Object, get:runtimeType, ObjectRuntimeType, 0x00e8ab29)
+  V(_StringBase, [], StringBaseCharAt, 0xe67164fe)                             \
+  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 0xa24c2704)                    \
+  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 0xa491df3e)                  \
+  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 0xb65ae1fc)                  \
+  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 0xb4b776e5)                \
+  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 0xb460abe4)                  \
+  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 0x8c066c71)                \
+  V(_TypedList, _getInt64, ByteArrayBaseGetInt64, 0xacf2f222)                  \
+  V(_TypedList, _getUint64, ByteArrayBaseGetUint64, 0xa74b200b)                \
+  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 0xa33a9f77)              \
+  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 0x87d86b60)              \
+  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 0x3e76086e)          \
+  V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 0xfea5f17f)              \
+  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 0xd2c4e74b)                    \
+  V(_TypedList, _setUint8, ByteArrayBaseSetInt8, 0xec62b082)                   \
+  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 0xc3566903)                  \
+  V(_TypedList, _setUint16, ByteArrayBaseSetInt16, 0xdb50780f)                 \
+  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 0xbeeeea8a)                  \
+  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 0xca02f10a)                \
+  V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 0xcf587ccf)                  \
+  V(_TypedList, _setUint64, ByteArrayBaseSetUint64, 0xe01a1df0)                \
+  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 0xb6a6294f)              \
+  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 0xce7dad17)              \
+  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 0x4b773b59)          \
+  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 0xfa2a6f88)              \
+  V(Object, get:runtimeType, ObjectRuntimeType, 0x8cdba093)
 
 // List of recognized list factories:
 // (factory-name-symbol, class-name-string, constructor-name-string,
 //  result-cid, fingerprint).
 #define RECOGNIZED_LIST_FACTORY_LIST(V)                                        \
-  V(_ListFactory, _List, ., kArrayCid, 0x2121902f)                             \
+  V(_ListFactory, _List, ., kArrayCid, 0xe9c6d2be)                             \
   V(_GrowableListWithData, _GrowableList, ._withData, kGrowableObjectArrayCid, \
-    0x28b2138e)                                                                \
+    0x55981e03)                                                                \
   V(_GrowableListFactory, _GrowableList, ., kGrowableObjectArrayCid,           \
     0x3eed680b)                                                                \
-  V(_Int8ArrayFactory, Int8List, ., kTypedDataInt8ArrayCid, 0x7e39a3a1)        \
-  V(_Uint8ArrayFactory, Uint8List, ., kTypedDataUint8ArrayCid, 0x3a79adf7)     \
+  V(_Int8ArrayFactory, Int8List, ., kTypedDataInt8ArrayCid, 0x6ce2f102)        \
+  V(_Uint8ArrayFactory, Uint8List, ., kTypedDataUint8ArrayCid, 0x1163d489)     \
   V(_Uint8ClampedArrayFactory, Uint8ClampedList, .,                            \
-    kTypedDataUint8ClampedArrayCid, 0x67f38395)                                \
-  V(_Int16ArrayFactory, Int16List, ., kTypedDataInt16ArrayCid, 0x6477bda8)     \
-  V(_Uint16ArrayFactory, Uint16List, ., kTypedDataUint16ArrayCid, 0x5707c5a2)  \
-  V(_Int32ArrayFactory, Int32List, ., kTypedDataInt32ArrayCid, 0x2b96ec0e)     \
-  V(_Uint32ArrayFactory, Uint32List, ., kTypedDataUint32ArrayCid, 0x0c1c0d62)  \
-  V(_Int64ArrayFactory, Int64List, ., kTypedDataInt64ArrayCid, 0x279ab485)     \
-  V(_Uint64ArrayFactory, Uint64List, ., kTypedDataUint64ArrayCid, 0x7bcb89c2)  \
+    kTypedDataUint8ClampedArrayCid, 0x0b0e9f0f)                                \
+  V(_Int16ArrayFactory, Int16List, ., kTypedDataInt16ArrayCid, 0x6addd02d)     \
+  V(_Uint16ArrayFactory, Uint16List, ., kTypedDataUint16ArrayCid, 0x139a6464)  \
+  V(_Int32ArrayFactory, Int32List, ., kTypedDataInt32ArrayCid, 0x40dad19a)     \
+  V(_Uint32ArrayFactory, Uint32List, ., kTypedDataUint32ArrayCid, 0x988357c5)  \
+  V(_Int64ArrayFactory, Int64List, ., kTypedDataInt64ArrayCid, 0xef0a3469)     \
+  V(_Uint64ArrayFactory, Uint64List, ., kTypedDataUint64ArrayCid, 0xf49c0472)  \
   V(_Float64ArrayFactory, Float64List, ., kTypedDataFloat64ArrayCid,           \
-    0x1fde3eaf)                                                                \
+    0xf623554b)                                                                \
   V(_Float32ArrayFactory, Float32List, ., kTypedDataFloat32ArrayCid,           \
-    0x43506c09)                                                                \
+    0x779b26f8)                                                                \
   V(_Float32x4ArrayFactory, Float32x4List, ., kTypedDataFloat32x4ArrayCid,     \
-    0x4a4030d6)
+    0x9edf5402)
 
 // clang-format on
 
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index ef2bc61..0579418 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -755,15 +755,22 @@
 #endif  // !defined(PRODUCT)
 };
 
+class SharedClassTable : public AllStatic {
+ public:
+  static word class_heap_stats_table_offset();
+};
+
 class ClassTable : public AllStatic {
  public:
   static word table_offset();
+  static word shared_class_table_offset();
 #if !defined(PRODUCT)
   static word ClassOffsetFor(intptr_t cid);
   static word StateOffsetFor(intptr_t cid);
-  static word class_heap_stats_table_offset();
   static word NewSpaceCounterOffsetFor(intptr_t cid);
   static word NewSpaceSizeOffsetFor(intptr_t cid);
+  static word SharedTableOffsetFor();
+  static word SizeOffsetFor(intptr_t cid, bool is_new);
 #endif  // !defined(PRODUCT)
   static const word kSizeOfClassPairLog2;
 };
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 021c6dd..add5eab 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -22,8 +22,6 @@
 static constexpr dart::compiler::target::word Array_kMaxElements = 268435455;
 static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
     65533;
-static constexpr dart::compiler::target::word ClassTable_kSizeOfClassPairLog2 =
-    3;
 static constexpr dart::compiler::target::word
     Instructions_kMonomorphicEntryOffsetJIT = 0;
 static constexpr dart::compiler::target::word
@@ -85,7 +83,11 @@
 static constexpr dart::compiler::target::word
     ClassHeapStats_allocated_size_since_gc_new_space_offset = 52;
 static constexpr dart::compiler::target::word ClassHeapStats_state_offset = 160;
+static constexpr dart::compiler::target::word
+    ClassTable_shared_class_table_offset = 20;
 static constexpr dart::compiler::target::word ClassTable_table_offset = 8;
+static constexpr dart::compiler::target::word
+    SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 20;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 12;
@@ -138,12 +140,12 @@
 static constexpr dart::compiler::target::word ICData_state_bits_offset = 28;
 static constexpr dart::compiler::target::word
     ICData_receivers_static_type_offset = 16;
-static constexpr dart::compiler::target::word Isolate_class_table_offset = 36;
+static constexpr dart::compiler::target::word Isolate_class_table_offset = 40;
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 20;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 24;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 28;
-static constexpr dart::compiler::target::word Isolate_object_store_offset = 32;
-static constexpr dart::compiler::target::word Isolate_single_step_offset = 56;
+static constexpr dart::compiler::target::word Isolate_object_store_offset = 36;
+static constexpr dart::compiler::target::word Isolate_single_step_offset = 64;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 16;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 16;
 static constexpr dart::compiler::target::word
@@ -339,8 +341,6 @@
 static constexpr dart::compiler::target::word ClassTable_elements_start_offset =
     0;
 static constexpr dart::compiler::target::word ClassTable_element_size = 168;
-static constexpr dart::compiler::target::word
-    ClassTable_class_heap_stats_table_offset = 16;
 static constexpr dart::compiler::target::word Code_entry_point_offset[] = {
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
@@ -378,8 +378,6 @@
     576460752303423487;
 static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
     32765;
-static constexpr dart::compiler::target::word ClassTable_kSizeOfClassPairLog2 =
-    4;
 static constexpr dart::compiler::target::word
     Instructions_kMonomorphicEntryOffsetJIT = 8;
 static constexpr dart::compiler::target::word
@@ -442,7 +440,11 @@
 static constexpr dart::compiler::target::word
     ClassHeapStats_allocated_size_since_gc_new_space_offset = 104;
 static constexpr dart::compiler::target::word ClassHeapStats_state_offset = 272;
+static constexpr dart::compiler::target::word
+    ClassTable_shared_class_table_offset = 40;
 static constexpr dart::compiler::target::word ClassTable_table_offset = 16;
+static constexpr dart::compiler::target::word
+    SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 24;
@@ -495,12 +497,12 @@
 static constexpr dart::compiler::target::word ICData_state_bits_offset = 52;
 static constexpr dart::compiler::target::word
     ICData_receivers_static_type_offset = 32;
-static constexpr dart::compiler::target::word Isolate_class_table_offset = 72;
+static constexpr dart::compiler::target::word Isolate_class_table_offset = 80;
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 40;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 48;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
-static constexpr dart::compiler::target::word Isolate_object_store_offset = 64;
-static constexpr dart::compiler::target::word Isolate_single_step_offset = 112;
+static constexpr dart::compiler::target::word Isolate_object_store_offset = 72;
+static constexpr dart::compiler::target::word Isolate_single_step_offset = 128;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 32;
 static constexpr dart::compiler::target::word
@@ -698,8 +700,6 @@
 static constexpr dart::compiler::target::word ClassTable_elements_start_offset =
     0;
 static constexpr dart::compiler::target::word ClassTable_element_size = 288;
-static constexpr dart::compiler::target::word
-    ClassTable_class_heap_stats_table_offset = 32;
 static constexpr dart::compiler::target::word Code_entry_point_offset[] = {
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
@@ -736,8 +736,6 @@
 static constexpr dart::compiler::target::word Array_kMaxElements = 268435455;
 static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
     65533;
-static constexpr dart::compiler::target::word ClassTable_kSizeOfClassPairLog2 =
-    3;
 static constexpr dart::compiler::target::word
     Instructions_kMonomorphicEntryOffsetJIT = 6;
 static constexpr dart::compiler::target::word
@@ -799,7 +797,11 @@
 static constexpr dart::compiler::target::word
     ClassHeapStats_allocated_size_since_gc_new_space_offset = 52;
 static constexpr dart::compiler::target::word ClassHeapStats_state_offset = 160;
+static constexpr dart::compiler::target::word
+    ClassTable_shared_class_table_offset = 20;
 static constexpr dart::compiler::target::word ClassTable_table_offset = 8;
+static constexpr dart::compiler::target::word
+    SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 20;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 12;
@@ -852,12 +854,12 @@
 static constexpr dart::compiler::target::word ICData_state_bits_offset = 28;
 static constexpr dart::compiler::target::word
     ICData_receivers_static_type_offset = 16;
-static constexpr dart::compiler::target::word Isolate_class_table_offset = 36;
+static constexpr dart::compiler::target::word Isolate_class_table_offset = 40;
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 20;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 24;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 28;
-static constexpr dart::compiler::target::word Isolate_object_store_offset = 32;
-static constexpr dart::compiler::target::word Isolate_single_step_offset = 56;
+static constexpr dart::compiler::target::word Isolate_object_store_offset = 36;
+static constexpr dart::compiler::target::word Isolate_single_step_offset = 64;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 16;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 16;
 static constexpr dart::compiler::target::word
@@ -1053,8 +1055,6 @@
 static constexpr dart::compiler::target::word ClassTable_elements_start_offset =
     0;
 static constexpr dart::compiler::target::word ClassTable_element_size = 168;
-static constexpr dart::compiler::target::word
-    ClassTable_class_heap_stats_table_offset = 16;
 static constexpr dart::compiler::target::word Code_entry_point_offset[] = {
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
@@ -1088,8 +1088,6 @@
     576460752303423487;
 static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
     32765;
-static constexpr dart::compiler::target::word ClassTable_kSizeOfClassPairLog2 =
-    4;
 static constexpr dart::compiler::target::word
     Instructions_kMonomorphicEntryOffsetJIT = 8;
 static constexpr dart::compiler::target::word
@@ -1152,7 +1150,11 @@
 static constexpr dart::compiler::target::word
     ClassHeapStats_allocated_size_since_gc_new_space_offset = 104;
 static constexpr dart::compiler::target::word ClassHeapStats_state_offset = 272;
+static constexpr dart::compiler::target::word
+    ClassTable_shared_class_table_offset = 40;
 static constexpr dart::compiler::target::word ClassTable_table_offset = 16;
+static constexpr dart::compiler::target::word
+    SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 24;
@@ -1205,12 +1207,12 @@
 static constexpr dart::compiler::target::word ICData_state_bits_offset = 52;
 static constexpr dart::compiler::target::word
     ICData_receivers_static_type_offset = 32;
-static constexpr dart::compiler::target::word Isolate_class_table_offset = 72;
+static constexpr dart::compiler::target::word Isolate_class_table_offset = 80;
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 40;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 48;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
-static constexpr dart::compiler::target::word Isolate_object_store_offset = 64;
-static constexpr dart::compiler::target::word Isolate_single_step_offset = 112;
+static constexpr dart::compiler::target::word Isolate_object_store_offset = 72;
+static constexpr dart::compiler::target::word Isolate_single_step_offset = 128;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 32;
 static constexpr dart::compiler::target::word
@@ -1408,8 +1410,6 @@
 static constexpr dart::compiler::target::word ClassTable_elements_start_offset =
     0;
 static constexpr dart::compiler::target::word ClassTable_element_size = 288;
-static constexpr dart::compiler::target::word
-    ClassTable_class_heap_stats_table_offset = 32;
 static constexpr dart::compiler::target::word Code_entry_point_offset[] = {
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
@@ -1448,8 +1448,6 @@
     576460752303423487;
 static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
     32765;
-static constexpr dart::compiler::target::word ClassTable_kSizeOfClassPairLog2 =
-    4;
 static constexpr dart::compiler::target::word
     Instructions_kMonomorphicEntryOffsetJIT = 0;
 static constexpr dart::compiler::target::word
@@ -1512,7 +1510,11 @@
 static constexpr dart::compiler::target::word
     ClassHeapStats_allocated_size_since_gc_new_space_offset = 104;
 static constexpr dart::compiler::target::word ClassHeapStats_state_offset = 272;
+static constexpr dart::compiler::target::word
+    ClassTable_shared_class_table_offset = 40;
 static constexpr dart::compiler::target::word ClassTable_table_offset = 16;
+static constexpr dart::compiler::target::word
+    SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 24;
@@ -1565,12 +1567,12 @@
 static constexpr dart::compiler::target::word ICData_state_bits_offset = 52;
 static constexpr dart::compiler::target::word
     ICData_receivers_static_type_offset = 32;
-static constexpr dart::compiler::target::word Isolate_class_table_offset = 72;
+static constexpr dart::compiler::target::word Isolate_class_table_offset = 80;
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 40;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 48;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
-static constexpr dart::compiler::target::word Isolate_object_store_offset = 64;
-static constexpr dart::compiler::target::word Isolate_single_step_offset = 112;
+static constexpr dart::compiler::target::word Isolate_object_store_offset = 72;
+static constexpr dart::compiler::target::word Isolate_single_step_offset = 128;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 32;
 static constexpr dart::compiler::target::word
@@ -1700,8 +1702,6 @@
 static constexpr dart::compiler::target::word ClassTable_elements_start_offset =
     0;
 static constexpr dart::compiler::target::word ClassTable_element_size = 288;
-static constexpr dart::compiler::target::word
-    ClassTable_class_heap_stats_table_offset = 32;
 static constexpr dart::compiler::target::word Code_entry_point_offset[] = {
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
@@ -1734,8 +1734,6 @@
 static constexpr dart::compiler::target::word Array_kMaxElements = 268435455;
 static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
     65533;
-static constexpr dart::compiler::target::word ClassTable_kSizeOfClassPairLog2 =
-    3;
 static constexpr dart::compiler::target::word
     Instructions_kMonomorphicEntryOffsetJIT = 0;
 static constexpr dart::compiler::target::word
@@ -1797,7 +1795,11 @@
 static constexpr dart::compiler::target::word
     ClassHeapStats_allocated_size_since_gc_new_space_offset = 52;
 static constexpr dart::compiler::target::word ClassHeapStats_state_offset = 160;
+static constexpr dart::compiler::target::word
+    ClassTable_shared_class_table_offset = 20;
 static constexpr dart::compiler::target::word ClassTable_table_offset = 8;
+static constexpr dart::compiler::target::word
+    SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 20;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 12;
@@ -1850,12 +1852,12 @@
 static constexpr dart::compiler::target::word ICData_state_bits_offset = 28;
 static constexpr dart::compiler::target::word
     ICData_receivers_static_type_offset = 16;
-static constexpr dart::compiler::target::word Isolate_class_table_offset = 36;
+static constexpr dart::compiler::target::word Isolate_class_table_offset = 40;
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 20;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 24;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 28;
-static constexpr dart::compiler::target::word Isolate_object_store_offset = 32;
-static constexpr dart::compiler::target::word Isolate_single_step_offset = 56;
+static constexpr dart::compiler::target::word Isolate_object_store_offset = 36;
+static constexpr dart::compiler::target::word Isolate_single_step_offset = 64;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 16;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 16;
 static constexpr dart::compiler::target::word
@@ -1984,8 +1986,6 @@
 static constexpr dart::compiler::target::word ClassTable_elements_start_offset =
     0;
 static constexpr dart::compiler::target::word ClassTable_element_size = 168;
-static constexpr dart::compiler::target::word
-    ClassTable_class_heap_stats_table_offset = 16;
 static constexpr dart::compiler::target::word Code_entry_point_offset[] = {
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h
index f67e729..eb574eb 100644
--- a/runtime/vm/compiler/runtime_offsets_list.h
+++ b/runtime/vm/compiler/runtime_offsets_list.h
@@ -34,7 +34,6 @@
   ARRAY(ObjectPool, element_offset)                                            \
   CONSTANT(Array, kMaxElements)                                                \
   CONSTANT(Array, kMaxNewSpaceElements)                                        \
-  CONSTANT(ClassTable, kSizeOfClassPairLog2)                                   \
   CONSTANT(Instructions, kMonomorphicEntryOffsetJIT)                           \
   CONSTANT(Instructions, kPolymorphicEntryOffsetJIT)                           \
   CONSTANT(Instructions, kMonomorphicEntryOffsetAOT)                           \
@@ -71,7 +70,9 @@
   NOT_IN_PRODUCT(                                                              \
       FIELD(ClassHeapStats, allocated_size_since_gc_new_space_offset))         \
   NOT_IN_PRODUCT(FIELD(ClassHeapStats, state_offset))                          \
+  FIELD(ClassTable, shared_class_table_offset)                                 \
   FIELD(ClassTable, table_offset)                                              \
+  NOT_IN_PRODUCT(FIELD(SharedClassTable, class_heap_stats_table_offset))       \
   FIELD(Closure, context_offset)                                               \
   FIELD(Closure, delayed_type_arguments_offset)                                \
   FIELD(Closure, function_offset)                                              \
@@ -244,7 +245,6 @@
   NOT_IN_PRODUCT(ARRAY_STRUCTFIELD(                                            \
       ClassTable, NewSpaceSizeOffsetFor, ClassOffsetFor,                       \
       ClassHeapStats::allocated_size_since_gc_new_space_offset()))             \
-  NOT_IN_PRODUCT(FIELD(ClassTable, class_heap_stats_table_offset))             \
   RANGE(Code, entry_point_offset, CodeEntryKind, CodeEntryKind::kNormal,       \
         CodeEntryKind::kMonomorphicUnchecked,                                  \
         [](CodeEntryKind value) { return true; })                              \
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index c565ba5..16746a5 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -2796,12 +2796,8 @@
   // Non-Closure handling.
   {
     __ Bind(&not_closure);
-    if (n == 1) {
-      __ SmiTag(kInstanceCidOrFunction);
-    } else {
-      ASSERT(n >= 2);
+    if (n >= 2) {
       Label has_no_type_arguments;
-      // [LoadClassById] also tags [kInstanceCidOrFunction] as a side-effect.
       __ LoadClassById(R5, kInstanceCidOrFunction);
       __ mov(kInstanceInstantiatorTypeArgumentsReg, kNullReg);
       __ LoadFieldFromOffset(
@@ -2818,6 +2814,7 @@
         __ mov(kInstanceDelayedFunctionTypeArgumentsReg, kNullReg);
       }
     }
+    __ SmiTag(kInstanceCidOrFunction);
   }
 
   Label found, not_found, next_iteration;
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index 7ac6ced..b376b02 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -2782,12 +2782,8 @@
   // Non-Closure handling.
   {
     __ Bind(&not_closure);
-    if (n == 1) {
-      __ SmiTag(kInstanceCidOrFunction);
-    } else {
-      ASSERT(n >= 2);
+    if (n >= 2) {
       Label has_no_type_arguments;
-      // [LoadClassById] also tags [kInstanceCidOrFunction] as a side-effect.
       __ LoadClassById(RDI, kInstanceCidOrFunction);
       __ movq(kInstanceInstantiatorTypeArgumentsReg, kNullReg);
       __ movl(
@@ -2806,6 +2802,7 @@
         __ movq(kInstanceDelayedFunctionTypeArgumentsReg, kNullReg);
       }
     }
+    __ SmiTag(kInstanceCidOrFunction);
   }
 
   Label found, not_found, next_iteration;
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 59f903a..0463a15 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -859,14 +859,6 @@
 #else
 #error What architecture?
 #endif
-  } else {
-#if defined(ARCH_IS_32_BIT)
-    buffer.AddString(" 32-bit");
-#elif defined(ARCH_IS_64_BIT)
-    buffer.AddString(" 64-bit");
-#else
-#error What word size?
-#endif
   }
 
   if (FLAG_precompiled_mode && FLAG_dwarf_stack_traces) {
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 4b259aa..4c62313 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1666,21 +1666,10 @@
 
   Symbols::Compact();
 
-  uint8_t* vm_snapshot_instruction_buffer = nullptr;
-  BlobImageWriter vm_image_writer(T, &vm_snapshot_instruction_buffer,
-                                  ApiReallocate, 2 * MB /* initial_size */,
-                                  /*shared_objects=*/nullptr,
-                                  /*shared_instructions=*/nullptr,
-                                  /*reused_instructions=*/nullptr);
-  uint8_t* isolate_snapshot_instruction_buffer = nullptr;
-  BlobImageWriter isolate_image_writer(T, &isolate_snapshot_instruction_buffer,
-                                       ApiReallocate, 2 * MB /* initial_size */,
-                                       /*shared_objects=*/nullptr,
-                                       /*shared_instructions=*/nullptr,
-                                       /*reused_instructions=*/nullptr);
   FullSnapshotWriter writer(Snapshot::kFull, vm_snapshot_data_buffer,
                             isolate_snapshot_data_buffer, ApiReallocate,
-                            &vm_image_writer, &isolate_image_writer);
+                            NULL /* vm_image_writer */,
+                            NULL /* isolate_image_writer */);
   writer.WriteFullSnapshot();
   if (vm_snapshot_data_buffer != NULL) {
     *vm_snapshot_data_size = writer.VmIsolateSnapshotSize();
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 0dd231a..6e3bcc2 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -637,13 +637,14 @@
   }
 }
 
-// Compute token_pos_ and token_pos_initialized_.
-// If not IsInterpreted(), then also compute try_index_ and deopt_id_.
+// If not token_pos_initialized_, compute token_pos_, try_index_ and,
+// if not IsInterpreted(), also compute deopt_id_.
 TokenPosition ActivationFrame::TokenPos() {
   if (!token_pos_initialized_) {
     token_pos_initialized_ = true;
     if (IsInterpreted()) {
       token_pos_ = bytecode().GetTokenIndexOfPC(pc_);
+      try_index_ = bytecode().GetTryIndexAtPc(pc_);
       return token_pos_;
     }
     token_pos_ = TokenPosition::kNoSource;
@@ -663,16 +664,6 @@
 }
 
 intptr_t ActivationFrame::TryIndex() {
-#if !defined(DART_PRECOMPILED_RUNTIME)
-  if (IsInterpreted()) {
-    if (pc_desc_.IsNull()) {
-      ASSERT(try_index_ == -1);
-      pc_desc_ = bytecode().pc_descriptors();
-      try_index_ = bytecode().GetTryIndexAtPc(pc_);
-    }
-    return try_index_;
-  }
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
   if (!token_pos_initialized_) {
     TokenPos();  // Side effect: computes token_pos_initialized_, try_index_.
   }
@@ -2467,9 +2458,9 @@
           // Grab the awaiter.
           async_activation ^= activation->GetAsyncAwaiter();
           async_stack_trace ^= activation->GetCausalStack();
-          // see comment regarding skipping frames of async functions called
-          // synchronously above.
-          skip_sync_async_frames_count = 2;
+          // Interpreted bytecode does not invoke _ClosureCall().
+          // Skip _AsyncAwaitCompleterStart() only.
+          skip_sync_async_frames_count = 1;
         } else {
           stack_trace->AddActivation(
               CollectDartFrame(isolate, frame->pc(), frame, bytecode));
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index 2e9d7f4..33487fb 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -885,10 +885,10 @@
   for (int sel = 0; sel < Heap::kNumWeakSelectors; sel++) {
     const auto selector = static_cast<Heap::WeakSelector>(sel);
     auto before_table = GetWeakTable(before_space, selector);
-    intptr_t entry = before_table->RemoveValue(before_object);
+    intptr_t entry = before_table->RemoveValueExclusive(before_object);
     if (entry != 0) {
       auto after_table = GetWeakTable(after_space, selector);
-      after_table->SetValue(after_object, entry);
+      after_table->SetValueExclusive(after_object, entry);
     }
   }
 
diff --git a/runtime/vm/heap/heap_test.cc b/runtime/vm/heap/heap_test.cc
index c79848e..a456287 100644
--- a/runtime/vm/heap/heap_test.cc
+++ b/runtime/vm/heap/heap_test.cc
@@ -82,7 +82,7 @@
  public:
   static ClassHeapStats* GetHeapStatsForCid(ClassTable* class_table,
                                             intptr_t cid) {
-    return class_table->PreliminaryStatsAt(cid);
+    return class_table->shared_class_table()->PreliminaryStatsAt(cid);
   }
 
   static void DumpClassHeapStats(ClassHeapStats* stats) {
diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc
index be5a212..5558aa8 100644
--- a/runtime/vm/heap/marker.cc
+++ b/runtime/vm/heap/marker.cc
@@ -90,7 +90,7 @@
       : ObjectPointerVisitor(isolate),
         thread_(Thread::Current()),
 #ifndef PRODUCT
-        num_classes_(isolate->class_table()->Capacity()),
+        num_classes_(isolate->shared_class_table()->Capacity()),
         class_stats_count_(new intptr_t[num_classes_]),
         class_stats_size_(new intptr_t[num_classes_]),
 #endif  // !PRODUCT
@@ -372,7 +372,8 @@
 class MarkingWeakVisitor : public HandleVisitor {
  public:
   explicit MarkingWeakVisitor(Thread* thread)
-      : HandleVisitor(thread), class_table_(thread->isolate()->class_table()) {}
+      : HandleVisitor(thread),
+        class_table_(thread->isolate()->shared_class_table()) {}
 
   void VisitHandle(uword addr) {
     FinalizablePersistentHandle* handle =
@@ -394,7 +395,7 @@
   }
 
  private:
-  ClassTable* class_table_;
+  SharedClassTable* class_table_;
 
   DISALLOW_COPY_AND_ASSIGN(MarkingWeakVisitor);
 };
@@ -500,11 +501,11 @@
         heap_->GetWeakTable(Heap::kOld, static_cast<Heap::WeakSelector>(sel));
     intptr_t size = table->size();
     for (intptr_t i = 0; i < size; i++) {
-      if (table->IsValidEntryAt(i)) {
-        RawObject* raw_obj = table->ObjectAt(i);
+      if (table->IsValidEntryAtExclusive(i)) {
+        RawObject* raw_obj = table->ObjectAtExclusive(i);
         ASSERT(raw_obj->IsHeapObject());
         if (!raw_obj->IsMarked()) {
-          table->InvalidateAt(i);
+          table->InvalidateAtExclusive(i);
         }
       }
     }
@@ -724,7 +725,7 @@
 #ifndef PRODUCT
     // Class heap stats are not themselves thread-safe yet, so we update the
     // stats while holding stats_mutex_.
-    ClassTable* table = heap_->isolate()->class_table();
+    auto table = heap_->isolate()->shared_class_table();
     for (intptr_t i = 0; i < table->NumCids(); ++i) {
       const intptr_t count = visitor->live_count(i);
       if (count > 0) {
diff --git a/runtime/vm/heap/pages.cc b/runtime/vm/heap/pages.cc
index 4a85864..88222d0 100644
--- a/runtime/vm/heap/pages.cc
+++ b/runtime/vm/heap/pages.cc
@@ -541,7 +541,8 @@
   intptr_t size_in_words = size >> kWordSizeLog2;
   AtomicOperations::IncrementBy(&(usage_.external_in_words), size_in_words);
   NOT_IN_PRODUCT(
-      heap_->isolate()->class_table()->UpdateAllocatedExternalOld(cid, size));
+      heap_->isolate()->shared_class_table()->UpdateAllocatedExternalOld(cid,
+                                                                         size));
 }
 
 void PageSpace::PromoteExternal(intptr_t cid, intptr_t size) {
@@ -1097,7 +1098,7 @@
     return;
   }
 
-  NOT_IN_PRODUCT(isolate->class_table()->ResetCountersOld());
+  NOT_IN_PRODUCT(isolate->shared_class_table()->ResetCountersOld());
   marker_->MarkObjects(this);
   usage_.used_in_words = marker_->marked_words() + allocated_black_in_words_;
   allocated_black_in_words_ = 0;
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index accb638..b92a870 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -281,7 +281,7 @@
   ScavengerWeakVisitor(Thread* thread, Scavenger* scavenger)
       : HandleVisitor(thread),
         scavenger_(scavenger),
-        class_table_(thread->isolate()->class_table()) {
+        class_table_(thread->isolate()->shared_class_table()) {
     ASSERT(scavenger->heap_->isolate() == thread->isolate());
   }
 
@@ -307,7 +307,7 @@
 
  private:
   Scavenger* scavenger_;
-  ClassTable* class_table_;
+  SharedClassTable* class_table_;
 
   DISALLOW_COPY_AND_ASSIGN(ScavengerWeakVisitor);
 };
@@ -486,7 +486,7 @@
 }
 
 SemiSpace* Scavenger::Prologue(Isolate* isolate) {
-  NOT_IN_PRODUCT(isolate->class_table()->ResetCountersNew());
+  NOT_IN_PRODUCT(isolate->shared_class_table()->ResetCountersNew());
 
   isolate->ReleaseStoreBuffers();
   AbandonTLABs(isolate);
@@ -593,7 +593,7 @@
     heap_->UpdateGlobalMaxUsed();
   }
 
-  NOT_IN_PRODUCT(isolate->class_table()->UpdatePromoted());
+  NOT_IN_PRODUCT(isolate->shared_class_table()->UpdatePromoted());
 }
 
 bool Scavenger::ShouldPerformIdleScavenge(int64_t deadline) {
@@ -708,7 +708,7 @@
 
 void Scavenger::ProcessToSpace(ScavengerVisitor* visitor) {
   Thread* thread = Thread::Current();
-  NOT_IN_PRODUCT(ClassTable* class_table = thread->isolate()->class_table());
+  NOT_IN_PRODUCT(auto class_table = visitor->isolate()->shared_class_table());
 
   // Iterate until all work has been drained.
   while ((resolved_top_ < top_) || PromotedStackHasMore()) {
@@ -851,8 +851,8 @@
                               WeakTable* replacement_old) {
     intptr_t size = table->size();
     for (intptr_t i = 0; i < size; i++) {
-      if (table->IsValidEntryAt(i)) {
-        RawObject* raw_obj = table->ObjectAt(i);
+      if (table->IsValidEntryAtExclusive(i)) {
+        RawObject* raw_obj = table->ObjectAtExclusive(i);
         ASSERT(raw_obj->IsHeapObject());
         uword raw_addr = RawObject::ToAddr(raw_obj);
         uword header = *reinterpret_cast<uword*>(raw_addr);
@@ -862,7 +862,7 @@
           raw_obj = RawObject::FromAddr(new_addr);
           auto replacement =
               raw_obj->IsNewObject() ? replacement_new : replacement_old;
-          replacement->SetValue(raw_obj, table->ValueAt(i));
+          replacement->SetValueExclusive(raw_obj, table->ValueAtExclusive(i));
         }
       }
     }
@@ -1161,7 +1161,8 @@
   ASSERT(size >= 0);
   external_size_ += size;
   NOT_IN_PRODUCT(
-      heap_->isolate()->class_table()->UpdateAllocatedExternalNew(cid, size));
+      heap_->isolate()->shared_class_table()->UpdateAllocatedExternalNew(cid,
+                                                                         size));
 }
 
 void Scavenger::FreeExternal(intptr_t size) {
diff --git a/runtime/vm/heap/weak_table.cc b/runtime/vm/heap/weak_table.cc
index 4fd7917..95acc86 100644
--- a/runtime/vm/heap/weak_table.cc
+++ b/runtime/vm/heap/weak_table.cc
@@ -29,11 +29,11 @@
   return result;
 }
 
-void WeakTable::SetValue(RawObject* key, intptr_t val) {
+void WeakTable::SetValueExclusive(RawObject* key, intptr_t val) {
   intptr_t mask = size() - 1;
   intptr_t idx = Hash(key) & mask;
   intptr_t empty_idx = -1;
-  RawObject* obj = ObjectAt(idx);
+  RawObject* obj = ObjectAtExclusive(idx);
 
   while (obj != NULL) {
     if (obj == key) {
@@ -44,7 +44,7 @@
       empty_idx = idx;  // Insert at this location if not found.
     }
     idx = (idx + 1) & mask;
-    obj = ObjectAt(idx);
+    obj = ObjectAtExclusive(idx);
   }
 
   if (val == 0) {
@@ -60,7 +60,7 @@
     idx = empty_idx;
   }
 
-  ASSERT(!IsValidEntryAt(idx));
+  ASSERT(!IsValidEntryAtExclusive(idx));
   // Set the key and value.
   SetObjectAt(idx, key);
   SetValueAt(idx, val);
@@ -87,7 +87,7 @@
   if (used_ == 0) return;
 
   for (intptr_t i = 0; i < size_; i++) {
-    if (IsValidEntryAt(i)) {
+    if (IsValidEntryAtExclusive(i)) {
       visitor->VisitPointer(ObjectPointerAt(i));
     }
   }
@@ -107,9 +107,9 @@
   intptr_t mask = new_size - 1;
   set_used(0);
   for (intptr_t i = 0; i < old_size; i++) {
-    if (IsValidEntryAt(i)) {
+    if (IsValidEntryAtExclusive(i)) {
       // Find the new hash location for this entry.
-      RawObject* key = ObjectAt(i);
+      RawObject* key = ObjectAtExclusive(i);
       intptr_t idx = Hash(key) & mask;
       RawObject* obj = reinterpret_cast<RawObject*>(new_data[ObjectIndex(idx)]);
       while (obj != NULL) {
@@ -119,7 +119,7 @@
       }
 
       new_data[ObjectIndex(idx)] = reinterpret_cast<intptr_t>(key);
-      new_data[ValueIndex(idx)] = ValueAt(i);
+      new_data[ValueIndex(idx)] = ValueAtExclusive(i);
       set_used(used() + 1);
     }
   }
diff --git a/runtime/vm/heap/weak_table.h b/runtime/vm/heap/weak_table.h
index c7970cf..c1487b1 100644
--- a/runtime/vm/heap/weak_table.h
+++ b/runtime/vm/heap/weak_table.h
@@ -8,6 +8,7 @@
 #include "vm/globals.h"
 
 #include "platform/assert.h"
+#include "vm/lockers.h"
 #include "vm/raw_object.h"
 
 namespace dart {
@@ -46,64 +47,82 @@
   intptr_t used() const { return used_; }
   intptr_t count() const { return count_; }
 
-  bool IsValidEntryAt(intptr_t i) const {
-    ASSERT(((ValueAt(i) == 0) && ((ObjectAt(i) == NULL) ||
-                                  (data_[ObjectIndex(i)] == kDeletedEntry))) ||
-           ((ValueAt(i) != 0) && (ObjectAt(i) != NULL) &&
-            (data_[ObjectIndex(i)] != kDeletedEntry)));
+  // The following methods can be called concurrently and are guarded by a lock.
+
+  intptr_t GetValue(RawObject* key) {
+    MutexLocker ml(&mutex_);
+    return GetValueExclusive(key);
+  }
+
+  void SetValue(RawObject* key, intptr_t val) {
+    MutexLocker ml(&mutex_);
+    return SetValueExclusive(key, val);
+  }
+
+  // The following "exclusive" methods must only be called from call sites
+  // which are known to have exclusive access to the weak table.
+  //
+  // This is mostly limited to GC related code (e.g. scavenger, marker, ...)
+
+  bool IsValidEntryAtExclusive(intptr_t i) const {
+    ASSERT((ValueAtExclusive(i) == 0 &&
+            (ObjectAtExclusive(i) == NULL ||
+             data_[ObjectIndex(i)] == kDeletedEntry)) ||
+           (ValueAtExclusive(i) != 0 && ObjectAtExclusive(i) != NULL &&
+            data_[ObjectIndex(i)] != kDeletedEntry));
     return (data_[ValueIndex(i)] != 0);
   }
 
-  void InvalidateAt(intptr_t i) {
-    ASSERT(IsValidEntryAt(i));
+  void InvalidateAtExclusive(intptr_t i) {
+    ASSERT(IsValidEntryAtExclusive(i));
     SetValueAt(i, 0);
   }
 
-  RawObject* ObjectAt(intptr_t i) const {
+  RawObject* ObjectAtExclusive(intptr_t i) const {
     ASSERT(i >= 0);
     ASSERT(i < size());
     return reinterpret_cast<RawObject*>(data_[ObjectIndex(i)]);
   }
 
-  intptr_t ValueAt(intptr_t i) const {
+  intptr_t ValueAtExclusive(intptr_t i) const {
     ASSERT(i >= 0);
     ASSERT(i < size());
     return data_[ValueIndex(i)];
   }
 
-  void SetValue(RawObject* key, intptr_t val);
+  void SetValueExclusive(RawObject* key, intptr_t val);
 
-  intptr_t GetValue(RawObject* key) const {
+  intptr_t GetValueExclusive(RawObject* key) const {
     intptr_t mask = size() - 1;
     intptr_t idx = Hash(key) & mask;
-    RawObject* obj = ObjectAt(idx);
+    RawObject* obj = ObjectAtExclusive(idx);
     while (obj != NULL) {
       if (obj == key) {
-        return ValueAt(idx);
+        return ValueAtExclusive(idx);
       }
       idx = (idx + 1) & mask;
-      obj = ObjectAt(idx);
+      obj = ObjectAtExclusive(idx);
     }
-    ASSERT(ValueAt(idx) == 0);
+    ASSERT(ValueAtExclusive(idx) == 0);
     return 0;
   }
 
   // Removes and returns the value associated with |key|. Returns 0 if there is
   // no value associated with |key|.
-  intptr_t RemoveValue(RawObject* key) {
+  intptr_t RemoveValueExclusive(RawObject* key) {
     intptr_t mask = size() - 1;
     intptr_t idx = Hash(key) & mask;
-    RawObject* obj = ObjectAt(idx);
+    RawObject* obj = ObjectAtExclusive(idx);
     while (obj != NULL) {
       if (obj == key) {
-        intptr_t result = ValueAt(idx);
-        InvalidateAt(idx);
+        intptr_t result = ValueAtExclusive(idx);
+        InvalidateAtExclusive(idx);
         return result;
       }
       idx = (idx + 1) & mask;
-      obj = ObjectAt(idx);
+      obj = ObjectAtExclusive(idx);
     }
-    ASSERT(ValueAt(idx) == 0);
+    ASSERT(ValueAtExclusive(idx) == 0);
     return 0;
   }
 
@@ -174,6 +193,8 @@
     return reinterpret_cast<uintptr_t>(key) * 92821;
   }
 
+  Mutex mutex_;
+
   // data_ contains size_ tuples of key/value.
   intptr_t* data_;
   // size_ keeps the number of entries in data_. used_ maintains the number of
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index 03672dc..c097744 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -1090,6 +1090,7 @@
       shared_data_image_(shared_data_image),
       shared_instructions_image_(shared_instructions_image) {
   ASSERT(data_image != NULL);
+  ASSERT(instructions_image != NULL);
 }
 
 RawApiError* ImageReader::VerifyAlignment() const {
@@ -1106,7 +1107,6 @@
 }
 
 RawInstructions* ImageReader::GetInstructionsAt(int32_t offset) const {
-  ASSERT(instructions_image_ != nullptr);
   ASSERT(Utils::IsAligned(offset, OS::PreferredCodeAlignment()));
 
   RawObject* result;
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index 77bd91d..e4a735a 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -264,7 +264,7 @@
                                           RawObject** result) {
   const uword start = thread->top();
 #ifndef PRODUCT
-  ClassTable* table = thread->isolate()->class_table();
+  auto table = thread->isolate()->shared_class_table();
   if (UNLIKELY(table->TraceAllocationFor(class_id))) {
     return false;
   }
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index c341416..261fde1 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -1050,7 +1050,8 @@
       current_tag_(UserTag::null()),
       default_tag_(UserTag::null()),
       ic_miss_code_(Code::null()),
-      class_table_(),
+      shared_class_table_(new SharedClassTable()),
+      class_table_(shared_class_table_.get()),
       store_buffer_(new StoreBuffer()),
 #if !defined(TARGET_ARCH_DBC) && !defined(DART_PRECOMPILED_RUNTIME)
       native_callback_trampolines_(),
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 48895f3..faef0b3 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -340,6 +340,9 @@
   SafepointHandler* safepoint_handler() const {
     return group()->safepoint_handler();
   }
+
+  SharedClassTable* shared_class_table() { return shared_class_table_.get(); }
+
   ClassTable* class_table() { return &class_table_; }
   static intptr_t class_table_offset() {
     return OFFSET_OF(Isolate, class_table_);
@@ -1023,6 +1026,7 @@
   RawUserTag* current_tag_;
   RawUserTag* default_tag_;
   RawCode* ic_miss_code_;
+  std::unique_ptr<SharedClassTable> shared_class_table_;
   ObjectStore* object_store_ = nullptr;
   ClassTable class_table_;
   bool single_step_ = false;
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 640c358..17fa30e 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -676,9 +676,6 @@
   if (skip_reload) {
     ASSERT(modified_libs_->IsEmpty());
     reload_skipped_ = true;
-    // Inform GetUnusedChangesInLastReload that a reload has happened.
-    I->object_store()->set_changed_in_last_reload(
-        GrowableObjectArray::Handle(GrowableObjectArray::New()));
     ReportOnJSON(js_);
 
     // If we use the CFE and performed a compilation, we need to notify that
@@ -1218,81 +1215,6 @@
 }
 #endif
 
-static void RecordChanges(const GrowableObjectArray& changed_in_last_reload,
-                          const Class& old_cls,
-                          const Class& new_cls) {
-  // All members of enum classes are synthetic, so nothing to report here.
-  if (new_cls.is_enum_class()) {
-    return;
-  }
-
-  // Don't report `typedef bool Predicate(Object o)` as unused. There is nothing
-  // to execute.
-  if (new_cls.IsTypedefClass()) {
-    return;
-  }
-
-  if (new_cls.raw() == old_cls.raw()) {
-    // A new class maps to itself. All its functions, field initizers, and so
-    // on are new.
-    changed_in_last_reload.Add(new_cls);
-    return;
-  }
-
-  if (old_cls.IsTopLevel()) {
-    return;
-  }
-
-  if (!old_cls.is_finalized()) {
-    if (new_cls.SourceFingerprint() == old_cls.SourceFingerprint()) {
-      return;
-    }
-    // We don't know the members. Register interest in the whole class. Creates
-    // false positives.
-    changed_in_last_reload.Add(new_cls);
-    return;
-  }
-  ASSERT(new_cls.is_finalized());
-
-  Zone* zone = Thread::Current()->zone();
-  const Array& functions = Array::Handle(zone, new_cls.functions());
-  const Array& fields = Array::Handle(zone, new_cls.fields());
-  Function& new_function = Function::Handle(zone);
-  Function& old_function = Function::Handle(zone);
-  Field& new_field = Field::Handle(zone);
-  Field& old_field = Field::Handle(zone);
-  String& selector = String::Handle(zone);
-  for (intptr_t i = 0; i < functions.Length(); i++) {
-    new_function ^= functions.At(i);
-    selector = new_function.name();
-    old_function = old_cls.LookupFunction(selector);
-    // If we made live changes with proper structed edits, this would just be
-    // old != new.
-    if (old_function.IsNull() || (new_function.SourceFingerprint() !=
-                                  old_function.SourceFingerprint())) {
-      ASSERT(!new_function.HasCode());
-      ASSERT(new_function.usage_counter() == 0);
-      changed_in_last_reload.Add(new_function);
-    }
-  }
-  for (intptr_t i = 0; i < fields.Length(); i++) {
-    new_field ^= fields.At(i);
-    if (!new_field.is_static()) continue;
-    selector = new_field.name();
-    old_field = old_cls.LookupField(selector);
-    if (old_field.IsNull() || !old_field.is_static()) {
-      // New field.
-      changed_in_last_reload.Add(new_field);
-    } else if (new_field.SourceFingerprint() != old_field.SourceFingerprint()) {
-      // Changed field.
-      changed_in_last_reload.Add(new_field);
-      if (!old_field.IsUninitialized()) {
-        new_field.set_initializer_changed_after_initialization(true);
-      }
-    }
-  }
-}
-
 void IsolateReloadContext::Commit() {
   TIMELINE_SCOPE(Commit);
   TIR_Print("---- COMMITTING RELOAD\n");
@@ -1331,9 +1253,6 @@
     lib_map.Release();
   }
 
-  const GrowableObjectArray& changed_in_last_reload =
-      GrowableObjectArray::Handle(GrowableObjectArray::New());
-
   {
     TIMELINE_SCOPE(CopyStaticFieldsAndPatchFieldsAndFunctions);
     // Copy static field values from the old classes to the new classes.
@@ -1359,7 +1278,6 @@
           old_cls.PatchFieldsAndFunctions();
           old_cls.MigrateImplicitStaticClosures(this, new_cls);
         }
-        RecordChanges(changed_in_last_reload, old_cls, new_cls);
       }
     }
 
@@ -1378,15 +1296,6 @@
     }
   }
 
-  if (FLAG_identity_reload) {
-    Object& changed = Object::Handle();
-    for (intptr_t i = 0; i < changed_in_last_reload.Length(); i++) {
-      changed = changed_in_last_reload.At(i);
-      ASSERT(changed.IsClass());  // Only fuzzy from lazy finalization.
-    }
-  }
-  I->object_store()->set_changed_in_last_reload(changed_in_last_reload);
-
   {
     TIMELINE_SCOPE(UpdateLibrariesArray);
     // Update the libraries array.
diff --git a/runtime/vm/isolate_reload.h b/runtime/vm/isolate_reload.h
index 300195e..b6e0553 100644
--- a/runtime/vm/isolate_reload.h
+++ b/runtime/vm/isolate_reload.h
@@ -145,6 +145,8 @@
   // All zone allocated objects must be allocated from this zone.
   Zone* zone() const { return zone_; }
 
+  bool UseSavedClassTableForGC() const { return saved_class_table_ != nullptr; }
+
   bool reload_skipped() const { return reload_skipped_; }
   bool reload_aborted() const { return reload_aborted_; }
   RawError* error() const;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 5dbc67b..c541cd2 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -2202,7 +2202,7 @@
     }
   }
 #ifndef PRODUCT
-  ClassTable* class_table = thread->isolate()->class_table();
+  auto class_table = thread->isolate()->shared_class_table();
   if (space == Heap::kNew) {
     class_table->UpdateAllocatedNew(cls_id, size);
   } else {
@@ -3298,7 +3298,7 @@
 
 bool Class::TraceAllocation(Isolate* isolate) const {
 #ifndef PRODUCT
-  ClassTable* class_table = isolate->class_table();
+  auto class_table = isolate->shared_class_table();
   return class_table->TraceAllocationFor(id());
 #else
   return false;
@@ -3310,7 +3310,7 @@
   Isolate* isolate = Isolate::Current();
   const bool changed = trace_allocation != this->TraceAllocation(isolate);
   if (changed) {
-    ClassTable* class_table = isolate->class_table();
+    auto class_table = isolate->shared_class_table();
     class_table->SetTraceAllocationFor(id(), trace_allocation);
     DisableAllocationStub();
   }
@@ -8104,21 +8104,31 @@
 }
 
 bool Function::CheckSourceFingerprint(const char* prefix, int32_t fp) const {
-  // TODO(36376): Restore checking fingerprints of recognized methods.
-  // '(kernel_offset() <= 0)' looks like an impossible condition, fix this and
-  //  re-enable fingerprints checking.
-  if (!Isolate::Current()->obfuscate() && !is_declared_in_bytecode() &&
-      (kernel_offset() <= 0) && (SourceFingerprint() != fp)) {
+  if (Isolate::Current()->obfuscate() || FLAG_precompiled_mode ||
+      (Dart::vm_snapshot_kind() != Snapshot::kNone)) {
+    return true;  // The kernel structure has been altered, skip checking.
+  }
+
+  if (is_declared_in_bytecode()) {
+    // AST and bytecode compute different fingerprints, and we only track one
+    // fingerprint set.
+    return true;
+  }
+
+  if (SourceFingerprint() != fp) {
     const bool recalculatingFingerprints = false;
     if (recalculatingFingerprints) {
       // This output can be copied into a file, then used with sed
       // to replace the old values.
-      // sed -i.bak -f /tmp/newkeys runtime/vm/compiler/method_recognizer.h
+      // sed -i.bak -f /tmp/newkeys \
+      //    runtime/vm/compiler/recognized_methods_list.h
       THR_Print("s/0x%08x/0x%08x/\n", fp, SourceFingerprint());
     } else {
       THR_Print(
-          "FP mismatch while recognizing method %s:"
-          " expecting 0x%08x found 0x%08x\n",
+          "FP mismatch while recognizing method %s: expecting 0x%08x found "
+          "0x%08x.\nIf the behavior of this function has changed, then changes "
+          "are also needed in the VM's compiler. Otherwise the fingerprint can "
+          "simply be updated in recognized_methods_list.h\n",
           ToFullyQualifiedCString(), fp, SourceFingerprint());
       return false;
     }
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 77461f0..8fab9f4 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -139,7 +139,6 @@
   R_(Function, megamorphic_miss_function)                                      \
   RW(Array, code_order_table)                                                  \
   RW(Array, obfuscation_map)                                                   \
-  RW(GrowableObjectArray, changed_in_last_reload)                              \
   RW(Class, ffi_pointer_class)                                                 \
   RW(Class, ffi_native_type_class)                                             \
   RW(Class, ffi_struct_class)                                                  \
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index 21566b5..65e7a5f 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -494,7 +494,7 @@
 }
 
 #if defined(DART_USE_TCMALLOC) && defined(HOST_OS_LINUX) && defined(DEBUG) &&  \
-    defined(HOST_ARCH_x64)
+    defined(HOST_ARCH_X64)
 
 DART_NOINLINE static void NativeAllocationSampleHelper(char** result) {
   ASSERT(result != NULL);
@@ -502,12 +502,12 @@
 }
 
 ISOLATE_UNIT_TEST_CASE(Profiler_NativeAllocation) {
-  EnableProfiler();
-
   bool enable_malloc_hooks_saved = FLAG_profiler_native_memory;
   FLAG_profiler_native_memory = true;
 
-  MallocHooks::InitOnce();
+  EnableProfiler();
+
+  MallocHooks::Init();
   MallocHooks::ResetStats();
   bool stack_trace_collection_enabled =
       MallocHooks::stack_trace_collection_enabled();
@@ -536,31 +536,27 @@
     // Filter for the class in the time range.
     NativeAllocationSampleFilter filter(before_allocations_micros,
                                         allocation_extent_micros);
-    profile.Build(thread, &filter, Profiler::sample_buffer());
+    profile.Build(thread, &filter, Profiler::allocation_sample_buffer());
     // We should have 1 allocation sample.
     EXPECT_EQ(1, profile.sample_count());
-    ProfileStackWalker walker(&profile)
+    ProfileStackWalker walker(&profile);
 
-        // Move down from the root.
-        EXPECT(walker.Down());
+    // Move down from the root.
     EXPECT_SUBSTRING("[Native]", walker.CurrentName());
-    EXPECT_EQ(walker.native_allocation_size_bytes(), 1024);
+    EXPECT_EQ(1024ul, profile.SampleAt(0)->native_allocation_size_bytes());
     EXPECT(walker.Down());
     EXPECT_STREQ("dart::Dart_TestProfiler_NativeAllocation()",
                  walker.CurrentName());
-    EXPECT_EQ(walker.native_allocation_size_bytes(), 1024);
     EXPECT(walker.Down());
     EXPECT_STREQ("dart::TestCase::Run()", walker.CurrentName());
-    EXPECT_EQ(walker.native_allocation_size_bytes(), 1024);
     EXPECT(walker.Down());
     EXPECT_STREQ("dart::TestCaseBase::RunTest()", walker.CurrentName());
-    EXPECT_EQ(walker.native_allocation_size_bytes(), 1024);
     EXPECT(walker.Down());
     EXPECT_STREQ("dart::TestCaseBase::RunAll()", walker.CurrentName());
-    EXPECT_EQ(walker.native_allocation_size_bytes(), 1024);
+    EXPECT(walker.Down());
+    EXPECT_SUBSTRING("[Native]", walker.CurrentName());
     EXPECT(walker.Down());
     EXPECT_STREQ("main", walker.CurrentName());
-    EXPECT_EQ(walker.native_allocation_size_bytes(), 1024);
     EXPECT(!walker.Down());
   }
 
@@ -601,11 +597,10 @@
 
   MallocHooks::set_stack_trace_collection_enabled(
       stack_trace_collection_enabled);
-  MallocHooks::TearDown();
   FLAG_profiler_native_memory = enable_malloc_hooks_saved;
 }
-#endif  // defined(DART_USE_TCMALLOC) && !defined(PRODUCT) &&
-        // !defined(TARGET_ARCH_DBC) && !defined(HOST_OS_FUCHSIA)
+#endif  // defined(DART_USE_TCMALLOC) && defined(HOST_OS_LINUX) &&             \
+        // defined(DEBUG) && defined(HOST_ARCH_X64)
 
 ISOLATE_UNIT_TEST_CASE(Profiler_ToggleRecordAllocation) {
   EnableProfiler();
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 1f2ccdb..212d274 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -9,6 +9,7 @@
 #include "vm/heap/become.h"
 #include "vm/heap/freelist.h"
 #include "vm/isolate.h"
+#include "vm/isolate_reload.h"
 #include "vm/object.h"
 #include "vm/runtime_entry.h"
 #include "vm/visitor.h"
@@ -57,11 +58,11 @@
     }
   }
   intptr_t class_id = ClassIdTag::decode(tags);
-  if (!isolate->class_table()->IsValidIndex(class_id)) {
+  if (!isolate->shared_class_table()->IsValidIndex(class_id)) {
     FATAL1("Invalid class id encountered %" Pd "\n", class_id);
   }
-  if ((class_id == kNullCid) &&
-      (isolate->class_table()->At(class_id) == NULL)) {
+  if (class_id == kNullCid &&
+      isolate->shared_class_table()->HasValidClassAt(class_id)) {
     // Null class not yet initialized; skip.
     return;
   }
@@ -212,9 +213,19 @@
       // TODO(koda): Add Size(ClassTable*) interface to allow caching in loops.
       Isolate* isolate = Isolate::Current();
 #if defined(DEBUG)
-      ClassTable* class_table = isolate->class_table();
+      auto class_table = isolate->shared_class_table();
+#if !defined(DART_PRECOMPILED_RUNTIME)
+      auto reload_context = isolate->reload_context();
+      const bool use_saved_class_table =
+          reload_context != nullptr ? reload_context->UseSavedClassTableForGC()
+                                    : false;
+#else
+      const bool use_saved_class_table = false;
+#endif
+
+      ASSERT(use_saved_class_table || class_table->SizeAt(class_id) > 0);
       if (!class_table->IsValidIndex(class_id) ||
-          !class_table->HasValidClassAt(class_id)) {
+          (!class_table->HasValidClassAt(class_id) && !use_saved_class_table)) {
         FATAL2("Invalid class id: %" Pd " from tags %x\n", class_id,
                ptr()->tags_);
       }
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index fc8dfc7..0c88bdc 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -2140,6 +2140,10 @@
 
  private:
   friend class Library;
+  friend class OneByteStringSerializationCluster;
+  friend class TwoByteStringSerializationCluster;
+  friend class OneByteStringDeserializationCluster;
+  friend class TwoByteStringDeserializationCluster;
   friend class RODataSerializationCluster;
   friend class ImageWriter;
 };
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 4ab9c57..98539e3 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -1415,70 +1415,6 @@
   return true;
 }
 
-static const MethodParameter* get_unused_changes_in_last_reload_params[] = {
-    ISOLATE_PARAMETER, NULL,
-};
-
-static bool GetUnusedChangesInLastReload(Thread* thread, JSONStream* js) {
-  if (CheckCompilerDisabled(thread, js)) {
-    return true;
-  }
-
-  const GrowableObjectArray& changed_in_last_reload =
-      GrowableObjectArray::Handle(
-          thread->isolate()->object_store()->changed_in_last_reload());
-  if (changed_in_last_reload.IsNull()) {
-    js->PrintError(kIsolateMustHaveReloaded, "No change to compare with.");
-    return true;
-  }
-  JSONObject jsobj(js);
-  jsobj.AddProperty("type", "UnusedChangesInLastReload");
-  JSONArray jsarr(&jsobj, "unused");
-  Object& changed = Object::Handle();
-  Function& function = Function::Handle();
-  Field& field = Field::Handle();
-  Class& cls = Class::Handle();
-  Array& functions = Array::Handle();
-  Array& fields = Array::Handle();
-  for (intptr_t i = 0; i < changed_in_last_reload.Length(); i++) {
-    changed = changed_in_last_reload.At(i);
-    if (changed.IsFunction()) {
-      function ^= changed.raw();
-      if (!function.WasExecuted()) {
-        jsarr.AddValue(function);
-      }
-    } else if (changed.IsField()) {
-      field ^= changed.raw();
-      if (field.IsUninitialized() ||
-          field.initializer_changed_after_initialization()) {
-        jsarr.AddValue(field);
-      }
-    } else if (changed.IsClass()) {
-      cls ^= changed.raw();
-      if (!cls.is_finalized()) {
-        // Not used at all.
-        jsarr.AddValue(cls);
-      } else {
-        functions = cls.functions();
-        for (intptr_t j = 0; j < functions.Length(); j++) {
-          function ^= functions.At(j);
-          if (!function.WasExecuted()) {
-            jsarr.AddValue(function);
-          }
-        }
-        fields = cls.fields();
-        for (intptr_t j = 0; j < fields.Length(); j++) {
-          field ^= fields.At(j);
-          if (field.IsUninitialized()) {
-            jsarr.AddValue(field);
-          }
-        }
-      }
-    }
-  }
-  return true;
-}
-
 static const MethodParameter* get_stack_params[] = {
     RUNNABLE_ISOLATE_PARAMETER,
     NULL,
@@ -3943,7 +3879,7 @@
   Isolate* isolate = thread->isolate();
   if (should_reset_accumulator) {
     isolate->UpdateLastAllocationProfileAccumulatorResetTimestamp();
-    isolate->class_table()->ResetAllocationAccumulators();
+    isolate->shared_class_table()->ResetAllocationAccumulators();
   }
   if (should_collect) {
     isolate->UpdateLastAllocationProfileGCTimestamp();
@@ -4763,8 +4699,6 @@
     get_source_report_params },
   { "getStack", GetStack,
     get_stack_params },
-  { "_getUnusedChangesInLastReload", GetUnusedChangesInLastReload,
-    get_unused_changes_in_last_reload_params },
   { "_getTagProfile", GetTagProfile,
     get_tag_profile_params },
   { "_getTypeArgumentsList", GetTypeArgumentsList,
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 5c3b68e..1f7beaa 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -196,6 +196,9 @@
   const uint8_t* Addr() const { return reinterpret_cast<const uint8_t*>(this); }
 
   const uint8_t* DataImage() const {
+    if (!IncludesCode(kind())) {
+      return NULL;
+    }
     uword offset = Utils::RoundUp(length(), OS::kMaxPreferredCodeAlignment);
     return Addr() + offset;
   }
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 3da6666..e05f475 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -724,8 +724,7 @@
       "}\n";
   Dart_Handle result;
 
-  uint8_t* isolate_snapshot_data_buffer = nullptr;
-  intptr_t isolate_snapshot_data_size = 0;
+  uint8_t* isolate_snapshot_data_buffer;
 
   // Start an Isolate, load a script and create a full snapshot.
   Timer timer1(true, "Snapshot_test");
@@ -750,38 +749,17 @@
     OS::PrintErr("Without Snapshot: %" Pd64 "us\n", timer1.TotalElapsedTime());
 
     // Write snapshot with object content.
-    uint8_t* isolate_snapshot_text_buffer = nullptr;
-    BlobImageWriter image_writer(thread, &isolate_snapshot_text_buffer,
-                                 &malloc_allocator, 2 * MB /* initial_size */,
-                                 /*shared_objects=*/nullptr,
-                                 /*shared_instructions=*/nullptr,
-                                 /*reused_instructions=*/nullptr);
-    FullSnapshotWriter writer(Snapshot::kFull, nullptr,
+    FullSnapshotWriter writer(Snapshot::kFull, NULL,
                               &isolate_snapshot_data_buffer, &malloc_allocator,
-                              nullptr, &image_writer);
+                              NULL, /*image_writer*/ nullptr);
     writer.WriteFullSnapshot();
-    isolate_snapshot_data_size = writer.IsolateSnapshotSize();
-    free(isolate_snapshot_text_buffer);
   }
 
-  // Malloc gives only 8 byte alignment, but we need
-  // OS::kMaxPreferredCodeAlignment. Rellocate to VirtualMemory to get page
-  // alignment.
-  std::unique_ptr<VirtualMemory> aligned_isolate_snapshot_data_buffer(
-      VirtualMemory::Allocate(
-          Utils::RoundUp(isolate_snapshot_data_size, VirtualMemory::PageSize()),
-          false, "snapshot_test"));
-  memmove(aligned_isolate_snapshot_data_buffer->address(),
-          isolate_snapshot_data_buffer, isolate_snapshot_data_size);
-  free(isolate_snapshot_data_buffer);
-  isolate_snapshot_data_buffer = nullptr;
-
   // Now Create another isolate using the snapshot and execute a method
   // from the script.
   Timer timer2(true, "Snapshot_test");
   timer2.Start();
-  TestCase::CreateTestIsolateFromSnapshot(reinterpret_cast<uint8_t*>(
-      aligned_isolate_snapshot_data_buffer->address()));
+  TestCase::CreateTestIsolateFromSnapshot(isolate_snapshot_data_buffer);
   {
     Dart_EnterScope();  // Start a Dart API scope for invoking API functions.
     timer2.Stop();
@@ -794,6 +772,7 @@
     Dart_ExitScope();
   }
   Dart_ShutdownIsolate();
+  free(isolate_snapshot_data_buffer);
 }
 
 // Helper function to call a top level Dart function and serialize the result.
diff --git a/sdk_nnbd/BUILD.gn b/sdk_nnbd/BUILD.gn
new file mode 100644
index 0000000..228fc3c
--- /dev/null
+++ b/sdk_nnbd/BUILD.gn
@@ -0,0 +1,1069 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for 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 GN file contains build rules for assembling the Dart SDK. There are
+# two possible variants: the "Full" SDK, and the "Platform" SDK. If you want
+# to make a new subset of the Full SDK, make it the same way we make
+# the Platform SDK.
+#
+# Warning:
+# If you need to copy something into dart-sdk/lib/foo in addition to the stuff
+# copied there by :copy_libraries, then you must depend on ":copy_libraries",
+# or ":copy_libraries" may delete/overwrite your addition, and the build will
+# fail.
+
+import("../build/dart/copy_tree.gni")
+import("../runtime/runtime_args.gni")
+
+declare_args() {
+  # Build a SDK with less stuff. It excludes dart2js, ddc, and web libraries.
+  dart_platform_sdk = true
+
+  # Path to stripped dart binaries relative to build output directory.
+  dart_stripped_binary = "dart"
+  dartaotruntime_stripped_binary = "dartaotruntime"
+  gen_snapshot_stripped_binary = "gen_snapshot"
+}
+
+# The directory layout of the SDK is as follows:
+#
+# ..dart-sdk/
+# ....bin/
+# ......dart or dart.exe (executable)
+# ......dart.lib (import library for VM native extensions on Windows)
+# ......dartaotruntime or dartaotruntime.exe (executable)
+# ......dartdoc
+# ......dartfmt
+# ......dart2aot
+# ......dart2js
+# ......dartanalyzer
+# ......dartdevc
+# ......utils/gen_snapshot or utils/gen_snapshot.exe (executable)
+# ......pub
+# ......snapshots/
+# ........analysis_server.dart.snapshot
+# ........dart2js.dart.snapshot
+# ........dartanalyzer.dart.snapshot
+# ........dartdoc.dart.snapshot
+# ........dartfmt.dart.snapshot
+# ........dartdevc.dart.snapshot
+# ........gen_kernel.dart.snapshot
+# ........kernel_worker.dart.snapshot
+# ........pub.dart.snapshot
+#.........resources/
+#...........dartdoc/
+#..............packages
+#.............resources/
+#.............templates/
+# ....include/
+# ......dart_api.h
+# ......dart_native_api.h
+# ......dart_tools_api.h
+# ....lib/
+# ......libraries.json
+# ......_internal/
+#.........strong.sum
+#.........dart2js_platform.dill
+#.........dart2js_server_platform.dill
+#.........dart2js_platform_strong.dill
+#.........dart2js_server_platform_strong.dill
+#.........vm_platform_strong.dill
+#.........dev_compiler/
+# ......async/
+# ......collection/
+# ......convert/
+# ......core/
+# ......html/
+# ......_http/
+# ......internal/
+# ......io/
+# ......isolate/
+# ......js/
+# ......js_util/
+# ......math/
+# ......mirrors/
+# ......typed_data/
+# ......wasm/
+# ......api_readme.md
+# ....model/
+# ......lexeme/
+# ........idx2word.json
+# ........model.tflite
+# ........word2idx.json
+
+# Scripts that go under bin/
+_platform_sdk_scripts = [
+  "dartanalyzer",
+  "dartfmt",
+  "pub",
+]
+
+_full_sdk_scripts = [
+  "dart2js",
+  "dartanalyzer",
+  "dartdevc",
+  "dartfmt",
+  "pub",
+]
+
+# Scripts not ending in _sdk that go under bin/
+_scripts = [ "dartdoc" ]
+
+# Snapshots that go under bin/snapshots
+_platform_sdk_snapshots = [
+  [
+    "dartanalyzer",
+    "../utils/dartanalyzer:generate_dartanalyzer_snapshot",
+  ],
+  [
+    "dart2native",
+    "../utils/dart2native:generate_dart2native_snapshot",
+  ],
+  [
+    "dartdoc",
+    "../utils/dartdoc",
+  ],
+  [
+    "dartfmt",
+    "../utils/dartfmt",
+  ],
+  [
+    "pub",
+    "../utils/pub",
+  ],
+]
+if (create_kernel_service_snapshot) {
+  _platform_sdk_snapshots += [
+    [
+      "kernel-service",
+      "../utils/kernel-service:kernel-service_snapshot",
+    ],
+  ]
+}
+if (dart_target_arch != "arm") {
+  _platform_sdk_snapshots += [
+    [
+      "analysis_server",
+      "../utils/analysis_server",
+    ],
+  ]
+}
+
+_full_sdk_snapshots = [
+  [
+    "dart2js",
+    "../utils/compiler:dart2js",
+  ],
+  [
+    "dartanalyzer",
+    "../utils/dartanalyzer:generate_dartanalyzer_snapshot",
+  ],
+  [
+    "dart2native",
+    "../utils/dart2native:generate_dart2native_snapshot",
+  ],
+  [
+    "dartdevc",
+    "../utils/dartdevc",
+  ],
+  [
+    "dartdoc",
+    "../utils/dartdoc",
+  ],
+  [
+    "dartfmt",
+    "../utils/dartfmt",
+  ],
+  [
+    "kernel_worker",
+    "../utils/bazel:kernel_worker",
+  ],
+  [
+    "pub",
+    "../utils/pub",
+  ],
+]
+if (create_kernel_service_snapshot) {
+  _full_sdk_snapshots += [
+    [
+      "kernel-service",
+      "../utils/kernel-service:kernel-service_snapshot",
+    ],
+  ]
+}
+if (dart_target_arch != "arm") {
+  _full_sdk_snapshots += [
+    [
+      "analysis_server",
+      "../utils/analysis_server",
+    ],
+  ]
+}
+
+# Libraries that go under lib/
+_full_sdk_libraries = [
+  "_chrome",
+  "_internal",
+  "async",
+  "cli",
+  "collection",
+  "convert",
+  "core",
+  "developer",
+  "ffi",
+  "html",
+  "_http",
+  "indexed_db",
+  "internal",
+  "io",
+  "isolate",
+  "js",
+  "js_util",
+  "math",
+  "mirrors",
+  "profiler",
+  "svg",
+  "typed_data",
+  "wasm",
+  "web_audio",
+  "web_gl",
+  "web_sql",
+]
+
+# Apps running on the platform SDK shouldn't be using Dart4Web libraries, but
+# the analyzer and dartdoc expect all the library sources to be present.
+#
+# _platform_sdk_libraries = [
+#   "_internal",
+#   "async",
+#   "cli",
+#   "collection",
+#   "convert",
+#   "core",
+#   "developer",
+#   "html",
+#   "_http",
+#   "internal",
+#   "io",
+#   "isolate",
+#   "math",
+#   "mirrors",
+#   "profiler",
+#   "typed_data",
+# ]
+_platform_sdk_libraries = _full_sdk_libraries
+
+# From here down to the copy_trees() invocation, we collect all the information
+# about trees that need to be copied in the list of scopes, copy_tree_specs.
+copy_tree_specs = []
+
+# This rule copies dartdoc templates to
+# bin/resources/dartdoc/templates
+copy_tree_specs += [ {
+      target = "copy_dartdoc_templates"
+      visibility = [ ":copy_dartdoc_files" ]
+      source = "../third_party/pkg/dartdoc/lib/templates"
+      dest = "$root_out_dir/dart-sdk/bin/resources/dartdoc/templates"
+      ignore_patterns = "{}"
+    } ]
+
+# This rule copies dartdoc resources to
+# bin/resources/dartdoc/resources
+copy_tree_specs += [ {
+      target = "copy_dartdoc_resources"
+      visibility = [ ":copy_dartdoc_files" ]
+      source = "../third_party/pkg/dartdoc/lib/resources"
+      dest = "$root_out_dir/dart-sdk/bin/resources/dartdoc/resources"
+      ignore_patterns = "{}"
+    } ]
+
+# This loop generates rules to copy libraries to lib/
+foreach(library, _full_sdk_libraries) {
+  copy_tree_specs += [ {
+        target = "copy_${library}_library"
+        visibility = [
+          ":copy_platform_sdk_libraries",
+          ":copy_full_sdk_libraries",
+        ]
+        source = "lib/$library"
+        dest = "$root_out_dir/dart-sdk/lib/$library"
+        ignore_patterns = "*.svn,doc,*.py,*.gypi,*.sh,.gitignore"
+      } ]
+}
+
+if (is_win) {
+  copy_tree_specs += [ {
+        target = "copy_7zip"
+        visibility = [ ":create_common_sdk" ]
+        deps = [
+          ":copy_libraries",
+        ]
+        source = "../third_party/7zip"
+        dest = "$root_out_dir/dart-sdk/lib/_internal/pub/asset/7zip"
+        ignore_patterns = ".svn"
+      } ]
+}
+
+if (target_cpu == "x64") {
+  copy_tree_specs += [
+      {
+        target = "copy_language_model"
+        visibility = [ ":create_common_sdk" ]
+        deps = [
+          ":copy_libraries",
+        ]
+        source = "../pkg/analysis_server/language_model"
+        dest = "$root_out_dir/dart-sdk/model"
+        ignore_patterns = "{}"
+      },
+      {
+        target = "copy_libtensorflowlite_c"
+        visibility = [ ":create_common_sdk" ]
+        deps = [
+          ":copy_libraries",
+        ]
+        source = "../third_party/pkg/tflite_native/lib/src/blobs"
+        dest = "$root_out_dir/dart-sdk/bin/snapshots"
+        ignore_patterns = "{}"
+      }
+   ]
+}
+
+# This generates targets for everything in copy_tree_specs. The targets have the
+# same name as the "target" fields in the scopes of copy_tree_specs.
+copy_trees("copy_trees") {
+  sources = copy_tree_specs
+}
+
+# Copies the Dart VM binary into bin/
+if (target_os != current_os && target_os == "fuchsia") {
+  # In the Fuchsia build, this has to use a symlink for two reasons.
+  # First, it makes the lookup of shared libraries relative to $ORIGIN
+  # (Linux) or @loader_path (macOS) find the libraries where they are,
+  # since those lookups use the directory of the symlink target rather
+  # than of the link itself (as they would for a copy or hard link).
+  # Second, when the dart binary is built as a "variant" (e.g. with a
+  # sanitizer), then $root_out_dir/dart is itself a symlink to the real
+  # binary in the selected variant toolchain's $root_out_dir and since
+  # the "copy" tool is actually a hard link rather than a copy, it will
+  # make a link to the symlink rather than the symlink's target, and the
+  # relative symlink interpreted from a different containing directory
+  # will not find the actual binary.
+  action("copy_dart") {
+    visibility = [ ":create_common_sdk" ]
+    dart_label = "../runtime/bin:dart"
+    deps = [
+      dart_label,
+    ]
+    dart_out = get_label_info(dart_label, "root_out_dir")
+    sources = [
+      "$dart_out/$dart_stripped_binary",
+    ]
+    outputs = [
+      "$root_out_dir/dart-sdk/bin/$dart_stripped_binary",
+    ]
+    script = "/bin/ln"
+    args = [
+      "-snf",
+      rebase_path(sources[0], get_path_info(outputs[0], "dir")),
+      rebase_path(outputs[0]),
+    ]
+  }
+} else {
+  copy("copy_dart") {
+    visibility = [ ":create_common_sdk" ]
+    deps = [
+      "../runtime/bin:dart",
+    ]
+    dart_out = get_label_info("../runtime/bin:dart", "root_out_dir")
+    if (is_win) {
+      sources = [
+        "$dart_out/dart.exe",
+      ]
+    } else {
+      sources = [
+        "$dart_out/$dart_stripped_binary",
+      ]
+    }
+    if (is_win) {
+      sources += [ "$dart_out/dart.lib" ]
+    }
+    outputs = [
+      "$root_out_dir/dart-sdk/bin/{{source_file_part}}",
+    ]
+  }
+}
+
+copy("copy_dartaotruntime") {
+  deps = [
+    "../runtime/bin:dartaotruntime",
+  ]
+  dartaotruntime_out = get_label_info("../runtime/bin:dartaotruntime", "root_out_dir")
+  if (is_win) {
+    sources = [
+      "$dartaotruntime_out/dartaotruntime.exe",
+    ]
+  } else {
+    sources = [
+      "$dartaotruntime_out/$dartaotruntime_stripped_binary",
+    ]
+  }
+  if (is_win) {
+    sources += [ "$dartaotruntime_out/dartaotruntime.lib" ]
+  }
+  outputs = [
+    "$root_out_dir/dart-sdk/bin/{{source_file_part}}",
+  ]
+}
+
+copy("copy_gen_snapshot") {
+  deps = [
+    "../runtime/bin:gen_snapshot",
+  ]
+  gen_snapshot_out = get_label_info("../runtime/bin:gen_snapshot", "root_out_dir")
+  if (is_win) {
+    sources = [
+      "$gen_snapshot_out/gen_snapshot.exe",
+    ]
+  } else {
+    sources = [
+      "$gen_snapshot_out/$gen_snapshot_stripped_binary",
+    ]
+  }
+  outputs = [
+    "$root_out_dir/dart-sdk/bin/utils/{{source_file_part}}",
+  ]
+}
+
+copy("copy_dart2aot") {
+  ext = ""
+  if (is_win) {
+    ext = ".bat"
+  }
+  sources = [
+    "bin/dart2aot$ext",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/bin/{{source_file_part}}",
+  ]
+}
+
+copy("copy_dart2native") {
+  deps = [
+    ":copy_gen_kernel_snapshot",
+    ":copy_gen_snapshot",
+  ]
+  ext = ""
+  if (is_win) {
+    ext = ".bat"
+  }
+  sources = [
+    "bin/dart2native$ext",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/bin/{{source_file_part}}",
+  ]
+}
+
+copy("copy_gen_kernel_snapshot") {
+  deps = [
+    "../utils/gen_kernel",
+  ]
+  sources = [
+    "$root_gen_dir/gen_kernel.dart.snapshot",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/bin/snapshots/{{source_file_part}}",
+  ]
+}
+
+# A template for copying the things in _platform_sdk_scripts and
+# _full_sdk_scripts into bin/
+template("copy_sdk_script") {
+  assert(defined(invoker.name), "copy_sdk_script must define 'name'")
+  name = invoker.name
+  ext = ""
+  if (is_win) {
+    ext = ".bat"
+  }
+  copy(target_name) {
+    visibility = [
+      ":copy_platform_sdk_scripts",
+      ":copy_full_sdk_scripts",
+    ]
+    sources = [
+      "bin/${name}_sdk$ext",
+    ]
+    outputs = [
+      "$root_out_dir/dart-sdk/bin/$name$ext",
+    ]
+  }
+}
+
+foreach(sdk_script, _full_sdk_scripts) {
+  copy_sdk_script("copy_${sdk_script}_script") {
+    name = sdk_script
+  }
+}
+
+foreach(script, _scripts) {
+  copy("copy_${script}_script") {
+    visibility = [
+      ":copy_platform_sdk_scripts",
+      ":copy_full_sdk_scripts",
+    ]
+    ext = ""
+    if (is_win) {
+      ext = ".bat"
+    }
+    sources = [
+      "bin/$script$ext",
+    ]
+    outputs = [
+      "$root_out_dir/dart-sdk/bin/{{source_file_part}}",
+    ]
+  }
+}
+
+# This is the main target for copying scripts in _platform_sdk_scripts to bin/
+group("copy_platform_sdk_scripts") {
+  visibility = [ ":create_platform_sdk" ]
+  public_deps = []
+  foreach(sdk_script, _platform_sdk_scripts) {
+    public_deps += [ ":copy_${sdk_script}_script" ]
+  }
+  foreach(script, _scripts) {
+    public_deps += [ ":copy_${script}_script" ]
+  }
+}
+
+# This is the main target for copying scripts in _full_sdk_scripts to bin/
+group("copy_full_sdk_scripts") {
+  visibility = [ ":create_full_sdk" ]
+  public_deps = []
+  foreach(sdk_script, _full_sdk_scripts) {
+    public_deps += [ ":copy_${sdk_script}_script" ]
+  }
+  foreach(script, _scripts) {
+    public_deps += [ ":copy_${script}_script" ]
+  }
+}
+
+# This loop generates "copy" targets that put snapshots into bin/snapshots
+foreach(snapshot, _full_sdk_snapshots) {
+  copy("copy_${snapshot[0]}_snapshot") {
+    visibility = [
+      ":copy_platform_sdk_snapshots",
+      ":copy_full_sdk_snapshots",
+    ]
+    deps = [
+      snapshot[1],
+    ]
+    sources = [
+      "$root_gen_dir/${snapshot[0]}.dart.snapshot",
+    ]
+    outputs = [
+      "$root_out_dir/dart-sdk/bin/snapshots/{{source_file_part}}",
+    ]
+  }
+}
+
+# This is the main rule for copying snapshots from _platform_sdk_snapshots to
+# bin/snapshots
+group("copy_platform_sdk_snapshots") {
+  visibility = [ ":create_platform_sdk" ]
+  public_deps = []
+  foreach(snapshot, _platform_sdk_snapshots) {
+    public_deps += [ ":copy_${snapshot[0]}_snapshot" ]
+  }
+}
+
+# This is the main rule for copying snapshots from _full_sdk_snapshots to
+# bin/snapshots
+group("copy_full_sdk_snapshots") {
+  visibility = [ ":create_full_sdk" ]
+  public_deps = []
+  foreach(snapshot, _full_sdk_snapshots) {
+    public_deps += [ ":copy_${snapshot[0]}_snapshot" ]
+  }
+}
+
+# This rule writes the .packages file for dartdoc resources.
+write_file("$root_out_dir/dart-sdk/bin/resources/dartdoc/.packages",
+           "dartdoc:.")
+
+# This is the main rule for copying the files that dartdoc needs.
+group("copy_dartdoc_files") {
+  visibility = [ ":create_common_sdk" ]
+  public_deps = [
+    ":copy_dartdoc_resources",
+    ":copy_dartdoc_templates",
+  ]
+}
+
+# This rule copies analyzer summaries to lib/_internal
+copy("copy_analysis_summaries") {
+  visibility = [ ":create_common_sdk" ]
+  deps = [
+    ":copy_libraries",
+    "../utils/dartanalyzer:generate_summary_strong",
+  ]
+  sources = [
+    "$root_gen_dir/strong.sum",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}",
+  ]
+}
+
+# This rule copies dill files to lib/_internal.
+copy("copy_vm_dill_files") {
+  visibility = [ ":create_common_sdk" ]
+  deps = [
+    ":copy_libraries",
+    "../runtime/vm:kernel_platform_files",
+  ]
+  sources = [
+    "$root_out_dir/vm_platform_strong.dill",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}",
+  ]
+}
+
+copy("copy_abi_dill_files") {
+  visibility = [ ":create_sdk_with_abi_versions" ]
+  sources = [
+    "../tools/abiversions",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/lib/_internal/abiversions",
+  ]
+}
+
+copy("copy_dart2js_dill_files") {
+  visibility = [ ":create_full_sdk" ]
+  deps = [
+    ":copy_libraries",
+    "../utils/compiler:compile_dart2js_platform",
+    "../utils/compiler:compile_dart2js_server_platform",
+  ]
+  sources = [
+    "$root_out_dir/dart2js_platform.dill",
+    "$root_out_dir/dart2js_server_platform.dill",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}",
+  ]
+}
+
+# This rule copies ddc summaries to lib/_internal
+copy("copy_dev_compiler_summary") {
+  visibility = [ ":copy_dev_compiler_sdk" ]
+  deps = [
+    ":copy_libraries",
+    "../utils/dartdevc:dartdevc_sdk",
+    "../utils/dartdevc:dartdevc_kernel_sdk_outline",
+  ]
+  gen_dir = get_label_info("../utils/dartdevc:dartdevc_sdk", "target_gen_dir")
+  sources = [
+    # TODO(vsm): Remove post CFE.
+    "$gen_dir/ddc_sdk.sum",
+    "$gen_dir/kernel/ddc_sdk.dill",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}",
+  ]
+}
+
+# TODO(vsm): Remove the old non-CFE versions of the SDK once we've completed
+# DDC to Kernel (DDK) migration.
+
+# This rule copies DDC's JS SDK and require.js to lib/dev_compiler/amd.
+copy("copy_dev_compiler_js_amd") {
+  visibility = [ ":copy_dev_compiler_js" ]
+  deps = [
+    "../utils/dartdevc:dartdevc_sdk",
+  ]
+  gen_dir = get_label_info("../utils/dartdevc:dartdevc_sdk", "target_gen_dir")
+  sources = [
+    "$gen_dir/js/amd/dart_sdk.js",
+    "$gen_dir/js/amd/dart_sdk.js.map",
+    "../third_party/requirejs/require.js",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/lib/dev_compiler/amd/{{source_file_part}}",
+  ]
+}
+
+# This rule copies DDC's JS SDK and run.js to lib/dev_compiler/common.
+copy("copy_dev_compiler_js_common") {
+  visibility = [ ":copy_dev_compiler_js" ]
+  deps = [
+    "../utils/dartdevc:dartdevc_sdk",
+  ]
+  gen_dir = get_label_info("../utils/dartdevc:dartdevc_sdk", "target_gen_dir")
+  sources = [
+    "$gen_dir/js/common/dart_sdk.js",
+    "$gen_dir/js/common/dart_sdk.js.map",
+    "../pkg/dev_compiler/lib/js/common/run.js",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/lib/dev_compiler/common/{{source_file_part}}",
+  ]
+}
+
+# This rule copies DDC's JS SDK to lib/dev_compiler/es6.
+copy("copy_dev_compiler_js_es6") {
+  visibility = [ ":copy_dev_compiler_js" ]
+  deps = [
+    "../utils/dartdevc:dartdevc_sdk",
+  ]
+  gen_dir = get_label_info("../utils/dartdevc:dartdevc_sdk", "target_gen_dir")
+  sources = [
+    "$gen_dir/js/es6/dart_sdk.js",
+    "$gen_dir/js/es6/dart_sdk.js.map",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/lib/dev_compiler/es6/{{source_file_part}}",
+  ]
+}
+
+# This rule copies DDK's JS SDK and require.js to lib/dev_compiler/kernel/amd.
+copy("copy_dev_compiler_js_amd_kernel") {
+  visibility = [ ":copy_dev_compiler_js" ]
+  deps = [
+    "../utils/dartdevc:dartdevc_kernel_sdk",
+  ]
+  gen_dir = get_label_info("../utils/dartdevc:dartdevc_kernel_sdk",
+                           "target_gen_dir")
+  sources = [
+    "$gen_dir/kernel/amd/dart_sdk.js",
+    "$gen_dir/kernel/amd/dart_sdk.js.map",
+    "../third_party/requirejs/require.js",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/lib/dev_compiler/kernel/amd/{{source_file_part}}",
+  ]
+}
+
+# This rule copies DDK's JS SDK to lib/dev_compiler/kernel/common.
+copy("copy_dev_compiler_js_common_kernel") {
+  visibility = [ ":copy_dev_compiler_js" ]
+  deps = [
+    "../utils/dartdevc:dartdevc_kernel_sdk",
+  ]
+  gen_dir = get_label_info("../utils/dartdevc:dartdevc_kernel_sdk",
+                           "target_gen_dir")
+  sources = [
+    "$gen_dir/kernel/common/dart_sdk.js",
+    "$gen_dir/kernel/common/dart_sdk.js.map",
+    "../pkg/dev_compiler/lib/js/common/run.js",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/lib/dev_compiler/kernel/common/{{source_file_part}}",
+  ]
+}
+
+# This rule copies DDK's JS SDK to lib/dev_compiler/kernel/es6.
+copy("copy_dev_compiler_js_es6_kernel") {
+  visibility = [ ":copy_dev_compiler_js" ]
+  deps = [
+    "../utils/dartdevc:dartdevc_kernel_sdk",
+  ]
+  gen_dir = get_label_info("../utils/dartdevc:dartdevc_kernel_sdk",
+                           "target_gen_dir")
+  sources = [
+    "$gen_dir/kernel/es6/dart_sdk.js",
+    "$gen_dir/kernel/es6/dart_sdk.js.map",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/lib/dev_compiler/kernel/es6/{{source_file_part}}",
+  ]
+}
+
+# Copies all of the JS artifacts needed by DDC.
+group("copy_dev_compiler_js") {
+  visibility = [
+    ":copy_dev_compiler_sdk",
+    ":copy_dev_compiler_tools",
+  ]
+  public_deps = [
+    ":copy_dev_compiler_js_amd",
+    ":copy_dev_compiler_js_amd_kernel",
+    ":copy_dev_compiler_js_common",
+    ":copy_dev_compiler_js_common_kernel",
+    ":copy_dev_compiler_js_es6",
+    ":copy_dev_compiler_js_es6_kernel",
+  ]
+}
+
+# This rule copies tools to go along with ddc.
+copy("copy_dev_compiler_tools") {
+  visibility = [ ":copy_dev_compiler_sdk" ]
+  deps = [
+    ":copy_dev_compiler_js",
+    "../utils/dartdevc:dartdevc_web",
+    "../utils/dartdevc:stack_trace_mapper",
+  ]
+  dart_out = get_label_info("../utils/dartdevc:dartdevc_web", "root_out_dir")
+  sources = [
+    "$dart_out/dev_compiler/build/web/dart_stack_trace_mapper.js",
+    "$dart_out/dev_compiler/build/web/ddc_web_compiler.js",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/lib/dev_compiler/web/{{source_file_part}}",
+  ]
+}
+
+# This is the main rule for copying ddc's dependencies to lib/
+group("copy_dev_compiler_sdk") {
+  visibility = [ ":create_full_sdk" ]
+  public_deps = [
+    ":copy_dev_compiler_js",
+    ":copy_dev_compiler_summary",
+    ":copy_dev_compiler_tools",
+  ]
+}
+
+# This rule copies header files to include/
+copy("copy_headers") {
+  visibility = [ ":create_common_sdk" ]
+  sources = [
+    "../runtime/include/dart_api.h",
+    "../runtime/include/dart_native_api.h",
+    "../runtime/include/dart_tools_api.h",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/include/{{source_file_part}}",
+  ]
+}
+
+# This rule copies libraries.json files to lib/
+copy("copy_libraries_specification") {
+  visibility = [ ":create_common_sdk" ]
+  sources = [
+    "lib/libraries.json",
+  ]
+  deps = [
+    ":copy_libraries",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/lib/{{source_file_part}}",
+  ]
+}
+
+# This is the main rule to copy libraries in _platform_sdk_libraries to lib/
+group("copy_platform_sdk_libraries") {
+  visibility = [
+    ":create_platform_sdk",
+    ":copy_libraries",
+  ]
+  public_deps = []
+  foreach(library, _platform_sdk_libraries) {
+    public_deps += [ ":copy_${library}_library" ]
+  }
+}
+
+# This is the main rule to copy libraries in _full_sdk_libraries to lib/
+group("copy_full_sdk_libraries") {
+  visibility = [
+    ":create_full_sdk",
+    ":copy_libraries",
+  ]
+  public_deps = []
+  foreach(library, _full_sdk_libraries) {
+    public_deps += [ ":copy_${library}_library" ]
+  }
+}
+
+group("copy_libraries") {
+  if (dart_platform_sdk) {
+    public_deps = [
+      ":copy_platform_sdk_libraries",
+    ]
+  } else {
+    public_deps = [
+      ":copy_full_sdk_libraries",
+    ]
+  }
+}
+
+# This rule writes the version file.
+action("write_version_file") {
+  visibility = [ ":create_common_sdk" ]
+  inputs = [
+    "../tools/VERSION",
+    "../.git/logs/HEAD",
+  ]
+  output = "$root_out_dir/dart-sdk/version"
+  outputs = [
+    output,
+  ]
+  script = "../tools/write_version_file.py"
+  args = [
+    "--output",
+    rebase_path(output),
+  ]
+}
+
+# This rule writes the revision file.
+action("write_revision_file") {
+  visibility = [ ":create_common_sdk" ]
+  inputs = [
+    "../.git/logs/HEAD",
+  ]
+  output = "$root_out_dir/dart-sdk/revision"
+  outputs = [
+    output,
+  ]
+  script = "../tools/write_revision_file.py"
+  args = [
+    "--output",
+    rebase_path(output),
+  ]
+}
+
+# Copy libraries.dart to lib/_internal/libraries.dart for backwards
+# compatibility.
+#
+# TODO(sigmund): stop copying libraries.dart. Old versions (<=0.25.1-alpha.4)
+# of the analyzer package do not support the new location of this file. We
+# should be able to remove the old file once we release a newer version of
+# analyzer and popular frameworks have migrated to use it.
+copy("copy_libraries_dart") {
+  visibility = [ ":create_common_sdk" ]
+  deps = [
+    ":copy_libraries",
+  ]
+  sources = [
+    "lib/_internal/sdk_library_metadata/lib/libraries.dart",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}",
+  ]
+}
+
+# This rule copies the README file.
+copy("copy_readme") {
+  visibility = [ ":create_common_sdk" ]
+  sources = [
+    "../README.dart-sdk",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/README",
+  ]
+}
+
+# This rule copies the LICENSE file.
+copy("copy_license") {
+  visibility = [ ":create_common_sdk" ]
+  sources = [
+    "../LICENSE",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/LICENSE",
+  ]
+}
+
+# This rule generates a custom dartdoc_options.yaml file.
+action("write_dartdoc_options") {
+  visibility = [ ":create_common_sdk" ]
+  inputs = [
+    "../.git/logs/HEAD",
+  ]
+  output = "$root_out_dir/dart-sdk/dartdoc_options.yaml"
+  outputs = [
+    output,
+  ]
+  script = "../tools/write_dartdoc_options_file.py"
+  args = [
+    "--output",
+    rebase_path(output),
+  ]
+}
+
+# This rule copies the API readme file to lib/
+copy("copy_api_readme") {
+  visibility = [ ":create_common_sdk" ]
+  sources = [
+    "api_readme.md",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/lib/api_readme.md",
+  ]
+}
+
+# Parts common to both platform and full SDKs.
+group("create_common_sdk") {
+  visibility = [ ":create_sdk" ]
+  public_deps = [
+    ":copy_analysis_summaries",
+    ":copy_api_readme",
+    ":copy_dart",
+    ":copy_dart2native",
+    ":copy_dartdoc_files",
+    ":copy_headers",
+    ":copy_libraries_dart",
+    ":copy_license",
+    ":copy_libraries_specification",
+    ":copy_readme",
+    ":copy_vm_dill_files",
+    ":write_dartdoc_options",
+    ":write_revision_file",
+    ":write_version_file",
+  ]
+  if (is_win) {
+    public_deps += [ ":copy_7zip" ]
+  }
+  if (target_cpu == "x64") {
+    public_deps += [
+      ":copy_language_model",
+      ":copy_libtensorflowlite_c",
+    ]
+  }
+}
+
+# Parts specific to the platform SDK.
+group("create_platform_sdk") {
+  visibility = [ ":create_sdk" ]
+  public_deps = [
+    ":copy_platform_sdk_libraries",
+    ":copy_platform_sdk_scripts",
+    ":copy_platform_sdk_snapshots",
+  ]
+}
+
+# Parts specific to the full SDK.
+group("create_full_sdk") {
+  visibility = [ ":create_sdk" ]
+
+  public_deps = [
+    ":copy_dart2js_dill_files",
+    ":copy_dev_compiler_sdk",
+    ":copy_full_sdk_libraries",
+    ":copy_full_sdk_scripts",
+    ":copy_full_sdk_snapshots",
+  ]
+}
+
+# The main target to depend on from ../BUILD.gn
+group("create_sdk") {
+  public_deps = [
+    ":create_common_sdk",
+  ]
+  if (dart_platform_sdk) {
+    public_deps += [ ":create_platform_sdk" ]
+  } else {
+    public_deps += [ ":create_full_sdk" ]
+  }
+}
+
+# Same as create_sdk, but with abi version files.
+group("create_sdk_with_abi_versions") {
+  public_deps = [
+    ":copy_abi_dill_files",
+    ":create_sdk",
+  ]
+}
diff --git a/sdk_nnbd/api_readme.md b/sdk_nnbd/api_readme.md
new file mode 100644
index 0000000..2f51f7e
--- /dev/null
+++ b/sdk_nnbd/api_readme.md
@@ -0,0 +1,32 @@
+Welcome to the Dart API reference documentation, covering the core Dart API
+libraries. Some of the most fundamental Dart libraries include:
+   
+  * [dart:core](dart-core/dart-core-library.html): Core functionality such as
+    strings, numbers, collections, errors, dates, and URIs.
+  * [dart:html](dart-html/dart-html-library.html): DOM manipulation for web apps
+    (available only to web apps).
+  * [dart:io](dart-io/dart-io-library.html): I/O for non-web apps.
+  
+Except for `dart:core`, you must import a library before you can use it. Here's
+an example of importing `dart:async` and `dart:math`:
+
+```dart
+import 'dart:async';
+import 'dart:math';
+```
+
+You can install more libraries using the
+[pub package manager](https://dart.dev/guides/packages).
+  
+The main site for learning and using Dart is
+[dart.dev](https://dart.dev). Check out these pages:
+  
+  * [Platforms](https://dart.dev/platforms)
+  * [Language tour](https://dart.dev/guides/language/language-tour)
+  * [Library tour](https://dart.dev/guides/libraries/library-tour)
+  * [Sample code](https://dart.dev/samples)
+  
+This API reference is automatically generated from source code in the [Dart
+SDK project](https://github.com/dart-lang/sdk).
+If you'd like to give feedback or edit this documentation, see
+[Contributing](https://github.com/dart-lang/sdk/wiki/Contributing).
diff --git a/sdk_nnbd/bin/dart b/sdk_nnbd/bin/dart
new file mode 100755
index 0000000..f50184b
--- /dev/null
+++ b/sdk_nnbd/bin/dart
@@ -0,0 +1,57 @@
+#!/usr/bin/env 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.
+
+function follow_links() {
+  file="$1"
+  while [ -h "$file" ]; do
+    # On Mac OS, readlink -f doesn't work.
+    file="$(readlink "$file")"
+  done
+  echo "$file"
+}
+
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Handle the case where dart-sdk/bin has been symlinked to.
+CUR_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
+
+if [[ `uname` == 'Darwin' ]];
+then
+  OUT_DIR="$CUR_DIR"/../../xcodebuild/
+else
+  OUT_DIR="$CUR_DIR"/../../out/
+fi
+
+if [ -z "$DART_CONFIGURATION" ];
+then
+  DIRS=$( ls "$OUT_DIR" )
+  # list of possible configurations in decreasing desirability
+  CONFIGS=("ReleaseX64" "ReleaseIA32" "DebugX64" "DebugIA32"
+    "ReleaseARM"    "ReleaseARM64"    "ReleaseARMV5TE"
+    "DebugARM"      "DebugARM64"      "DebugARMV5TE")
+  DART_CONFIGURATION="None"
+  for CONFIG in ${CONFIGS[*]}
+  do
+    for DIR in $DIRS;
+    do
+      if [ "$CONFIG" = "$DIR" ];
+      then
+        # choose most desirable configuration that is available and break
+        DART_CONFIGURATION="$DIR"
+        break 2
+      fi
+    done
+  done
+  if [ "$DART_CONFIGURATION" = "None" ]
+  then
+    echo "No valid dart configuration found in $OUT_DIR"
+    exit 1
+  fi
+fi
+
+BIN_DIR="$OUT_DIR$DART_CONFIGURATION"
+
+exec "$BIN_DIR"/dart "$@"
diff --git a/sdk_nnbd/bin/dart.bat b/sdk_nnbd/bin/dart.bat
new file mode 100644
index 0000000..a6a24de
--- /dev/null
+++ b/sdk_nnbd/bin/dart.bat
@@ -0,0 +1,16 @@
+@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.
+
+set SCRIPTPATH=%~dp0
+
+REM Does the path have a trailing slash? If so, remove it.
+if %SCRIPTPATH:~-1%== set SCRIPTPATH=%SCRIPTPATH:~0,-1%
+
+REM DART_CONFIGURATION defaults to ReleaseX64
+if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseX64
+
+set arguments=%*
+
+"%SCRIPTPATH%\..\..\out\%DART_CONFIGURATION%\dart.exe" %arguments%
diff --git a/sdk_nnbd/bin/dart2aot b/sdk_nnbd/bin/dart2aot
new file mode 100755
index 0000000..9390db6
--- /dev/null
+++ b/sdk_nnbd/bin/dart2aot
@@ -0,0 +1,111 @@
+#!/usr/bin/env bash
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Script for generating AOT snapshot in two steps:
+# - Compilation to kernel with additional AOT specific transformations.
+# - Compilation of kernel into snapshot using gen_snapshot.
+
+# Parse incoming arguments and extract the value of --packages option if any
+# was passed. Split options (--xyz) and non-options into two separate arrays.
+# All options will be passed to gen_snapshot, while --packages will be
+# passed to the CFE (Common Front-End).
+
+set -e
+
+OPTIONS=()
+GEN_KERNEL_OPTIONS=()
+PACKAGES=
+BUILD_ELF=0
+
+ARGV=()
+for arg in "$@"; do
+  case $arg in
+    --packages=*)
+    PACKAGES="$arg"
+    ;;
+    --enable-asserts)
+    GEN_KERNEL_OPTIONS+=("$arg")
+    OPTIONS+=("$arg")
+    ;;
+    --tfa | \
+    --no-tfa | \
+    -D* )
+    GEN_KERNEL_OPTIONS+=("$arg")
+    ;;
+    --build-elf)
+    BUILD_ELF=1
+    ;;
+    --*)
+    OPTIONS+=("$arg")
+    ;;
+    *)
+    ARGV+=("$arg")
+    ;;
+  esac
+done
+
+if [ "${#ARGV[@]}" -ne 2 ]; then
+    echo "Usage: $0 [options] <dart-source-file> <dart-aot-file>"
+    echo ""
+    echo "Dart AOT (ahead-of-time) compile Dart source code into native machine code."
+    exit 1
+fi
+
+SOURCE_FILE="${ARGV[0]}"
+SNAPSHOT_FILE="${ARGV[1]}"
+
+if [ $BUILD_ELF -eq 1 ]; then
+  GEN_SNAPSHOT_OPTION="--snapshot-kind=app-aot-assembly"
+  GEN_SNAPSHOT_FILENAME="--assembly=${SNAPSHOT_FILE}.S"
+else
+  GEN_SNAPSHOT_OPTION="--snapshot-kind=app-aot-blobs"
+  GEN_SNAPSHOT_FILENAME="--blobs_container_filename=${SNAPSHOT_FILE}"
+fi
+
+function follow_links() {
+  file="$1"
+  while [ -h "$file" ]; do
+    # On Mac OS, readlink -f doesn't work.
+    file="$(readlink "$file")"
+  done
+  echo "$file"
+}
+
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Handle the case where dart-sdk/bin has been symlinked to.
+BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
+
+SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)"
+
+DART="$BIN_DIR/dart"
+GEN_SNAPSHOT="$BIN_DIR/utils/gen_snapshot"
+
+SNAPSHOT_DIR="$BIN_DIR/snapshots"
+SNAPSHOT="$SNAPSHOT_DIR/gen_kernel.dart.snapshot"
+
+# Step 1: Generate Kernel binary from the input Dart source.
+"$DART"                                                                        \
+     "${SNAPSHOT}"                                                             \
+     --platform "${SDK_DIR}/lib/_internal/vm_platform_strong.dill"             \
+     --aot                                                                     \
+     -Ddart.vm.product=true                                                    \
+     "${GEN_KERNEL_OPTIONS[@]}"                                                \
+     $PACKAGES                                                                 \
+     -o "$SNAPSHOT_FILE.dill"                                                  \
+     "$SOURCE_FILE"
+
+# Step 2: Generate snapshot from the Kernel binary.
+"$GEN_SNAPSHOT"                                                                \
+     "$GEN_SNAPSHOT_OPTION"                                                    \
+     "$GEN_SNAPSHOT_FILENAME"                                                  \
+     "${OPTIONS[@]}"                                                           \
+     "$SNAPSHOT_FILE.dill"
+
+# Step 3: Assemble the assembly file into an ELF object.
+if [ $BUILD_ELF -eq 1 ]; then
+    gcc -shared -o "$SNAPSHOT_FILE" "${SNAPSHOT_FILE}.S"
+fi
diff --git a/sdk_nnbd/bin/dart2aot.bat b/sdk_nnbd/bin/dart2aot.bat
new file mode 100644
index 0000000..321e867
--- /dev/null
+++ b/sdk_nnbd/bin/dart2aot.bat
@@ -0,0 +1,58 @@
+@echo off
+REM Copyright (c) 2019, 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%
+
+rem Get absolute full name for DART_ROOT.
+for %%i in ("%SDK_DIR%\..\") do set DART_ROOT=%%~fi
+
+rem Remove trailing backslash if there is one
+if %DART_ROOT:~-1%==\ set DART_ROOT=%DART_ROOT:~0,-1%
+
+set DART=%BIN_DIR%\dart.exe
+set GEN_KERNEL=%BIN_DIR%\snapshots\gen_kernel.dart.snapshot
+set VM_PLATFORM_STRONG=%SDK_DIR%\lib\_internal\vm_platform_strong.dill
+set GEN_SNAPSHOT=%BIN_DIR%\utils\gen_snapshot.exe
+
+set SOURCE_FILE=%1
+set SNAPSHOT_FILE=%2
+set GEN_SNAPSHOT_OPTION=--snapshot-kind=app-aot-blobs
+set GEN_SNAPSHOT_FILENAME=--blobs_container_filename=%SNAPSHOT_FILE%
+
+REM Step 1: Generate Kernel binary from the input Dart source.
+%DART% %GEN_KERNEL% --platform %VM_PLATFORM_STRONG% --aot -Ddart.vm.product=true -o %SNAPSHOT_FILE%.dill %SOURCE_FILE%
+
+REM Step 2: Generate snapshot from the Kernel binary.
+%GEN_SNAPSHOT% %GEN_SNAPSHOT_OPTION% %GEN_SNAPSHOT_FILENAME% %SNAPSHOT_FILE%.dill
+
+endlocal
+
+exit /b %errorlevel%
+
+:follow_links
+setlocal
+for %%i in (%1) do set result=%%~fi
+set current=
+for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
+                                             ^| %SystemRoot%\System32\find.exe ">     %~n1 [" 2^>nul`) do (
+  set current=%%i
+)
+if not "%current%"=="" call :follow_links "%current%", result
+endlocal & set %~2=%result%
+goto :eof
+
+:end
diff --git a/sdk_nnbd/bin/dart2js b/sdk_nnbd/bin/dart2js
new file mode 100755
index 0000000..cfc91b1
--- /dev/null
+++ b/sdk_nnbd/bin/dart2js
@@ -0,0 +1,55 @@
+#!/usr/bin/env 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.
+
+function follow_links() {
+  file="$1"
+  while [ -h "$file" ]; do
+    # On Mac OS, readlink -f doesn't work.
+    file="$(readlink "$file")"
+  done
+  echo "$file"
+}
+
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Handle the case where dart-sdk/bin has been symlinked to.
+BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
+
+SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)"
+
+DART="$BIN_DIR/dart"
+
+unset EXTRA_OPTIONS
+declare -a EXTRA_OPTIONS
+
+if test -t 1; then
+  # Stdout is a terminal.
+  if test 8 -le `tput colors`; then
+    # Stdout has at least 8 colors, so enable colors.
+    EXTRA_OPTIONS+=('--enable-diagnostic-colors')
+  fi
+fi
+
+unset EXTRA_VM_OPTIONS
+declare -a EXTRA_VM_OPTIONS
+
+case $0 in
+  *_developer)
+    EXTRA_VM_OPTIONS+=('--enable-asserts')
+    ;;
+esac
+
+# We allow extra vm options to be passed in through an environment variable.
+if [[ $DART_VM_OPTIONS ]]; then
+  read -a OPTIONS <<< "$DART_VM_OPTIONS"
+  EXTRA_VM_OPTIONS+=("${OPTIONS[@]}")
+fi
+
+DART_ROOT="$(cd "${SDK_DIR}/.." ; pwd -P)"
+
+DART2JS="package:compiler/src/dart2js.dart"
+
+exec "$DART" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$DART2JS" "${EXTRA_OPTIONS[@]}" "$@"
diff --git a/sdk_nnbd/bin/dart2js.bat b/sdk_nnbd/bin/dart2js.bat
new file mode 100644
index 0000000..9341ad8
--- /dev/null
+++ b/sdk_nnbd/bin/dart2js.bat
@@ -0,0 +1,60 @@
+@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 DART=%BIN_DIR%\dart
+
+set EXTRA_OPTIONS=
+set EXTRA_VM_OPTIONS=
+
+if _%DART2JS_DEVELOPER_MODE%_ == _1_ (
+  set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% --enable-asserts
+)
+
+rem We allow extra vm options to be passed in through an environment variable.
+if not "_%DART_VM_OPTIONS%_" == "__" (
+  set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% %DART_VM_OPTIONS%
+)
+
+rem Get absolute full name for DART_ROOT.
+for %%i in ("%SDK_DIR%\..\") do set DART_ROOT=%%~fi
+
+rem Remove trailing backslash if there is one
+if %DART_ROOT:~-1%==\ set DART_ROOT=%DART_ROOT:~0,-1%
+
+set DART2JS=%DART_ROOT%\pkg\compiler\lib\src\dart2js.dart
+
+"%DART%" "--packages=%DART_ROOT%\.packages" %EXTRA_VM_OPTIONS% "%DART2JS%" %EXTRA_OPTIONS% %*
+
+endlocal
+
+exit /b %errorlevel%
+
+:follow_links
+setlocal
+for %%i in (%1) do set result=%%~fi
+set current=
+for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
+                                             ^| %SystemRoot%\System32\find.exe ">     %~n1 [" 2^>nul`) do (
+  set current=%%i
+)
+if not "%current%"=="" call :follow_links "%current%", result
+endlocal & set %~2=%result%
+goto :eof
+
+:end
diff --git a/sdk_nnbd/bin/dart2js_developer b/sdk_nnbd/bin/dart2js_developer
new file mode 100755
index 0000000..226d1a9
--- /dev/null
+++ b/sdk_nnbd/bin/dart2js_developer
@@ -0,0 +1,6 @@
+#!/usr/bin/env 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.
+
+. ${BASH_SOURCE%_developer}
diff --git a/sdk_nnbd/bin/dart2js_developer.bat b/sdk_nnbd/bin/dart2js_developer.bat
new file mode 100644
index 0000000..c4a2959
--- /dev/null
+++ b/sdk_nnbd/bin/dart2js_developer.bat
@@ -0,0 +1,10 @@
+@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
+set DART2JS_DEVELOPER_MODE=1
+call "%~dp0dart2js.bat" %*
+endlocal
+exit /b %errorlevel%
diff --git a/sdk_nnbd/bin/dart2js_sdk b/sdk_nnbd/bin/dart2js_sdk
new file mode 100755
index 0000000..e7999b4
--- /dev/null
+++ b/sdk_nnbd/bin/dart2js_sdk
@@ -0,0 +1,58 @@
+#!/usr/bin/env 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.
+
+function follow_links() {
+  file="$1"
+  while [ -h "$file" ]; do
+    # On Mac OS, readlink -f doesn't work.
+    file="$(readlink "$file")"
+  done
+  echo "$file"
+}
+
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Handle the case where dart-sdk/bin has been symlinked to.
+BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
+
+SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)"
+
+DART="$BIN_DIR/dart"
+
+SNAPSHOT_DIR="$BIN_DIR/snapshots"
+SNAPSHOT="$SNAPSHOT_DIR/dart2js.dart.snapshot"
+
+unset EXTRA_OPTIONS
+declare -a EXTRA_OPTIONS
+
+if test -t 1; then
+  # Stdout is a terminal.
+  if test 8 -le `tput colors`; then
+    # Stdout has at least 8 colors, so enable colors.
+    EXTRA_OPTIONS+=('--enable-diagnostic-colors')
+  fi
+fi
+
+unset EXTRA_VM_OPTIONS
+declare -a EXTRA_VM_OPTIONS
+
+if test -f "$SNAPSHOT"; then
+  EXTRA_OPTIONS+=("--libraries-spec=$SDK_DIR/lib/libraries.json")
+fi
+
+case $0 in
+  *_developer)
+    EXTRA_VM_OPTIONS+=('--enable-asserts')
+    ;;
+esac
+
+# We allow extra vm options to be passed in through an environment variable.
+if [[ $DART_VM_OPTIONS ]]; then
+  read -a OPTIONS <<< "$DART_VM_OPTIONS"
+  EXTRA_VM_OPTIONS+=("${OPTIONS[@]}")
+fi
+
+exec "$DART" "${EXTRA_VM_OPTIONS[@]}" "$SNAPSHOT" "${EXTRA_OPTIONS[@]}" "$@"
diff --git a/sdk_nnbd/bin/dart2js_sdk.bat b/sdk_nnbd/bin/dart2js_sdk.bat
new file mode 100755
index 0000000..8485cdc
--- /dev/null
+++ b/sdk_nnbd/bin/dart2js_sdk.bat
@@ -0,0 +1,57 @@
+@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 DART=%BIN_DIR%\dart
+set SNAPSHOT=%BIN_DIR%\snapshots\dart2js.dart.snapshot
+
+set EXTRA_OPTIONS=
+set EXTRA_VM_OPTIONS=
+
+if _%DART2JS_DEVELOPER_MODE%_ == _1_ (
+  set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% --enable-asserts
+)
+
+if exist "%SNAPSHOT%" (
+  set EXTRA_OPTIONS=%EXTRA_OPTIONS% "--libraries-spec=%SDK_DIR%\lib\libraries.json"
+)
+
+rem We allow extra vm options to be passed in through an environment variable.
+if not "_%DART_VM_OPTIONS%_" == "__" (
+  set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% %DART_VM_OPTIONS%
+)
+
+"%DART%" %EXTRA_VM_OPTIONS% "%SNAPSHOT%" %EXTRA_OPTIONS% %*
+
+endlocal
+
+exit /b %errorlevel%
+
+:follow_links
+setlocal
+for %%i in (%1) do set result=%%~fi
+set current=
+for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
+                                             ^| find ">     %~n1 [" 2^>nul`) do (
+  set current=%%i
+)
+if not "%current%"=="" call :follow_links "%current%", result
+endlocal & set %~2=%result%
+goto :eof
+
+:end
diff --git a/sdk_nnbd/bin/dart2native b/sdk_nnbd/bin/dart2native
new file mode 100755
index 0000000..29f29d7
--- /dev/null
+++ b/sdk_nnbd/bin/dart2native
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for 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 dart2native.dart.snapshot on the Dart VM
+
+function follow_links() {
+  file="$1"
+  while [ -h "$file" ]; do
+    # On Mac OS, readlink -f doesn't work.
+    file="$(readlink "$file")"
+  done
+  echo "$file"
+}
+
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Handle the case where dart-sdk/bin has been symlinked to.
+BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
+SNAPSHOTS_DIR="${BIN_DIR}/snapshots"
+DART="$BIN_DIR/dart"
+
+exec "$DART" "${SNAPSHOTS_DIR}/dart2native.dart.snapshot" $*
diff --git a/sdk_nnbd/bin/dart2native.bat b/sdk_nnbd/bin/dart2native.bat
new file mode 100644
index 0000000..631dce8
--- /dev/null
+++ b/sdk_nnbd/bin/dart2native.bat
@@ -0,0 +1,43 @@
+@echo off
+REM Copyright (c) 2019, 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
+
+set DART=%BIN_DIR%\dart
+
+"%DART%" "%BIN_DIR%\snapshots\dart2native.dart.snapshot" %*
+
+endlocal
+
+exit /b %errorlevel%
+
+rem Follow the symbolic links (junctions points) using `dir to determine the
+rem canonical path. Output with a link looks something like this
+rem
+rem 01/03/2013  10:11 PM    <JUNCTION>     abc def
+rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk]
+rem
+rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename
+rem surrounded by right angle bracket and left square bracket. Once we get
+rem the filename, which is name of the link, we recursively follow that.
+:follow_links
+setlocal
+for %%i in (%1) do set result=%%~fi
+set current=
+for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
+                                             ^| %SystemRoot%\System32\find.exe ">     %~n1 [" 2^>nul`) do (
+  set current=%%i
+)
+if not "%current%"=="" call :follow_links "%current%", result
+endlocal & set %~2=%result%
+goto :eof
+
+:end
diff --git a/sdk_nnbd/bin/dartanalyzer b/sdk_nnbd/bin/dartanalyzer
new file mode 100755
index 0000000..7ea062c
--- /dev/null
+++ b/sdk_nnbd/bin/dartanalyzer
@@ -0,0 +1,50 @@
+#!/usr/bin/env 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 a
+# BSD-style license that can be found in the LICENSE file.
+
+# Run dartanalyzer.dart on the Dart VM. This script assumes the Dart repo's
+# directory structure.
+
+function follow_links() {
+  file="$1"
+  while [ -h "$file" ]; do
+    # On Mac OS, readlink -f doesn't work.
+    file="$(readlink "$file")"
+  done
+  echo "$file"
+}
+
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Handle the case where dart-sdk/bin has been symlinked to.
+BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
+SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)"
+
+SDK_ARG="--dart-sdk=$SDK_DIR"
+
+DART="$BIN_DIR/dart"
+
+unset EXTRA_VM_OPTIONS
+declare -a EXTRA_VM_OPTIONS
+
+case $0 in
+  *_developer)
+    EXTRA_VM_OPTIONS+=('--enable-asserts')
+    ;;
+esac
+
+# We allow extra vm options to be passed in through an environment variable.
+if [[ $DART_VM_OPTIONS ]]; then
+  read -a OPTIONS <<< "$DART_VM_OPTIONS"
+  EXTRA_VM_OPTIONS+=("${OPTIONS[@]}")
+fi
+
+DART_ROOT="$(cd "${SDK_DIR}/.." ; pwd -P)"
+
+ANALYZER="$DART_ROOT/pkg/analyzer_cli/bin/analyzer.dart"
+
+DEV_OPTIONS="--use-analysis-driver-memory-byte-store"
+
+exec "$DART" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$ANALYZER" "$DEV_OPTIONS" "$SDK_ARG" "$@"
diff --git a/sdk_nnbd/bin/dartanalyzer.bat b/sdk_nnbd/bin/dartanalyzer.bat
new file mode 100644
index 0000000..efa3a6a
--- /dev/null
+++ b/sdk_nnbd/bin/dartanalyzer.bat
@@ -0,0 +1,70 @@
+@echo off
+REM Copyright (c) 2013, 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
+
+set DART=%BIN_DIR%\dart
+
+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 SDK_ARG=--dart-sdk=%SDK_DIR%
+
+set EXTRA_VM_OPTIONS=
+
+if _%DARTANALYZER_DEVELOPER_MODE%_ == _1_ (
+  set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% --enable_asserts
+)
+
+rem We allow extra vm options to be passed in through an environment variable.
+if not "_%DART_VM_OPTIONS%_" == "__" (
+  set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% %DART_VM_OPTIONS%
+)
+
+rem Get absolute full name for DART_ROOT.
+for %%i in ("%SDK_DIR%\..\") do set DART_ROOT=%%~fi
+
+rem Remove trailing backslash if there is one
+if %DART_ROOT:~-1%==\ set DART_ROOT=%DART_ROOT:~0,-1%
+
+set ANALYZER=%DART_ROOT%\pkg\analyzer_cli\bin\analyzer.dart
+
+"%DART%" "--packages=%DART_ROOT%\.packages" %EXTRA_VM_OPTIONS% "%ANALYZER%" "%SDK_ARG%" %*
+
+endlocal
+
+exit /b %errorlevel%
+
+rem Follow the symbolic links (junctions points) using `dir to determine the
+rem canonical path. Output with a link looks something like this
+rem
+rem 01/03/2013  10:11 PM    <JUNCTION>     abc def
+rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk]
+rem
+rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename
+rem surrounded by right angle bracket and left square bracket. Once we get
+rem the filename, which is name of the link, we recursively follow that.
+:follow_links
+setlocal
+for %%i in (%1) do set result=%%~fi
+set current=
+for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
+                                             ^| %SystemRoot%\System32\find.exe ">     %~n1 [" 2^>nul`) do (
+  set current=%%i
+)
+if not "%current%"=="" call :follow_links "%current%", result
+endlocal & set %~2=%result%
+goto :eof
+
+:end
diff --git a/sdk_nnbd/bin/dartanalyzer_developer b/sdk_nnbd/bin/dartanalyzer_developer
new file mode 100755
index 0000000..373dc67
--- /dev/null
+++ b/sdk_nnbd/bin/dartanalyzer_developer
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+# Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+. ${BASH_SOURCE%_developer}
diff --git a/sdk_nnbd/bin/dartanalyzer_developer.bat b/sdk_nnbd/bin/dartanalyzer_developer.bat
new file mode 100644
index 0000000..b560fe8
--- /dev/null
+++ b/sdk_nnbd/bin/dartanalyzer_developer.bat
@@ -0,0 +1,10 @@
+@echo off
+REM Copyright (c) 2014, 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
+set DARTANALYZER_DEVELOPER_MODE=1
+call "%~dp0dartanalyzer.bat" %*
+endlocal
+exit /b %errorlevel%
diff --git a/sdk_nnbd/bin/dartanalyzer_sdk b/sdk_nnbd/bin/dartanalyzer_sdk
new file mode 100755
index 0000000..28f37ab
--- /dev/null
+++ b/sdk_nnbd/bin/dartanalyzer_sdk
@@ -0,0 +1,31 @@
+#!/usr/bin/env 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 a
+# BSD-style license that can be found in the LICENSE file.
+
+# Run dartanalyzer.dart on the Dart VM. This script assumes the Dart SDK's
+# directory structure.
+
+function follow_links() {
+  file="$1"
+  while [ -h "$file" ]; do
+    # On Mac OS, readlink -f doesn't work.
+    file="$(readlink "$file")"
+  done
+  echo "$file"
+}
+
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Handle the case where dart-sdk/bin has been symlinked to.
+BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
+SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)"
+
+SDK_ARG="--dart-sdk=$SDK_DIR"
+
+SNAPSHOT="$BIN_DIR/snapshots/dartanalyzer.dart.snapshot"
+
+# We are running the snapshot in the built SDK.
+DART="$BIN_DIR/dart"
+exec "$DART" "$SNAPSHOT" "$SDK_ARG" "$@"
diff --git a/sdk_nnbd/bin/dartanalyzer_sdk.bat b/sdk_nnbd/bin/dartanalyzer_sdk.bat
new file mode 100644
index 0000000..ab66885
--- /dev/null
+++ b/sdk_nnbd/bin/dartanalyzer_sdk.bat
@@ -0,0 +1,52 @@
+@echo off
+REM Copyright (c) 2013, 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
+
+set DART=%BIN_DIR%\dart
+set SNAPSHOT=%BIN_DIR%\snapshots\dartanalyzer.dart.snapshot
+
+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 SDK_ARG=--dart-sdk=%SDK_DIR%
+
+"%DART%" "%SNAPSHOT%" "%SDK_ARG%" %*
+
+endlocal
+
+exit /b %errorlevel%
+
+rem Follow the symbolic links (junctions points) using `dir to determine the
+rem canonical path. Output with a link looks something like this
+rem
+rem 01/03/2013  10:11 PM    <JUNCTION>     abc def
+rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk]
+rem
+rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename
+rem surrounded by right angle bracket and left square bracket. Once we get
+rem the filename, which is name of the link, we recursively follow that.
+:follow_links
+setlocal
+for %%i in (%1) do set result=%%~fi
+set current=
+for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
+                                             ^| find ">     %~n1 [" 2^>nul`) do (
+  set current=%%i
+)
+if not "%current%"=="" call :follow_links "%current%", result
+endlocal & set %~2=%result%
+goto :eof
+
+:end
diff --git a/sdk_nnbd/bin/dartdevc b/sdk_nnbd/bin/dartdevc
new file mode 100755
index 0000000..5b75ad2
--- /dev/null
+++ b/sdk_nnbd/bin/dartdevc
@@ -0,0 +1,48 @@
+#!/usr/bin/env 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 a
+# BSD-style license that can be found in the LICENSE file.
+
+# Run dev compiler on the Dart VM. This script assumes the Dart repo's
+# directory structure.
+
+function follow_links() {
+  file="$1"
+  while [ -h "$file" ]; do
+    # On Mac OS, readlink -f doesn't work.
+    file="$(readlink "$file")"
+  done
+  echo "$file"
+}
+
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Handle the case where dart-sdk/bin has been symlinked to.
+BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
+SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)"
+
+SDK_ARG="--dart-sdk=$SDK_DIR"
+
+DART="$BIN_DIR/dart"
+
+unset EXTRA_VM_OPTIONS
+declare -a EXTRA_VM_OPTIONS
+
+case $0 in
+  *_developer)
+    EXTRA_VM_OPTIONS+=('--checked')
+    ;;
+esac
+
+# We allow extra vm options to be passed in through an environment variable.
+if [[ $DART_VM_OPTIONS ]]; then
+  read -a OPTIONS <<< "$DART_VM_OPTIONS"
+  EXTRA_VM_OPTIONS+=("${OPTIONS[@]}")
+fi
+
+DART_ROOT="$(cd "${SDK_DIR}/.." ; pwd -P)"
+
+DEV_COMPILER="$DART_ROOT/pkg/dev_compiler/bin/dartdevc.dart"
+
+exec "$DART" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$DEV_COMPILER" "$SDK_ARG" "$@"
diff --git a/sdk_nnbd/bin/dartdevc.bat b/sdk_nnbd/bin/dartdevc.bat
new file mode 100644
index 0000000..fec39e4
--- /dev/null
+++ b/sdk_nnbd/bin/dartdevc.bat
@@ -0,0 +1,66 @@
+@echo off
+REM Copyright (c) 2013, 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
+
+set DART=%BIN_DIR%\dart
+
+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 SDK_ARG=--dart-sdk=%SDK_DIR%
+
+set EXTRA_VM_OPTIONS=
+
+rem We allow extra vm options to be passed in through an environment variable.
+if not "_%DART_VM_OPTIONS%_" == "__" (
+  set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% %DART_VM_OPTIONS%
+)
+
+rem Get absolute full name for DART_ROOT.
+for %%i in ("%SDK_DIR%\..\") do set DART_ROOT=%%~fi
+
+rem Remove trailing backslash if there is one
+if %DART_ROOT:~-1%==\ set DART_ROOT=%DART_ROOT:~0,-1%
+
+set DEV_COMPILER=%DART_ROOT%\third_party\pkg\dev_compiler\bin\dartdevc.dart
+
+"%DART%" "--packages=%DART_ROOT%\.packages" %EXTRA_VM_OPTIONS% "DEV_COMPILER%" "%SDK_ARG%" %*
+
+endlocal
+
+exit /b %errorlevel%
+
+rem Follow the symbolic links (junctions points) using `dir to determine the
+rem canonical path. Output with a link looks something like this
+rem
+rem 01/03/2013  10:11 PM    <JUNCTION>     abc def
+rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk]
+rem
+rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename
+rem surrounded by right angle bracket and left square bracket. Once we get
+rem the filename, which is name of the link, we recursively follow that.
+:follow_links
+setlocal
+for %%i in (%1) do set result=%%~fi
+set current=
+for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
+                                             ^| find ">     %~n1 [" 2^>nul`) do (
+  set current=%%i
+)
+if not "%current%"=="" call :follow_links "%current%", result
+endlocal & set %~2=%result%
+goto :eof
+
+:end
diff --git a/sdk_nnbd/bin/dartdevc_sdk b/sdk_nnbd/bin/dartdevc_sdk
new file mode 100755
index 0000000..60d2fe1
--- /dev/null
+++ b/sdk_nnbd/bin/dartdevc_sdk
@@ -0,0 +1,28 @@
+#!/usr/bin/env 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 a
+# BSD-style license that can be found in the LICENSE file.
+
+# Run dev compiler on the Dart VM. This script assumes the Dart SDK's
+# directory structure.
+
+function follow_links() {
+  file="$1"
+  while [ -h "$file" ]; do
+    # On Mac OS, readlink -f doesn't work.
+    file="$(readlink "$file")"
+  done
+  echo "$file"
+}
+
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Handle the case where dart-sdk/bin has been symlinked to.
+BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
+
+SNAPSHOT="$BIN_DIR/snapshots/dartdevc.dart.snapshot"
+
+# We are running the snapshot in the built SDK.
+DART="$BIN_DIR/dart"
+exec "$DART" "$SNAPSHOT" "$@"
diff --git a/sdk_nnbd/bin/dartdevc_sdk.bat b/sdk_nnbd/bin/dartdevc_sdk.bat
new file mode 100644
index 0000000..5dbf707
--- /dev/null
+++ b/sdk_nnbd/bin/dartdevc_sdk.bat
@@ -0,0 +1,52 @@
+@echo off
+REM Copyright (c) 2013, 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
+
+set DART=%BIN_DIR%\dart
+set SNAPSHOT=%BIN_DIR%\snapshots\dartdevc.dart.snapshot
+
+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 SDK_ARG=--dart-sdk=%SDK_DIR%
+
+"%DART%" "%SNAPSHOT%" "%SDK_ARG%" %*
+
+endlocal
+
+exit /b %errorlevel%
+
+rem Follow the symbolic links (junctions points) using `dir to determine the
+rem canonical path. Output with a link looks something like this
+rem
+rem 01/03/2013  10:11 PM    <JUNCTION>     abc def
+rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk]
+rem
+rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename
+rem surrounded by right angle bracket and left square bracket. Once we get
+rem the filename, which is name of the link, we recursively follow that.
+:follow_links
+setlocal
+for %%i in (%1) do set result=%%~fi
+set current=
+for /f "usebackq 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_nnbd/bin/dartdoc b/sdk_nnbd/bin/dartdoc
new file mode 100755
index 0000000..e9584c1
--- /dev/null
+++ b/sdk_nnbd/bin/dartdoc
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+# Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+function follow_links() {
+  file="$1"
+  while [ -h "$file" ]; do
+    # On Mac OS, readlink -f doesn't work.
+    file="$(readlink "$file")"
+  done
+  echo "$file"
+}
+
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Handle the case where dart-sdk/bin has been symlinked to.
+BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
+SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)"
+
+SNAPSHOT="$BIN_DIR/snapshots/dartdoc.dart.snapshot"
+
+# We are running the snapshot in the built SDK.
+DART="$BIN_DIR/dart"
+exec "$DART" "--packages=$BIN_DIR/resources/dartdoc/.packages" "$SNAPSHOT" "$@"
diff --git a/sdk_nnbd/bin/dartdoc.bat b/sdk_nnbd/bin/dartdoc.bat
new file mode 100644
index 0000000..876eb0e
--- /dev/null
+++ b/sdk_nnbd/bin/dartdoc.bat
@@ -0,0 +1,44 @@
+@echo off
+REM Copyright (c) 2015, 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
+
+set DART=%BIN_DIR%\dart
+set SNAPSHOT=%BIN_DIR%\snapshots\dartdoc.dart.snapshot
+
+"%DART%" "--packages=%BIN_DIR%/resources/dartdoc/.packages" "%SNAPSHOT%" %*
+
+endlocal
+
+exit /b %errorlevel%
+
+rem Follow the symbolic links (junctions points) using `dir to determine the
+rem canonical path. Output with a link looks something like this
+rem
+rem 01/03/2013  10:11 PM    <JUNCTION>     abc def
+rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk]
+rem
+rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename
+rem surrounded by right angle bracket and left square bracket. Once we get
+rem the filename, which is name of the link, we recursively follow that.
+:follow_links
+setlocal
+for %%i in (%1) do set result=%%~fi
+set current=
+for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
+                                             ^| %SystemRoot%\System32\find.exe ">     %~n1 [" 2^>nul`) do (
+  set current=%%i
+)
+if not "%current%"=="" call :follow_links "%current%", result
+endlocal & set %~2=%result%
+goto :eof
+
+:end
diff --git a/sdk_nnbd/bin/dartfmt b/sdk_nnbd/bin/dartfmt
new file mode 100755
index 0000000..ad54140
--- /dev/null
+++ b/sdk_nnbd/bin/dartfmt
@@ -0,0 +1,31 @@
+#!/usr/bin/env 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 a
+# BSD-style license that can be found in the LICENSE file.
+
+# Run dart_style/bin/format.dart on the Dart VM. This script assumes the Dart
+# repo's directory structure.
+
+function follow_links() {
+  file="$1"
+  while [ -h "$file" ]; do
+    # On Mac OS, readlink -f doesn't work.
+    file="$(readlink "$file")"
+  done
+  echo "$file"
+}
+
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Handle the case where dart-sdk/bin has been symlinked to.
+BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
+SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)"
+
+DART="$BIN_DIR/dart"
+
+DART_ROOT="$(cd "${SDK_DIR}/.." ; pwd -P)"
+
+DARTFMT="$DART_ROOT/third_party/pkg_tested/dart_style/bin/format.dart"
+
+exec "$DART" "--packages=$DART_ROOT/.packages" "$DARTFMT" "$@"
diff --git a/sdk_nnbd/bin/dartfmt.bat b/sdk_nnbd/bin/dartfmt.bat
new file mode 100644
index 0000000..7a7412b
--- /dev/null
+++ b/sdk_nnbd/bin/dartfmt.bat
@@ -0,0 +1,57 @@
+@echo off
+REM Copyright (c) 2013, 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
+
+set DART=%BIN_DIR%\dart
+
+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%
+
+rem Get absolute full name for DART_ROOT.
+for %%i in ("%SDK_DIR%\..\") do set DART_ROOT=%%~fi
+
+rem Remove trailing backslash if there is one
+if %DART_ROOT:~-1%==\ set DART_ROOT=%DART_ROOT:~0,-1%
+
+set DARTFMT=%DART_ROOT%\third_party\pkg_tested\dart_style\bin\format.dart
+
+"%DART%" "--packages=%DART_ROOT%\.packages" "%DARTFMT%" %*
+
+endlocal
+
+exit /b %errorlevel%
+
+rem Follow the symbolic links (junctions points) using `dir to determine the
+rem canonical path. Output with a link looks something like this
+rem
+rem 01/03/2013  10:11 PM    <JUNCTION>     abc def
+rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk]
+rem
+rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename
+rem surrounded by right angle bracket and left square bracket. Once we get
+rem the filename, which is name of the link, we recursively follow that.
+:follow_links
+setlocal
+for %%i in (%1) do set result=%%~fi
+set current=
+for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
+                                             ^| %SystemRoot%\System32\find.exe ">     %~n1 [" 2^>nul`) do (
+  set current=%%i
+)
+if not "%current%"=="" call :follow_links "%current%", result
+endlocal & set %~2=%result%
+goto :eof
+
+:end
diff --git a/sdk_nnbd/bin/dartfmt_sdk b/sdk_nnbd/bin/dartfmt_sdk
new file mode 100755
index 0000000..273733c
--- /dev/null
+++ b/sdk_nnbd/bin/dartfmt_sdk
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+# Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+# for 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 dart_style/bin/format.dart on the Dart VM. This script assumes the Dart
+# SDK's directory structure.
+
+function follow_links() {
+  file="$1"
+  while [ -h "$file" ]; do
+    # On Mac OS, readlink -f doesn't work.
+    file="$(readlink "$file")"
+  done
+  echo "$file"
+}
+
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Handle the case where dart-sdk/bin has been symlinked to.
+BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
+SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)"
+
+SNAPSHOT="$BIN_DIR/snapshots/dartfmt.dart.snapshot"
+
+# We are running the snapshot in the built SDK.
+DART="$BIN_DIR/dart"
+exec "$DART" "$SNAPSHOT" "$@"
diff --git a/sdk_nnbd/bin/dartfmt_sdk.bat b/sdk_nnbd/bin/dartfmt_sdk.bat
new file mode 100644
index 0000000..295b977
--- /dev/null
+++ b/sdk_nnbd/bin/dartfmt_sdk.bat
@@ -0,0 +1,44 @@
+@echo off
+REM Copyright (c) 2015, 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
+
+set DART=%BIN_DIR%\dart
+set SNAPSHOT=%BIN_DIR%\snapshots\dartfmt.dart.snapshot
+
+"%DART%" "%SNAPSHOT%" %*
+
+endlocal
+
+exit /b %errorlevel%
+
+rem Follow the symbolic links (junctions points) using `dir to determine the
+rem canonical path. Output with a link looks something like this
+rem
+rem 01/03/2013  10:11 PM    <JUNCTION>     abc def
+rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk]
+rem
+rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename
+rem surrounded by right angle bracket and left square bracket. Once we get
+rem the filename, which is name of the link, we recursively follow that.
+:follow_links
+setlocal
+for %%i in (%1) do set result=%%~fi
+set current=
+for /f "usebackq 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_nnbd/bin/pub b/sdk_nnbd/bin/pub
new file mode 100755
index 0000000..5dda611
--- /dev/null
+++ b/sdk_nnbd/bin/pub
@@ -0,0 +1,85 @@
+#!/usr/bin/env 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 is only used when running pub from
+# within the Dart source repo. The shipped SDK instead uses "pub_sdk", which is
+# renamed to "pub" when the SDK is built.
+
+function follow_links() {
+  file="$1"
+  while [ -h "$file" ]; do
+    # On Mac OS, readlink -f doesn't work.
+    file="$(readlink "$file")"
+  done
+  echo "$file"
+}
+
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Handle the case where dart-sdk/bin has been symlinked to.
+BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
+
+SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)"
+
+SNAPSHOT="$BIN_DIR/snapshots/pub.dart.snapshot"
+
+unset VM_OPTIONS
+declare -a VM_OPTIONS
+
+if [[ `uname` == 'Darwin' ]];
+then
+  OUT_DIR="$BIN_DIR"/../../xcodebuild/
+else
+  OUT_DIR="$BIN_DIR"/../../out/
+fi
+
+# Allow extra VM options to be passed in through an environment variable.
+if [[ $DART_VM_OPTIONS ]]; then
+  read -a OPTIONS <<< "$DART_VM_OPTIONS"
+  VM_OPTIONS+=("${OPTIONS[@]}")
+fi
+
+if [ -z "$DART_CONFIGURATION" ];
+then
+  DIRS=$( ls "$OUT_DIR" )
+  # list of possible configurations in decreasing desirability
+  CONFIGS=("ReleaseX64" "ReleaseIA32" "DebugX64" "DebugIA32"
+    "ReleaseARM"    "ReleaseARM64"    "ReleaseARMV5TE"
+    "DebugARM"      "DebugARM64"      "DebugARMV5TE")
+  DART_CONFIGURATION="None"
+  for CONFIG in ${CONFIGS[*]}
+  do
+    for DIR in $DIRS;
+    do
+      if [ "$CONFIG" = "$DIR" ];
+      then
+        # choose most desirable configuration that is available and break
+        DART_CONFIGURATION="$DIR"
+        break 2
+      fi
+    done
+  done
+  if [ "$DART_CONFIGURATION" = "None" ]
+  then
+    echo "No valid dart configuration found in $OUT_DIR"
+    exit 1
+  fi
+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"
+
+# Run pub.
+PUB="$SDK_DIR/../third_party/pkg/pub/bin/pub.dart"
+exec "$DART" "--packages=$SDK_DIR/../.packages" "${VM_OPTIONS[@]}" "$PUB" "$@"
diff --git a/sdk_nnbd/bin/pub.bat b/sdk_nnbd/bin/pub.bat
new file mode 100644
index 0000000..7eb8b0d
--- /dev/null
+++ b/sdk_nnbd/bin/pub.bat
@@ -0,0 +1,56 @@
+@echo off
+REM Copyright (c) 2014, 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.
+
+rem Run pub.dart on the Dart VM. This script is only used when running pub from
+rem within the Dart source repo. The shipped SDK instead uses "pub_sdk.bat",
+rem which is renamed to "pub.bat" when the SDK is built.
+
+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 VM_OPTIONS=
+
+rem We allow extra vm options to be passed in through an environment variable.
+if not "_%DART_VM_OPTIONS%_" == "__" (
+  set VM_OPTIONS=%VM_OPTIONS% %DART_VM_OPTIONS%
+)
+
+rem Use the Dart binary in the built SDK so pub can find the version file next
+rem to it.
+set BUILD_DIR=%SDK_DIR%\..\out\ReleaseX64
+set DART=%BUILD_DIR%\dart-sdk\bin\dart
+
+rem Run pub.
+set PUB="%SDK_DIR%\..\third_party\pkg\pub\bin\pub.dart"
+"%DART%" "--packages=%SDK_DIR%\..\.packages" %VM_OPTIONS% "%PUB%" %*
+
+endlocal
+
+exit /b %errorlevel%
+
+:follow_links
+setlocal
+for %%i in (%1) do set result=%%~fi
+set current=
+for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
+                                             ^| %SystemRoot%\System32\find.exe ">     %~n1 [" 2^>nul`) do (
+  set current=%%i
+)
+if not "%current%"=="" call :follow_links "%current%", result
+endlocal & set %~2=%result%
+goto :eof
+
+:end
diff --git a/sdk_nnbd/bin/pub_sdk b/sdk_nnbd/bin/pub_sdk
new file mode 100755
index 0000000..4d29878
--- /dev/null
+++ b/sdk_nnbd/bin/pub_sdk
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+# Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+# for 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.
+
+function follow_links() {
+  file="$1"
+  while [ -h "$file" ]; do
+    # On Mac OS, readlink -f doesn't work.
+    file="$(readlink "$file")"
+  done
+  echo "$file"
+}
+
+function array_contains() {
+  local needle="$1"
+  local element
+  shift
+  for element; do [ "$element" = "$needle" ] && return 0; done
+  return 1
+}
+
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Handle the case where dart-sdk/bin has been symlinked to.
+BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
+
+
+unset VM_OPTIONS
+declare -a VM_OPTIONS
+
+# Allow extra VM options to be passed in through an environment variable.
+if [[ $DART_VM_OPTIONS ]]; then
+  read -a OPTIONS <<< "$DART_VM_OPTIONS"
+  VM_OPTIONS+=("${OPTIONS[@]}")
+fi
+
+# Run the pub snapshot.
+DART="$BIN_DIR/dart"
+if array_contains "--no-preview-dart-2" "${VM_OPTIONS[@]}"; then
+  echo "Pub no longer supports Dart 1"
+  exit -1
+else
+  SNAPSHOT="$BIN_DIR/snapshots/pub.dart.snapshot"
+  exec "$DART" "${VM_OPTIONS[@]}" "$SNAPSHOT" "$@"
+fi
diff --git a/sdk_nnbd/bin/pub_sdk.bat b/sdk_nnbd/bin/pub_sdk.bat
new file mode 100644
index 0000000..bde0e4a
--- /dev/null
+++ b/sdk_nnbd/bin/pub_sdk.bat
@@ -0,0 +1,53 @@
+@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 VM_OPTIONS=
+set USING_DART_1=
+
+rem We allow extra vm options to be passed in through an environment variable.
+if not "_%DART_VM_OPTIONS%_" == "__" (
+  set VM_OPTIONS=%VM_OPTIONS% %DART_VM_OPTIONS%
+  for %%o in (%DART_VM_OPTIONS%) do (
+    if "%%o" equ "--no-preview-dart-2" set USING_DART_1=y
+  )
+)
+
+if defined USING_DART_1 (
+  echo "Pub no longer supports Dart 1"
+) else (
+  "%BIN_DIR%\dart" %VM_OPTIONS% "%BIN_DIR%\snapshots\pub.dart.snapshot" %*
+)
+
+endlocal
+
+exit /b %errorlevel%
+
+:follow_links
+setlocal
+for %%i in (%1) do set result=%%~fi
+set current=
+for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
+                                             ^| find ">     %~n1 [" 2^>nul`) do (
+  set current=%%i
+)
+if not "%current%"=="" call :follow_links "%current%", result
+endlocal & set %~2=%result%
+goto :eof
+
+:end
diff --git a/sdk_nnbd/lib/_chrome/dart2js/chrome_dart2js.dart b/sdk_nnbd/lib/_chrome/dart2js/chrome_dart2js.dart
new file mode 100644
index 0000000..023afe4
--- /dev/null
+++ b/sdk_nnbd/lib/_chrome/dart2js/chrome_dart2js.dart
@@ -0,0 +1,1258 @@
+/// Native wrappers for the Chrome packaged app APIs.
+///
+/// These functions allow direct access to the chrome.* APIs, allowing
+/// Chrome packaged apps to be written using Dart.
+///
+/// For more information on these APIs, see the
+/// [chrome.* API documentation](http://developer.chrome.com/apps/api_index.html).
+library _chrome;
+
+import 'dart:_foreign_helper' show JS;
+import 'dart:_js_helper';
+import 'dart:html_common';
+import 'dart:html';
+
+// 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.
+
+// DO NOT EDIT
+// Auto-generated dart:_chrome library.
+
+/* TODO(sashab): Add "show convertDartClosureToJS" once 'show' works. */
+
+// Generated files below this line.
+// 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 set of utilities for use with the Chrome Extension APIs.
+ *
+ * Allows for easy access to required JS objects.
+ */
+
+/**
+ * A dart object, that is convertible to JS. Used for creating objects in dart,
+ * then passing them to JS.
+ *
+ * Objects that are passable to JS need to implement this interface.
+ */
+abstract class ChromeObject {
+  /*
+   * Default Constructor
+   *
+   * Called by child objects during their regular construction.
+   */
+  ChromeObject() : _jsObject = JS('var', '{}');
+
+  /*
+   * Internal proxy constructor
+   *
+   * Creates a new Dart object using this existing proxy.
+   */
+  ChromeObject._proxy(this._jsObject);
+
+  /*
+   * JS Object Representation
+   */
+  final Object _jsObject;
+}
+
+/**
+ * Useful functions for converting arguments.
+ */
+
+/**
+ * Converts the given map-type argument to js-friendly format, recursively.
+ * Returns the new Map object.
+ */
+Object _convertMapArgument(Map argument) {
+  Map m = new Map();
+  for (Object key in argument.keys) m[key] = convertArgument(argument[key]);
+  return convertDartToNative_Dictionary(m);
+}
+
+/**
+ * Converts the given list-type argument to js-friendly format, recursively.
+ * Returns the new List object.
+ */
+List _convertListArgument(List argument) {
+  List l = new List();
+  for (var i = 0; i < argument.length; i++) l.add(convertArgument(argument[i]));
+  return l;
+}
+
+/**
+ * Converts the given argument Object to js-friendly format, recursively.
+ *
+ * Flattens out all Chrome objects into their corresponding ._toMap()
+ * definitions, then converts them to JS objects.
+ *
+ * Returns the new argument.
+ *
+ * Cannot be used for functions.
+ */
+Object convertArgument(var argument) {
+  if (argument == null) return argument;
+
+  if (argument is num || argument is String || argument is bool)
+    return argument;
+
+  if (argument is ChromeObject) return argument._jsObject;
+
+  if (argument is List) return _convertListArgument(argument);
+
+  if (argument is Map) return _convertMapArgument(argument);
+
+  if (argument is Function)
+    throw new Exception("Cannot serialize Function argument ${argument}.");
+
+  // TODO(sashab): Try and detect whether the argument is already serialized.
+  return argument;
+}
+
+/// Description of a declarative rule for handling events.
+class Rule extends ChromeObject {
+  /*
+   * Public (Dart) constructor
+   */
+  Rule({String id, List conditions, List actions, int priority}) {
+    this.id = id;
+    this.conditions = conditions;
+    this.actions = actions;
+    this.priority = priority;
+  }
+
+  /*
+   * Private (JS) constructor
+   */
+  Rule._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+  String get id => JS('String', '#.id', this._jsObject);
+
+  void set id(String id) {
+    JS('void', '#.id = #', this._jsObject, id);
+  }
+
+  // TODO(sashab): Wrap these generic Lists somehow.
+  List get conditions => JS('List', '#.conditions', this._jsObject);
+
+  void set conditions(List conditions) {
+    JS('void', '#.conditions = #', this._jsObject, convertArgument(conditions));
+  }
+
+  // TODO(sashab): Wrap these generic Lists somehow.
+  List get actions => JS('List', '#.actions', this._jsObject);
+
+  void set actions(List actions) {
+    JS('void', '#.actions = #', this._jsObject, convertArgument(actions));
+  }
+
+  int get priority => JS('int', '#.priority', this._jsObject);
+
+  void set priority(int priority) {
+    JS('void', '#.priority = #', this._jsObject, priority);
+  }
+}
+
+/**
+ * The Event class.
+ *
+ * Chrome Event classes extend this interface.
+ *
+ * e.g.
+ *
+ *  // chrome.app.runtime.onLaunched
+ *  class Event_ChromeAppRuntimeOnLaunched extends Event {
+ *    // constructor, passing the arity of the callback
+ *    Event_ChromeAppRuntimeOnLaunched(jsObject) :
+ *     super._(jsObject, 1);
+ *
+ *    // methods, strengthening the Function parameter specificity
+ *    void addListener(void callback(LaunchData launchData))
+ *        => super.addListener(callback);
+ *    void removeListener(void callback(LaunchData launchData))
+ *        => super.removeListener(callback);
+ *    bool hasListener(void callback(LaunchData launchData))
+ *        => super.hasListener(callback);
+ *  }
+ *
+ */
+class Event {
+  /*
+   * JS Object Representation
+   */
+  final Object _jsObject;
+
+  /*
+   * Number of arguments the callback takes.
+   */
+  final int _callbackArity;
+
+  /*
+   * Private constructor
+   */
+  Event._(this._jsObject, this._callbackArity);
+
+  /*
+   * Methods
+   */
+
+  /// Registers an event listener <em>callback</em> to an event.
+  void addListener(covariant Function callback) => JS(
+      'void',
+      '#.addListener(#)',
+      this._jsObject,
+      convertDartClosureToJS(callback, this._callbackArity));
+
+  /// Deregisters an event listener <em>callback</em> from an event.
+  void removeListener(covariant Function callback) => JS(
+      'void',
+      '#.removeListener(#)',
+      this._jsObject,
+      convertDartClosureToJS(callback, this._callbackArity));
+
+  /// Returns True if <em>callback</em> is registered to the event.
+  bool hasListener(covariant Function callback) => JS(
+      'bool',
+      '#.hasListener(#)',
+      this._jsObject,
+      convertDartClosureToJS(callback, this._callbackArity));
+
+  /// Returns true if any event listeners are registered to the event.
+  bool hasListeners() => JS('bool', '#.hasListeners()', this._jsObject);
+
+  /// Registers rules to handle events.
+  ///
+  /// [eventName] is the name of the event this function affects and [rules] are
+  /// the rules to be registered. These do not replace previously registered
+  /// rules. [callback] is called with registered rules.
+  ///
+  void addRules(String eventName, List<Rule> rules,
+      [void callback(List<Rule> rules)]) {
+    // proxy the callback
+    void __proxy_callback(List rules) {
+      if (callback != null) {
+        List<Rule> __proxy_rules = new List<Rule>();
+
+        for (Object o in rules) __proxy_rules.add(new Rule._proxy(o));
+
+        callback(__proxy_rules);
+      }
+    }
+
+    JS(
+        'void',
+        '#.addRules(#, #, #)',
+        this._jsObject,
+        convertArgument(eventName),
+        convertArgument(rules),
+        convertDartClosureToJS(__proxy_callback, 1));
+  }
+
+  /// Returns currently registered rules.
+  ///
+  /// [eventName] is the name of the event this function affects and, if an array
+  /// is passed as [ruleIdentifiers], only rules with identifiers contained in
+  /// this array are returned. [callback] is called with registered rules.
+  ///
+  void getRules(String eventName,
+      [List<String> ruleIdentifiers, void callback(List<Rule> rules)]) {
+    // proxy the callback
+    void __proxy_callback(List rules) {
+      if (callback != null) {
+        List<Rule> __proxy_rules = new List<Rule>();
+
+        for (Object o in rules) __proxy_rules.add(new Rule._proxy(o));
+
+        callback(__proxy_rules);
+      }
+    }
+
+    JS(
+        'void',
+        '#.getRules(#, #, #)',
+        this._jsObject,
+        convertArgument(eventName),
+        convertArgument(ruleIdentifiers),
+        convertDartClosureToJS(__proxy_callback, 1));
+  }
+
+  /// Unregisters currently registered rules.
+  ///
+  /// [eventName] is the name of the event this function affects and, if an array
+  /// is passed as [ruleIdentifiers], only rules with identifiers contained in
+  /// this array are unregistered. [callback] is called when the rules are
+  /// unregistered.
+  ///
+  void removeRules(String eventName,
+          [List<String> ruleIdentifiers, void callback()]) =>
+      JS(
+          'void',
+          '#.removeRules(#, #, #)',
+          this._jsObject,
+          convertArgument(eventName),
+          convertArgument(ruleIdentifiers),
+          convertDartClosureToJS(callback, 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.
+
+// chrome.app
+class API_ChromeApp {
+  /*
+   * JS Variable
+   */
+  final Object _jsObject;
+
+  /*
+   * Members
+   */
+  API_app_window window;
+  API_app_runtime runtime;
+
+  /*
+   * Constructor
+   */
+  API_ChromeApp(this._jsObject) {
+    var window_object = JS('', '#.window', this._jsObject);
+    if (window_object == null)
+      throw new UnsupportedError('Not supported by current browser.');
+    window = new API_app_window(window_object);
+
+    var runtime_object = JS('', '#.runtime', this._jsObject);
+    if (runtime_object == null)
+      throw new UnsupportedError('Not supported by current browser.');
+    runtime = new API_app_runtime(runtime_object);
+  }
+}
+
+// chrome
+class API_Chrome {
+  /*
+   * JS Variable
+   */
+  Object _jsObject;
+
+  /*
+   * Members
+   */
+  API_ChromeApp app;
+  API_file_system fileSystem;
+
+  /*
+   * Constructor
+   */
+  API_Chrome() {
+    this._jsObject = JS("Object", "chrome");
+    if (this._jsObject == null)
+      throw new UnsupportedError('Not supported by current browser.');
+
+    var app_object = JS('', '#.app', this._jsObject);
+    if (app_object == null)
+      throw new UnsupportedError('Not supported by current browser.');
+    app = new API_ChromeApp(app_object);
+
+    var file_system_object = JS('', '#.fileSystem', this._jsObject);
+    if (file_system_object == null)
+      throw new UnsupportedError('Not supported by current browser.');
+    fileSystem = new API_file_system(file_system_object);
+  }
+}
+
+// The final chrome objects
+final API_Chrome chrome = new API_Chrome();
+// 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.
+
+// Generated from namespace: app.window
+
+/**
+ * Types
+ */
+
+class AppWindowBounds extends ChromeObject {
+  /*
+   * Public constructor
+   */
+  AppWindowBounds({int left, int top, int width, int height}) {
+    if (left != null) this.left = left;
+    if (top != null) this.top = top;
+    if (width != null) this.width = width;
+    if (height != null) this.height = height;
+  }
+
+  /*
+   * Private constructor
+   */
+  AppWindowBounds._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+  int get left => JS('int', '#.left', this._jsObject);
+
+  void set left(int left) {
+    JS('void', '#.left = #', this._jsObject, left);
+  }
+
+  int get top => JS('int', '#.top', this._jsObject);
+
+  void set top(int top) {
+    JS('void', '#.top = #', this._jsObject, top);
+  }
+
+  int get width => JS('int', '#.width', this._jsObject);
+
+  void set width(int width) {
+    JS('void', '#.width = #', this._jsObject, width);
+  }
+
+  int get height => JS('int', '#.height', this._jsObject);
+
+  void set height(int height) {
+    JS('void', '#.height = #', this._jsObject, height);
+  }
+}
+
+class AppWindowCreateWindowOptions extends ChromeObject {
+  /*
+   * Public constructor
+   */
+  AppWindowCreateWindowOptions(
+      {String id,
+      int defaultWidth,
+      int defaultHeight,
+      int defaultLeft,
+      int defaultTop,
+      int width,
+      int height,
+      int left,
+      int top,
+      int minWidth,
+      int minHeight,
+      int maxWidth,
+      int maxHeight,
+      String type,
+      String frame,
+      AppWindowBounds bounds,
+      bool transparentBackground,
+      String state,
+      bool hidden,
+      bool resizable,
+      bool singleton}) {
+    if (id != null) this.id = id;
+    if (defaultWidth != null) this.defaultWidth = defaultWidth;
+    if (defaultHeight != null) this.defaultHeight = defaultHeight;
+    if (defaultLeft != null) this.defaultLeft = defaultLeft;
+    if (defaultTop != null) this.defaultTop = defaultTop;
+    if (width != null) this.width = width;
+    if (height != null) this.height = height;
+    if (left != null) this.left = left;
+    if (top != null) this.top = top;
+    if (minWidth != null) this.minWidth = minWidth;
+    if (minHeight != null) this.minHeight = minHeight;
+    if (maxWidth != null) this.maxWidth = maxWidth;
+    if (maxHeight != null) this.maxHeight = maxHeight;
+    if (type != null) this.type = type;
+    if (frame != null) this.frame = frame;
+    if (bounds != null) this.bounds = bounds;
+    if (transparentBackground != null)
+      this.transparentBackground = transparentBackground;
+    if (state != null) this.state = state;
+    if (hidden != null) this.hidden = hidden;
+    if (resizable != null) this.resizable = resizable;
+    if (singleton != null) this.singleton = singleton;
+  }
+
+  /*
+   * Private constructor
+   */
+  AppWindowCreateWindowOptions._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+  /// Id to identify the window. This will be used to remember the size and
+  /// position of the window and restore that geometry when a window with the
+  /// same id is later opened.
+  String get id => JS('String', '#.id', this._jsObject);
+
+  void set id(String id) {
+    JS('void', '#.id = #', this._jsObject, id);
+  }
+
+  /// Default width of the window. (Deprecated; regular bounds act like this
+  /// now.)
+  int get defaultWidth => JS('int', '#.defaultWidth', this._jsObject);
+
+  void set defaultWidth(int defaultWidth) {
+    JS('void', '#.defaultWidth = #', this._jsObject, defaultWidth);
+  }
+
+  /// Default height of the window. (Deprecated; regular bounds act like this
+  /// now.)
+  int get defaultHeight => JS('int', '#.defaultHeight', this._jsObject);
+
+  void set defaultHeight(int defaultHeight) {
+    JS('void', '#.defaultHeight = #', this._jsObject, defaultHeight);
+  }
+
+  /// Default X coordinate of the window. (Deprecated; regular bounds act like
+  /// this now.)
+  int get defaultLeft => JS('int', '#.defaultLeft', this._jsObject);
+
+  void set defaultLeft(int defaultLeft) {
+    JS('void', '#.defaultLeft = #', this._jsObject, defaultLeft);
+  }
+
+  /// Default Y coordinate of the window. (Deprecated; regular bounds act like
+  /// this now.)
+  int get defaultTop => JS('int', '#.defaultTop', this._jsObject);
+
+  void set defaultTop(int defaultTop) {
+    JS('void', '#.defaultTop = #', this._jsObject, defaultTop);
+  }
+
+  /// Width of the window. (Deprecated; use 'bounds'.)
+  int get width => JS('int', '#.width', this._jsObject);
+
+  void set width(int width) {
+    JS('void', '#.width = #', this._jsObject, width);
+  }
+
+  /// Height of the window. (Deprecated; use 'bounds'.)
+  int get height => JS('int', '#.height', this._jsObject);
+
+  void set height(int height) {
+    JS('void', '#.height = #', this._jsObject, height);
+  }
+
+  /// X coordinate of the window. (Deprecated; use 'bounds'.)
+  int get left => JS('int', '#.left', this._jsObject);
+
+  void set left(int left) {
+    JS('void', '#.left = #', this._jsObject, left);
+  }
+
+  /// Y coordinate of the window. (Deprecated; use 'bounds'.)
+  int get top => JS('int', '#.top', this._jsObject);
+
+  void set top(int top) {
+    JS('void', '#.top = #', this._jsObject, top);
+  }
+
+  /// Minimum width for the lifetime of the window.
+  int get minWidth => JS('int', '#.minWidth', this._jsObject);
+
+  void set minWidth(int minWidth) {
+    JS('void', '#.minWidth = #', this._jsObject, minWidth);
+  }
+
+  /// Minimum height for the lifetime of the window.
+  int get minHeight => JS('int', '#.minHeight', this._jsObject);
+
+  void set minHeight(int minHeight) {
+    JS('void', '#.minHeight = #', this._jsObject, minHeight);
+  }
+
+  /// Maximum width for the lifetime of the window.
+  int get maxWidth => JS('int', '#.maxWidth', this._jsObject);
+
+  void set maxWidth(int maxWidth) {
+    JS('void', '#.maxWidth = #', this._jsObject, maxWidth);
+  }
+
+  /// Maximum height for the lifetime of the window.
+  int get maxHeight => JS('int', '#.maxHeight', this._jsObject);
+
+  void set maxHeight(int maxHeight) {
+    JS('void', '#.maxHeight = #', this._jsObject, maxHeight);
+  }
+
+  /// Type of window to create.
+  String get type => JS('String', '#.type', this._jsObject);
+
+  void set type(String type) {
+    JS('void', '#.type = #', this._jsObject, type);
+  }
+
+  /// Frame type: 'none' or 'chrome' (defaults to 'chrome').
+  String get frame => JS('String', '#.frame', this._jsObject);
+
+  void set frame(String frame) {
+    JS('void', '#.frame = #', this._jsObject, frame);
+  }
+
+  /// Size and position of the content in the window (excluding the titlebar). If
+  /// an id is also specified and a window with a matching id has been shown
+  /// before, the remembered bounds of the window will be used instead.
+  AppWindowBounds get bounds =>
+      new AppWindowBounds._proxy(JS('', '#.bounds', this._jsObject));
+
+  void set bounds(AppWindowBounds bounds) {
+    JS('void', '#.bounds = #', this._jsObject, convertArgument(bounds));
+  }
+
+  /// Enable window background transparency. Only supported in ash. Requires
+  /// experimental API permission.
+  bool get transparentBackground =>
+      JS('bool', '#.transparentBackground', this._jsObject);
+
+  void set transparentBackground(bool transparentBackground) {
+    JS('void', '#.transparentBackground = #', this._jsObject,
+        transparentBackground);
+  }
+
+  /// The initial state of the window, allowing it to be created already
+  /// fullscreen, maximized, or minimized. Defaults to 'normal'.
+  String get state => JS('String', '#.state', this._jsObject);
+
+  void set state(String state) {
+    JS('void', '#.state = #', this._jsObject, state);
+  }
+
+  /// If true, the window will be created in a hidden state. Call show() on the
+  /// window to show it once it has been created. Defaults to false.
+  bool get hidden => JS('bool', '#.hidden', this._jsObject);
+
+  void set hidden(bool hidden) {
+    JS('void', '#.hidden = #', this._jsObject, hidden);
+  }
+
+  /// If true, the window will be resizable by the user. Defaults to true.
+  bool get resizable => JS('bool', '#.resizable', this._jsObject);
+
+  void set resizable(bool resizable) {
+    JS('void', '#.resizable = #', this._jsObject, resizable);
+  }
+
+  /// By default if you specify an id for the window, the window will only be
+  /// created if another window with the same id doesn't already exist. If a
+  /// window with the same id already exists that window is activated instead. If
+  /// you do want to create multiple windows with the same id, you can set this
+  /// property to false.
+  bool get singleton => JS('bool', '#.singleton', this._jsObject);
+
+  void set singleton(bool singleton) {
+    JS('void', '#.singleton = #', this._jsObject, singleton);
+  }
+}
+
+class AppWindowAppWindow extends ChromeObject {
+  /*
+   * Private constructor
+   */
+  AppWindowAppWindow._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+  /// The JavaScript 'window' object for the created child.
+  // 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.
+
+  // TODO(sashab, sra): Detect whether this is the current window, or an
+  // external one, and return an appropriately-typed object
+  WindowBase get contentWindow =>
+      JS("Window", "#.contentWindow", this._jsObject);
+
+  /*
+   * Methods
+   */
+  /// Focus the window.
+  void focus() => JS('void', '#.focus()', this._jsObject);
+
+  /// Fullscreens the window.
+  void fullscreen() => JS('void', '#.fullscreen()', this._jsObject);
+
+  /// Is the window fullscreen?
+  bool isFullscreen() => JS('bool', '#.isFullscreen()', this._jsObject);
+
+  /// Minimize the window.
+  void minimize() => JS('void', '#.minimize()', this._jsObject);
+
+  /// Is the window minimized?
+  bool isMinimized() => JS('bool', '#.isMinimized()', this._jsObject);
+
+  /// Maximize the window.
+  void maximize() => JS('void', '#.maximize()', this._jsObject);
+
+  /// Is the window maximized?
+  bool isMaximized() => JS('bool', '#.isMaximized()', this._jsObject);
+
+  /// Restore the window, exiting a maximized, minimized, or fullscreen state.
+  void restore() => JS('void', '#.restore()', this._jsObject);
+
+  /// Move the window to the position (|left|, |top|).
+  void moveTo(int left, int top) =>
+      JS('void', '#.moveTo(#, #)', this._jsObject, left, top);
+
+  /// Resize the window to |width|x|height| pixels in size.
+  void resizeTo(int width, int height) =>
+      JS('void', '#.resizeTo(#, #)', this._jsObject, width, height);
+
+  /// Draw attention to the window.
+  void drawAttention() => JS('void', '#.drawAttention()', this._jsObject);
+
+  /// Clear attention to the window.
+  void clearAttention() => JS('void', '#.clearAttention()', this._jsObject);
+
+  /// Close the window.
+  void close() => JS('void', '#.close()', this._jsObject);
+
+  /// Show the window. Does nothing if the window is already visible.
+  void show() => JS('void', '#.show()', this._jsObject);
+
+  /// Hide the window. Does nothing if the window is already hidden.
+  void hide() => JS('void', '#.hide()', this._jsObject);
+
+  /// Get the window's bounds as a $ref:Bounds object.
+  // 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.
+
+  // TODO(sashab, kalman): Fix IDL parser to read function return values
+  // correctly. Currently, it just reads void for all functions.
+  AppWindowBounds getBounds() =>
+      new AppWindowBounds._proxy(JS('void', '#.getBounds()', this._jsObject));
+
+  /// Set the window's bounds.
+  void setBounds(AppWindowBounds bounds) =>
+      JS('void', '#.setBounds(#)', this._jsObject, convertArgument(bounds));
+
+  /// Set the app icon for the window (experimental). Currently this is only
+  /// being implemented on Ash. TODO(stevenjb): Investigate implementing this on
+  /// Windows and OSX.
+  void setIcon(String icon_url) =>
+      JS('void', '#.setIcon(#)', this._jsObject, icon_url);
+}
+
+/**
+ * Events
+ */
+
+/// Fired when the window is resized.
+class Event_app_window_onBoundsChanged extends Event {
+  void addListener(void callback()) => super.addListener(callback);
+
+  void removeListener(void callback()) => super.removeListener(callback);
+
+  bool hasListener(void callback()) => super.hasListener(callback);
+
+  Event_app_window_onBoundsChanged(jsObject) : super._(jsObject, 0);
+}
+
+/// Fired when the window is closed.
+class Event_app_window_onClosed extends Event {
+  void addListener(void callback()) => super.addListener(callback);
+
+  void removeListener(void callback()) => super.removeListener(callback);
+
+  bool hasListener(void callback()) => super.hasListener(callback);
+
+  Event_app_window_onClosed(jsObject) : super._(jsObject, 0);
+}
+
+/// Fired when the window is fullscreened.
+class Event_app_window_onFullscreened extends Event {
+  void addListener(void callback()) => super.addListener(callback);
+
+  void removeListener(void callback()) => super.removeListener(callback);
+
+  bool hasListener(void callback()) => super.hasListener(callback);
+
+  Event_app_window_onFullscreened(jsObject) : super._(jsObject, 0);
+}
+
+/// Fired when the window is maximized.
+class Event_app_window_onMaximized extends Event {
+  void addListener(void callback()) => super.addListener(callback);
+
+  void removeListener(void callback()) => super.removeListener(callback);
+
+  bool hasListener(void callback()) => super.hasListener(callback);
+
+  Event_app_window_onMaximized(jsObject) : super._(jsObject, 0);
+}
+
+/// Fired when the window is minimized.
+class Event_app_window_onMinimized extends Event {
+  void addListener(void callback()) => super.addListener(callback);
+
+  void removeListener(void callback()) => super.removeListener(callback);
+
+  bool hasListener(void callback()) => super.hasListener(callback);
+
+  Event_app_window_onMinimized(jsObject) : super._(jsObject, 0);
+}
+
+/// Fired when the window is restored from being minimized or maximized.
+class Event_app_window_onRestored extends Event {
+  void addListener(void callback()) => super.addListener(callback);
+
+  void removeListener(void callback()) => super.removeListener(callback);
+
+  bool hasListener(void callback()) => super.hasListener(callback);
+
+  Event_app_window_onRestored(jsObject) : super._(jsObject, 0);
+}
+
+/**
+ * Functions
+ */
+
+class API_app_window {
+  /*
+   * API connection
+   */
+  Object _jsObject;
+
+  /*
+   * Events
+   */
+  Event_app_window_onBoundsChanged onBoundsChanged;
+  Event_app_window_onClosed onClosed;
+  Event_app_window_onFullscreened onFullscreened;
+  Event_app_window_onMaximized onMaximized;
+  Event_app_window_onMinimized onMinimized;
+  Event_app_window_onRestored onRestored;
+
+  /*
+   * Functions
+   */
+  /// The size and position of a window can be specified in a number of different
+  /// ways. The most simple option is not specifying anything at all, in which
+  /// case a default size and platform dependent position will be used.<br/><br/>
+  /// Another option is to use the bounds property, which will put the window at
+  /// the specified coordinates with the specified size. If the window has a
+  /// frame, it's total size will be the size given plus the size of the frame;
+  /// that is, the size in bounds is the content size, not the window
+  /// size.<br/><br/> To automatically remember the positions of windows you can
+  /// give them ids. If a window has an id, This id is used to remember the size
+  /// and position of the window whenever it is moved or resized. This size and
+  /// position is then used instead of the specified bounds on subsequent opening
+  /// of a window with the same id. If you need to open a window with an id at a
+  /// location other than the remembered default, you can create it hidden, move
+  /// it to the desired location, then show it.
+  // 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.
+
+  // TODO(sashab): This override is no longer needed once prefixes are removed.
+  void create(String url,
+      [AppWindowCreateWindowOptions options,
+      void callback(AppWindowAppWindow created_window)]) {
+    void __proxy_callback(created_window) {
+      if (callback != null)
+        callback(new AppWindowAppWindow._proxy(created_window));
+    }
+
+    JS('void', '#.create(#, #, #)', this._jsObject, url,
+        convertArgument(options), convertDartClosureToJS(__proxy_callback, 1));
+  }
+
+  /// Returns an $ref:AppWindow object for the current script context (ie
+  /// JavaScript 'window' object). This can also be called on a handle to a
+  /// script context for another page, for example:
+  /// otherWindow.chrome.app.window.current().
+  // 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.
+
+  // TODO(sashab, kalman): Fix IDL parser to read function return values
+  // correctly. Currently, it just reads void for all functions.
+  AppWindowAppWindow current() =>
+      new AppWindowAppWindow._proxy(JS('void', '#.current()', this._jsObject));
+
+  void initializeAppWindow(Object state) => JS('void',
+      '#.initializeAppWindow(#)', this._jsObject, convertArgument(state));
+
+  API_app_window(this._jsObject) {
+    onBoundsChanged = new Event_app_window_onBoundsChanged(
+        JS('', '#.onBoundsChanged', this._jsObject));
+    onClosed =
+        new Event_app_window_onClosed(JS('', '#.onClosed', this._jsObject));
+    onFullscreened = new Event_app_window_onFullscreened(
+        JS('', '#.onFullscreened', this._jsObject));
+    onMaximized = new Event_app_window_onMaximized(
+        JS('', '#.onMaximized', this._jsObject));
+    onMinimized = new Event_app_window_onMinimized(
+        JS('', '#.onMinimized', this._jsObject));
+    onRestored =
+        new Event_app_window_onRestored(JS('', '#.onRestored', this._jsObject));
+  }
+}
+// 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.
+
+// Generated from namespace: app.runtime
+
+/**
+ * Types
+ */
+
+class AppRuntimeLaunchItem extends ChromeObject {
+  /*
+   * Public constructor
+   */
+  AppRuntimeLaunchItem({FileEntry entry, String type}) {
+    if (entry != null) this.entry = entry;
+    if (type != null) this.type = type;
+  }
+
+  /*
+   * Private constructor
+   */
+  AppRuntimeLaunchItem._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+  /// FileEntry for the file.
+  FileEntry get entry => JS('FileEntry', '#.entry', this._jsObject);
+
+  void set entry(FileEntry entry) {
+    JS('void', '#.entry = #', this._jsObject, convertArgument(entry));
+  }
+
+  /// The MIME type of the file.
+  String get type => JS('String', '#.type', this._jsObject);
+
+  void set type(String type) {
+    JS('void', '#.type = #', this._jsObject, type);
+  }
+}
+
+class AppRuntimeLaunchData extends ChromeObject {
+  /*
+   * Public constructor
+   */
+  AppRuntimeLaunchData({String id, List<AppRuntimeLaunchItem> items}) {
+    if (id != null) this.id = id;
+    if (items != null) this.items = items;
+  }
+
+  /*
+   * Private constructor
+   */
+  AppRuntimeLaunchData._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+  /// The id of the file handler that the app is being invoked with.
+  String get id => JS('String', '#.id', this._jsObject);
+
+  void set id(String id) {
+    JS('void', '#.id = #', this._jsObject, id);
+  }
+
+  List<AppRuntimeLaunchItem> get items {
+    List<AppRuntimeLaunchItem> __proxy_items = new List<AppRuntimeLaunchItem>();
+    int count = JS('int', '#.items.length', this._jsObject);
+    for (int i = 0; i < count; i++) {
+      var item = JS('', '#.items[#]', this._jsObject, i);
+      __proxy_items.add(new AppRuntimeLaunchItem._proxy(item));
+    }
+    return __proxy_items;
+  }
+
+  void set items(List<AppRuntimeLaunchItem> items) {
+    JS('void', '#.items = #', this._jsObject, convertArgument(items));
+  }
+}
+
+/**
+ * Events
+ */
+
+/// Fired when an app is launched from the launcher.
+class Event_app_runtime_onLaunched extends Event {
+  void addListener(void callback(AppRuntimeLaunchData launchData)) {
+    void __proxy_callback(launchData) {
+      if (callback != null) {
+        callback(new AppRuntimeLaunchData._proxy(launchData));
+      }
+    }
+
+    super.addListener(__proxy_callback);
+  }
+
+  void removeListener(void callback(AppRuntimeLaunchData launchData)) {
+    void __proxy_callback(launchData) {
+      if (callback != null) {
+        callback(new AppRuntimeLaunchData._proxy(launchData));
+      }
+    }
+
+    super.removeListener(__proxy_callback);
+  }
+
+  bool hasListener(void callback(AppRuntimeLaunchData launchData)) {
+    void __proxy_callback(launchData) {
+      if (callback != null) {
+        callback(new AppRuntimeLaunchData._proxy(launchData));
+      }
+    }
+
+    super.hasListener(__proxy_callback);
+  }
+
+  Event_app_runtime_onLaunched(jsObject) : super._(jsObject, 1);
+}
+
+/// Fired at Chrome startup to apps that were running when Chrome last shut
+/// down.
+class Event_app_runtime_onRestarted extends Event {
+  void addListener(void callback()) => super.addListener(callback);
+
+  void removeListener(void callback()) => super.removeListener(callback);
+
+  bool hasListener(void callback()) => super.hasListener(callback);
+
+  Event_app_runtime_onRestarted(jsObject) : super._(jsObject, 0);
+}
+
+/**
+ * Functions
+ */
+
+class API_app_runtime {
+  /*
+   * API connection
+   */
+  Object _jsObject;
+
+  /*
+   * Events
+   */
+  Event_app_runtime_onLaunched onLaunched;
+  Event_app_runtime_onRestarted onRestarted;
+  API_app_runtime(this._jsObject) {
+    onLaunched = new Event_app_runtime_onLaunched(
+        JS('', '#.onLaunched', this._jsObject));
+    onRestarted = new Event_app_runtime_onRestarted(
+        JS('', '#.onRestarted', this._jsObject));
+  }
+}
+// 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.
+
+// Generated from namespace: fileSystem
+
+/**
+ * Types
+ */
+
+class FilesystemAcceptOption extends ChromeObject {
+  /*
+   * Public constructor
+   */
+  FilesystemAcceptOption(
+      {String description, List<String> mimeTypes, List<String> extensions}) {
+    if (description != null) this.description = description;
+    if (mimeTypes != null) this.mimeTypes = mimeTypes;
+    if (extensions != null) this.extensions = extensions;
+  }
+
+  /*
+   * Private constructor
+   */
+  FilesystemAcceptOption._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+  /// This is the optional text description for this option. If not present, a
+  /// description will be automatically generated; typically containing an
+  /// expanded list of valid extensions (e.g. "text/html" may expand to "*.html,
+  /// *.htm").
+  String get description => JS('String', '#.description', this._jsObject);
+
+  void set description(String description) {
+    JS('void', '#.description = #', this._jsObject, description);
+  }
+
+  /// Mime-types to accept, e.g. "image/jpeg" or "audio/*". One of mimeTypes or
+  /// extensions must contain at least one valid element.
+  List<String> get mimeTypes =>
+      JS('List<String>', '#.mimeTypes', this._jsObject);
+
+  void set mimeTypes(List<String> mimeTypes) {
+    JS('void', '#.mimeTypes = #', this._jsObject, mimeTypes);
+  }
+
+  /// Extensions to accept, e.g. "jpg", "gif", "crx".
+  List<String> get extensions =>
+      JS('List<String>', '#.extensions', this._jsObject);
+
+  void set extensions(List<String> extensions) {
+    JS('void', '#.extensions = #', this._jsObject, extensions);
+  }
+}
+
+class FilesystemChooseEntryOptions extends ChromeObject {
+  /*
+   * Public constructor
+   */
+  FilesystemChooseEntryOptions(
+      {String type,
+      String suggestedName,
+      List<FilesystemAcceptOption> accepts,
+      bool acceptsAllTypes}) {
+    if (type != null) this.type = type;
+    if (suggestedName != null) this.suggestedName = suggestedName;
+    if (accepts != null) this.accepts = accepts;
+    if (acceptsAllTypes != null) this.acceptsAllTypes = acceptsAllTypes;
+  }
+
+  /*
+   * Private constructor
+   */
+  FilesystemChooseEntryOptions._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+  /// Type of the prompt to show. The default is 'openFile'.
+  String get type => JS('String', '#.type', this._jsObject);
+
+  void set type(String type) {
+    JS('void', '#.type = #', this._jsObject, type);
+  }
+
+  /// The suggested file name that will be presented to the user as the default
+  /// name to read or write. This is optional.
+  String get suggestedName => JS('String', '#.suggestedName', this._jsObject);
+
+  void set suggestedName(String suggestedName) {
+    JS('void', '#.suggestedName = #', this._jsObject, suggestedName);
+  }
+
+  /// The optional list of accept options for this file opener. Each option will
+  /// be presented as a unique group to the end-user.
+  List<FilesystemAcceptOption> get accepts {
+    List<FilesystemAcceptOption> __proxy_accepts =
+        new List<FilesystemAcceptOption>();
+    int count = JS('int', '#.accepts.length', this._jsObject);
+    for (int i = 0; i < count; i++) {
+      var item = JS('', '#.accepts[#]', this._jsObject, i);
+      __proxy_accepts.add(new FilesystemAcceptOption._proxy(item));
+    }
+    return __proxy_accepts;
+  }
+
+  void set accepts(List<FilesystemAcceptOption> accepts) {
+    JS('void', '#.accepts = #', this._jsObject, convertArgument(accepts));
+  }
+
+  /// Whether to accept all file types, in addition to the options specified in
+  /// the accepts argument. The default is true. If the accepts field is unset or
+  /// contains no valid entries, this will always be reset to true.
+  bool get acceptsAllTypes => JS('bool', '#.acceptsAllTypes', this._jsObject);
+
+  void set acceptsAllTypes(bool acceptsAllTypes) {
+    JS('void', '#.acceptsAllTypes = #', this._jsObject, acceptsAllTypes);
+  }
+}
+
+/**
+ * Functions
+ */
+
+class API_file_system {
+  /*
+   * API connection
+   */
+  Object _jsObject;
+
+  /*
+   * Functions
+   */
+  /// Get the display path of a FileEntry object. The display path is based on
+  /// the full path of the file on the local file system, but may be made more
+  /// readable for display purposes.
+  void getDisplayPath(FileEntry fileEntry, void callback(String displayPath)) =>
+      JS('void', '#.getDisplayPath(#, #)', this._jsObject,
+          convertArgument(fileEntry), convertDartClosureToJS(callback, 1));
+
+  /// Get a writable FileEntry from another FileEntry. This call will fail if the
+  /// application does not have the 'write' permission under 'fileSystem'.
+  void getWritableEntry(
+      FileEntry fileEntry, void callback(FileEntry fileEntry)) {
+    void __proxy_callback(fileEntry) {
+      if (callback != null) {
+        callback(fileEntry);
+      }
+    }
+
+    JS(
+        'void',
+        '#.getWritableEntry(#, #)',
+        this._jsObject,
+        convertArgument(fileEntry),
+        convertDartClosureToJS(__proxy_callback, 1));
+  }
+
+  /// Gets whether this FileEntry is writable or not.
+  void isWritableEntry(FileEntry fileEntry, void callback(bool isWritable)) =>
+      JS('void', '#.isWritableEntry(#, #)', this._jsObject,
+          convertArgument(fileEntry), convertDartClosureToJS(callback, 1));
+
+  /// Ask the user to choose a file.
+  void chooseEntry(void callback(FileEntry fileEntry),
+      [FilesystemChooseEntryOptions options]) {
+    void __proxy_callback(fileEntry) {
+      if (callback != null) {
+        callback(fileEntry);
+      }
+    }
+
+    JS('void', '#.chooseEntry(#, #)', this._jsObject, convertArgument(options),
+        convertDartClosureToJS(__proxy_callback, 1));
+  }
+
+  /// Returns the file entry with the given id if it can be restored. This call
+  /// will fail otherwise.
+  void restoreEntry(String id, void callback(FileEntry fileEntry)) {
+    void __proxy_callback(fileEntry) {
+      if (callback != null) {
+        callback(fileEntry);
+      }
+    }
+
+    JS('void', '#.restoreEntry(#, #)', this._jsObject, id,
+        convertDartClosureToJS(__proxy_callback, 1));
+  }
+
+  /// Returns whether a file entry for the given id can be restored, i.e. whether
+  /// restoreEntry would succeed with this id now.
+  void isRestorable(String id, void callback(bool isRestorable)) => JS(
+      'void',
+      '#.isRestorable(#, #)',
+      this._jsObject,
+      id,
+      convertDartClosureToJS(callback, 1));
+
+  /// Returns an id that can be passed to restoreEntry to regain access to a
+  /// given file entry. Only the 500 most recently used entries are retained,
+  /// where calls to retainEntry and restoreEntry count as use. If the app has
+  /// the 'retainEntries' permission under 'fileSystem', entries are retained
+  /// indefinitely. Otherwise, entries are retained only while the app is running
+  /// and across restarts.
+  String retainEntry(FileEntry fileEntry) => JS(
+      'String', '#.retainEntry(#)', this._jsObject, convertArgument(fileEntry));
+
+  API_file_system(this._jsObject) {}
+}
diff --git a/sdk_nnbd/lib/_http/crypto.dart b/sdk_nnbd/lib/_http/crypto.dart
new file mode 100644
index 0000000..28b65ee
--- /dev/null
+++ b/sdk_nnbd/lib/_http/crypto.dart
@@ -0,0 +1,458 @@
+// Copyright (c) 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 dart._http;
+
+class _CryptoUtils {
+  static const int PAD = 61; // '='
+  static const int CR = 13; // '\r'
+  static const int LF = 10; // '\n'
+  static const int LINE_LENGTH = 76;
+
+  static const String _encodeTable =
+      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+  static const String _encodeTableUrlSafe =
+      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+
+  // Lookup table used for finding Base 64 alphabet index of a given byte.
+  // -2 : Outside Base 64 alphabet.
+  // -1 : '\r' or '\n'
+  //  0 : = (Padding character).
+  // >0 : Base 64 alphabet index of given byte.
+  static const List<int> _decodeTable = const [
+    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -2, -2, -1, -2, -2, //
+    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
+    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, 62, -2, 63, //
+    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, 00, -2, -2, //
+    -2, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, //
+    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, 63, //
+    -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, //
+    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2, //
+    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
+    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
+    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
+    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
+    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
+    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
+    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
+    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2
+  ];
+
+  static Random _rng = new Random.secure();
+
+  static Uint8List getRandomBytes(int count) {
+    final Uint8List result = new Uint8List(count);
+    for (int i = 0; i < count; i++) {
+      result[i] = _rng.nextInt(0xff);
+    }
+    return result;
+  }
+
+  static String bytesToHex(List<int> bytes) {
+    var result = new StringBuffer();
+    for (var part in bytes) {
+      result.write('${part < 16 ? '0' : ''}${part.toRadixString(16)}');
+    }
+    return result.toString();
+  }
+
+  static String bytesToBase64(List<int> bytes,
+      [bool urlSafe = false, bool addLineSeparator = false]) {
+    int len = bytes.length;
+    if (len == 0) {
+      return "";
+    }
+    final String lookup = urlSafe ? _encodeTableUrlSafe : _encodeTable;
+    // Size of 24 bit chunks.
+    final int remainderLength = len.remainder(3);
+    final int chunkLength = len - remainderLength;
+    // Size of base output.
+    int outputLen = ((len ~/ 3) * 4) + ((remainderLength > 0) ? 4 : 0);
+    // Add extra for line separators.
+    if (addLineSeparator) {
+      outputLen += ((outputLen - 1) ~/ LINE_LENGTH) << 1;
+    }
+    List<int> out = new List<int>(outputLen);
+
+    // Encode 24 bit chunks.
+    int j = 0, i = 0, c = 0;
+    while (i < chunkLength) {
+      int x = ((bytes[i++] << 16) & 0xFFFFFF) |
+          ((bytes[i++] << 8) & 0xFFFFFF) |
+          bytes[i++];
+      out[j++] = lookup.codeUnitAt(x >> 18);
+      out[j++] = lookup.codeUnitAt((x >> 12) & 0x3F);
+      out[j++] = lookup.codeUnitAt((x >> 6) & 0x3F);
+      out[j++] = lookup.codeUnitAt(x & 0x3f);
+      // Add optional line separator for each 76 char output.
+      if (addLineSeparator && ++c == 19 && j < outputLen - 2) {
+        out[j++] = CR;
+        out[j++] = LF;
+        c = 0;
+      }
+    }
+
+    // If input length if not a multiple of 3, encode remaining bytes and
+    // add padding.
+    if (remainderLength == 1) {
+      int x = bytes[i];
+      out[j++] = lookup.codeUnitAt(x >> 2);
+      out[j++] = lookup.codeUnitAt((x << 4) & 0x3F);
+      out[j++] = PAD;
+      out[j++] = PAD;
+    } else if (remainderLength == 2) {
+      int x = bytes[i];
+      int y = bytes[i + 1];
+      out[j++] = lookup.codeUnitAt(x >> 2);
+      out[j++] = lookup.codeUnitAt(((x << 4) | (y >> 4)) & 0x3F);
+      out[j++] = lookup.codeUnitAt((y << 2) & 0x3F);
+      out[j++] = PAD;
+    }
+
+    return new String.fromCharCodes(out);
+  }
+
+  static List<int> base64StringToBytes(String input,
+      [bool ignoreInvalidCharacters = true]) {
+    int len = input.length;
+    if (len == 0) {
+      return new List<int>(0);
+    }
+
+    // Count '\r', '\n' and illegal characters, For illegal characters,
+    // if [ignoreInvalidCharacters] is false, throw an exception.
+    int extrasLen = 0;
+    for (int i = 0; i < len; i++) {
+      int c = _decodeTable[input.codeUnitAt(i)];
+      if (c < 0) {
+        extrasLen++;
+        if (c == -2 && !ignoreInvalidCharacters) {
+          throw new FormatException('Invalid character: ${input[i]}');
+        }
+      }
+    }
+
+    if ((len - extrasLen) % 4 != 0) {
+      throw new FormatException('''Size of Base 64 characters in Input
+          must be a multiple of 4. Input: $input''');
+    }
+
+    // Count pad characters, ignore illegal characters at the end.
+    int padLength = 0;
+    for (int i = len - 1; i >= 0; i--) {
+      int currentCodeUnit = input.codeUnitAt(i);
+      if (_decodeTable[currentCodeUnit] > 0) break;
+      if (currentCodeUnit == PAD) padLength++;
+    }
+    int outputLen = (((len - extrasLen) * 6) >> 3) - padLength;
+    List<int> out = new List<int>(outputLen);
+
+    for (int i = 0, o = 0; o < outputLen;) {
+      // Accumulate 4 valid 6 bit Base 64 characters into an int.
+      int x = 0;
+      for (int j = 4; j > 0;) {
+        int c = _decodeTable[input.codeUnitAt(i++)];
+        if (c >= 0) {
+          x = ((x << 6) & 0xFFFFFF) | c;
+          j--;
+        }
+      }
+      out[o++] = x >> 16;
+      if (o < outputLen) {
+        out[o++] = (x >> 8) & 0xFF;
+        if (o < outputLen) out[o++] = x & 0xFF;
+      }
+    }
+    return out;
+  }
+}
+
+// Constants.
+const _MASK_8 = 0xff;
+const _MASK_32 = 0xffffffff;
+const _BITS_PER_BYTE = 8;
+const _BYTES_PER_WORD = 4;
+
+// Base class encapsulating common behavior for cryptographic hash
+// functions.
+abstract class _HashBase {
+  // Hasher state.
+  final int _chunkSizeInWords;
+  final int _digestSizeInWords;
+  final bool _bigEndianWords;
+  int _lengthInBytes = 0;
+  List<int> _pendingData;
+  List<int> _currentChunk;
+  List<int> _h;
+  bool _digestCalled = false;
+
+  _HashBase(
+      this._chunkSizeInWords, this._digestSizeInWords, this._bigEndianWords)
+      : _pendingData = [] {
+    _currentChunk = new List(_chunkSizeInWords);
+    _h = new List(_digestSizeInWords);
+  }
+
+  // Update the hasher with more data.
+  add(List<int> data) {
+    if (_digestCalled) {
+      throw new StateError(
+          'Hash update method called after digest was retrieved');
+    }
+    _lengthInBytes += data.length;
+    _pendingData.addAll(data);
+    _iterate();
+  }
+
+  // Finish the hash computation and return the digest string.
+  List<int> close() {
+    if (_digestCalled) {
+      return _resultAsBytes();
+    }
+    _digestCalled = true;
+    _finalizeData();
+    _iterate();
+    assert(_pendingData.length == 0);
+    return _resultAsBytes();
+  }
+
+  // Returns the block size of the hash in bytes.
+  int get blockSize {
+    return _chunkSizeInWords * _BYTES_PER_WORD;
+  }
+
+  // Create a fresh instance of this Hash.
+  newInstance();
+
+  // One round of the hash computation.
+  _updateHash(List<int> m);
+
+  // Helper methods.
+  _add32(x, y) => (x + y) & _MASK_32;
+  _roundUp(val, n) => (val + n - 1) & -n;
+
+  // Rotate left limiting to unsigned 32-bit values.
+  int _rotl32(int val, int shift) {
+    var mod_shift = shift & 31;
+    return ((val << mod_shift) & _MASK_32) |
+        ((val & _MASK_32) >> (32 - mod_shift));
+  }
+
+  // Compute the final result as a list of bytes from the hash words.
+  List<int> _resultAsBytes() {
+    var result = <int>[];
+    for (var i = 0; i < _h.length; i++) {
+      result.addAll(_wordToBytes(_h[i]));
+    }
+    return result;
+  }
+
+  // Converts a list of bytes to a chunk of 32-bit words.
+  _bytesToChunk(List<int> data, int dataIndex) {
+    assert((data.length - dataIndex) >= (_chunkSizeInWords * _BYTES_PER_WORD));
+
+    for (var wordIndex = 0; wordIndex < _chunkSizeInWords; wordIndex++) {
+      var w3 = _bigEndianWords ? data[dataIndex] : data[dataIndex + 3];
+      var w2 = _bigEndianWords ? data[dataIndex + 1] : data[dataIndex + 2];
+      var w1 = _bigEndianWords ? data[dataIndex + 2] : data[dataIndex + 1];
+      var w0 = _bigEndianWords ? data[dataIndex + 3] : data[dataIndex];
+      dataIndex += 4;
+      var word = (w3 & 0xff) << 24;
+      word |= (w2 & _MASK_8) << 16;
+      word |= (w1 & _MASK_8) << 8;
+      word |= (w0 & _MASK_8);
+      _currentChunk[wordIndex] = word;
+    }
+  }
+
+  // Convert a 32-bit word to four bytes.
+  List<int> _wordToBytes(int word) {
+    List<int> bytes = new List(_BYTES_PER_WORD);
+    bytes[0] = (word >> (_bigEndianWords ? 24 : 0)) & _MASK_8;
+    bytes[1] = (word >> (_bigEndianWords ? 16 : 8)) & _MASK_8;
+    bytes[2] = (word >> (_bigEndianWords ? 8 : 16)) & _MASK_8;
+    bytes[3] = (word >> (_bigEndianWords ? 0 : 24)) & _MASK_8;
+    return bytes;
+  }
+
+  // Iterate through data updating the hash computation for each
+  // chunk.
+  _iterate() {
+    var len = _pendingData.length;
+    var chunkSizeInBytes = _chunkSizeInWords * _BYTES_PER_WORD;
+    if (len >= chunkSizeInBytes) {
+      var index = 0;
+      for (; (len - index) >= chunkSizeInBytes; index += chunkSizeInBytes) {
+        _bytesToChunk(_pendingData, index);
+        _updateHash(_currentChunk);
+      }
+      _pendingData = _pendingData.sublist(index, len);
+    }
+  }
+
+  // Finalize the data. Add a 1 bit to the end of the message. Expand with
+  // 0 bits and add the length of the message.
+  _finalizeData() {
+    _pendingData.add(0x80);
+    var contentsLength = _lengthInBytes + 9;
+    var chunkSizeInBytes = _chunkSizeInWords * _BYTES_PER_WORD;
+    var finalizedLength = _roundUp(contentsLength, chunkSizeInBytes);
+    var zeroPadding = finalizedLength - contentsLength;
+    for (var i = 0; i < zeroPadding; i++) {
+      _pendingData.add(0);
+    }
+    var lengthInBits = _lengthInBytes * _BITS_PER_BYTE;
+    assert(lengthInBits < pow(2, 32));
+    if (_bigEndianWords) {
+      _pendingData.addAll(_wordToBytes(0));
+      _pendingData.addAll(_wordToBytes(lengthInBits & _MASK_32));
+    } else {
+      _pendingData.addAll(_wordToBytes(lengthInBits & _MASK_32));
+      _pendingData.addAll(_wordToBytes(0));
+    }
+  }
+}
+
+// The MD5 hasher is used to compute an MD5 message digest.
+class _MD5 extends _HashBase {
+  _MD5() : super(16, 4, false) {
+    _h[0] = 0x67452301;
+    _h[1] = 0xefcdab89;
+    _h[2] = 0x98badcfe;
+    _h[3] = 0x10325476;
+  }
+
+  // Returns a new instance of this Hash.
+  _MD5 newInstance() {
+    return new _MD5();
+  }
+
+  static const _k = const [
+    0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, //
+    0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, //
+    0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, //
+    0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, //
+    0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, //
+    0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, //
+    0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, //
+    0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, //
+    0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, //
+    0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, //
+    0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
+  ];
+
+  static const _r = const [
+    7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, //
+    20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, //
+    16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, //
+    10, 15, 21, 6, 10, 15, 21
+  ];
+
+  // Compute one iteration of the MD5 algorithm with a chunk of
+  // 16 32-bit pieces.
+  void _updateHash(List<int> m) {
+    assert(m.length == 16);
+
+    var a = _h[0];
+    var b = _h[1];
+    var c = _h[2];
+    var d = _h[3];
+
+    var t0;
+    var t1;
+
+    for (var i = 0; i < 64; i++) {
+      if (i < 16) {
+        t0 = (b & c) | ((~b & _MASK_32) & d);
+        t1 = i;
+      } else if (i < 32) {
+        t0 = (d & b) | ((~d & _MASK_32) & c);
+        t1 = ((5 * i) + 1) % 16;
+      } else if (i < 48) {
+        t0 = b ^ c ^ d;
+        t1 = ((3 * i) + 5) % 16;
+      } else {
+        t0 = c ^ (b | (~d & _MASK_32));
+        t1 = (7 * i) % 16;
+      }
+
+      var temp = d;
+      d = c;
+      c = b;
+      b = _add32(
+          b, _rotl32(_add32(_add32(a, t0), _add32(_k[i], m[t1])), _r[i]));
+      a = temp;
+    }
+
+    _h[0] = _add32(a, _h[0]);
+    _h[1] = _add32(b, _h[1]);
+    _h[2] = _add32(c, _h[2]);
+    _h[3] = _add32(d, _h[3]);
+  }
+}
+
+// The SHA1 hasher is used to compute an SHA1 message digest.
+class _SHA1 extends _HashBase {
+  // Construct a SHA1 hasher object.
+  _SHA1()
+      : _w = new List(80),
+        super(16, 5, true) {
+    _h[0] = 0x67452301;
+    _h[1] = 0xEFCDAB89;
+    _h[2] = 0x98BADCFE;
+    _h[3] = 0x10325476;
+    _h[4] = 0xC3D2E1F0;
+  }
+
+  // Returns a new instance of this Hash.
+  _SHA1 newInstance() {
+    return new _SHA1();
+  }
+
+  // Compute one iteration of the SHA1 algorithm with a chunk of
+  // 16 32-bit pieces.
+  void _updateHash(List<int> m) {
+    assert(m.length == 16);
+
+    var a = _h[0];
+    var b = _h[1];
+    var c = _h[2];
+    var d = _h[3];
+    var e = _h[4];
+
+    for (var i = 0; i < 80; i++) {
+      if (i < 16) {
+        _w[i] = m[i];
+      } else {
+        var n = _w[i - 3] ^ _w[i - 8] ^ _w[i - 14] ^ _w[i - 16];
+        _w[i] = _rotl32(n, 1);
+      }
+      var t = _add32(_add32(_rotl32(a, 5), e), _w[i]);
+      if (i < 20) {
+        t = _add32(_add32(t, (b & c) | (~b & d)), 0x5A827999);
+      } else if (i < 40) {
+        t = _add32(_add32(t, (b ^ c ^ d)), 0x6ED9EBA1);
+      } else if (i < 60) {
+        t = _add32(_add32(t, (b & c) | (b & d) | (c & d)), 0x8F1BBCDC);
+      } else {
+        t = _add32(_add32(t, b ^ c ^ d), 0xCA62C1D6);
+      }
+
+      e = d;
+      d = c;
+      c = _rotl32(b, 30);
+      b = a;
+      a = t & _MASK_32;
+    }
+
+    _h[0] = _add32(a, _h[0]);
+    _h[1] = _add32(b, _h[1]);
+    _h[2] = _add32(c, _h[2]);
+    _h[3] = _add32(d, _h[3]);
+    _h[4] = _add32(e, _h[4]);
+  }
+
+  List<int> _w;
+}
diff --git a/sdk_nnbd/lib/_http/http.dart b/sdk_nnbd/lib/_http/http.dart
new file mode 100644
index 0000000..2fc751f
--- /dev/null
+++ b/sdk_nnbd/lib/_http/http.dart
@@ -0,0 +1,2196 @@
+// 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 dart._http;
+
+import 'dart:async';
+import 'dart:collection'
+    show
+        HashMap,
+        HashSet,
+        Queue,
+        ListQueue,
+        LinkedList,
+        LinkedListEntry,
+        UnmodifiableMapView;
+import 'dart:convert';
+import 'dart:developer' hide log;
+import 'dart:_internal' show Since, HttpStatus;
+import 'dart:math';
+import 'dart:io';
+import 'dart:typed_data';
+
+part 'crypto.dart';
+part 'http_date.dart';
+part 'http_headers.dart';
+part 'http_impl.dart';
+part 'http_parser.dart';
+part 'http_session.dart';
+part 'overrides.dart';
+part 'websocket.dart';
+part 'websocket_impl.dart';
+
+/**
+ * A server that delivers content, such as web pages, using the HTTP protocol.
+ *
+ * The HttpServer is a [Stream] that provides [HttpRequest] objects. Each
+ * HttpRequest has an associated [HttpResponse] object.
+ * The server responds to a request by writing to that HttpResponse object.
+ * The following example shows how to bind an HttpServer to an IPv6
+ * [InternetAddress] on port 80 (the standard port for HTTP servers)
+ * and how to listen for requests.
+ * Port 80 is the default HTTP port. However, on most systems accessing
+ * this requires super-user privileges. For local testing consider
+ * using a non-reserved port (1024 and above).
+ *
+ *     import 'dart:io';
+ *
+ *     main() {
+ *       HttpServer
+ *           .bind(InternetAddress.anyIPv6, 80)
+ *           .then((server) {
+ *             server.listen((HttpRequest request) {
+ *               request.response.write('Hello, world!');
+ *               request.response.close();
+ *             });
+ *           });
+ *     }
+ *
+ * Incomplete requests, in which all or part of the header is missing, are
+ * ignored, and no exceptions or HttpRequest objects are generated for them.
+ * Likewise, when writing to an HttpResponse, any [Socket] exceptions are
+ * ignored and any future writes are ignored.
+ *
+ * The HttpRequest exposes the request headers and provides the request body,
+ * if it exists, as a Stream of data. If the body is unread, it is drained
+ * when the server writes to the HttpResponse or closes it.
+ *
+ * ## Bind with a secure HTTPS connection
+ *
+ * Use [bindSecure] to create an HTTPS server.
+ *
+ * The server presents a certificate to the client. The certificate
+ * chain and the private key are set in the [SecurityContext]
+ * object that is passed to [bindSecure].
+ *
+ *     import 'dart:io';
+ *     import "dart:isolate";
+ *
+ *     main() {
+ *       SecurityContext context = new SecurityContext();
+ *       var chain =
+ *           Platform.script.resolve('certificates/server_chain.pem')
+ *           .toFilePath();
+ *       var key =
+ *           Platform.script.resolve('certificates/server_key.pem')
+ *           .toFilePath();
+ *       context.useCertificateChain(chain);
+ *       context.usePrivateKey(key, password: 'dartdart');
+ *
+ *       HttpServer
+ *           .bindSecure(InternetAddress.anyIPv6,
+ *                       443,
+ *                       context)
+ *           .then((server) {
+ *             server.listen((HttpRequest request) {
+ *               request.response.write('Hello, world!');
+ *               request.response.close();
+ *             });
+ *           });
+ *     }
+ *
+ *  The certificates and keys are PEM files, which can be created and
+ *  managed with the tools in OpenSSL.
+ *
+ * ## Connect to a server socket
+ *
+ * You can use the [listenOn] constructor to attach an HTTP server to
+ * a [ServerSocket].
+ *
+ *     import 'dart:io';
+ *
+ *     main() {
+ *       ServerSocket.bind(InternetAddress.anyIPv6, 80)
+ *         .then((serverSocket) {
+ *           HttpServer httpserver = new HttpServer.listenOn(serverSocket);
+ *           serverSocket.listen((Socket socket) {
+ *             socket.write('Hello, client.');
+ *           });
+ *         });
+ *     }
+ *
+ * ## Other resources
+ *
+ * * HttpServer is a Stream. Refer to the [Stream] class for information
+ * about the streaming qualities of an HttpServer.
+ * Pausing the subscription of the stream, pauses at the OS level.
+ *
+ * * The [shelf](https://pub.dartlang.org/packages/shelf)
+ * package on pub.dartlang.org contains a set of high-level classes that,
+ * together with this class, makes it easy to provide content through HTTP
+ * servers.
+ */
+abstract class HttpServer implements Stream<HttpRequest> {
+  /**
+   * Gets and sets the default value of the `Server` header for all responses
+   * generated by this [HttpServer].
+   *
+   * If [serverHeader] is `null`, no `Server` header will be added to each
+   * response.
+   *
+   * The default value is `null`.
+   */
+  String serverHeader;
+
+  /**
+   * Default set of headers added to all response objects.
+   *
+   * By default the following headers are in this set:
+   *
+   *     Content-Type: text/plain; charset=utf-8
+   *     X-Frame-Options: SAMEORIGIN
+   *     X-Content-Type-Options: nosniff
+   *     X-XSS-Protection: 1; mode=block
+   *
+   * If the `Server` header is added here and the `serverHeader` is set as
+   * well then the value of `serverHeader` takes precedence.
+   */
+  HttpHeaders get defaultResponseHeaders;
+
+  /**
+   * Whether the [HttpServer] should compress the content, if possible.
+   *
+   * The content can only be compressed when the response is using
+   * chunked Transfer-Encoding and the incoming request has `gzip`
+   * as an accepted encoding in the Accept-Encoding header.
+   *
+   * The default value is `false` (compression disabled).
+   * To enable, set `autoCompress` to `true`.
+   */
+  bool autoCompress;
+
+  /**
+   * Gets or sets the timeout used for idle keep-alive connections. If no
+   * further request is seen within [idleTimeout] after the previous request was
+   * completed, the connection is dropped.
+   *
+   * Default is 120 seconds.
+   *
+   * Note that it may take up to `2 * idleTimeout` before a idle connection is
+   * aborted.
+   *
+   * To disable, set [idleTimeout] to `null`.
+   */
+  Duration idleTimeout;
+
+  /**
+   * Starts listening for HTTP requests on the specified [address] and
+   * [port].
+   *
+   * The [address] can either be a [String] or an
+   * [InternetAddress]. If [address] is a [String], [bind] will
+   * perform a [InternetAddress.lookup] and use the first value in the
+   * list. To listen on the loopback adapter, which will allow only
+   * incoming connections from the local host, use the value
+   * [InternetAddress.loopbackIPv4] or
+   * [InternetAddress.loopbackIPv6]. To allow for incoming
+   * connection from the network use either one of the values
+   * [InternetAddress.anyIPv4] or [InternetAddress.anyIPv6] to
+   * bind to all interfaces or the IP address of a specific interface.
+   *
+   * If an IP version 6 (IPv6) address is used, both IP version 6
+   * (IPv6) and version 4 (IPv4) connections will be accepted. To
+   * restrict this to version 6 (IPv6) only, use [v6Only] to set
+   * version 6 only. However, if the address is
+   * [InternetAddress.loopbackIPv6], only IP version 6 (IPv6) connections
+   * will be accepted.
+   *
+   * If [port] has the value [:0:] an ephemeral port will be chosen by
+   * the system. The actual port used can be retrieved using the
+   * [port] getter.
+   *
+   * The optional argument [backlog] can be used to specify the listen
+   * backlog for the underlying OS listen setup. If [backlog] has the
+   * value of [:0:] (the default) a reasonable value will be chosen by
+   * the system.
+   *
+   * The optional argument [shared] specifies whether additional HttpServer
+   * objects can bind to the same combination of `address`, `port` and `v6Only`.
+   * If `shared` is `true` and more `HttpServer`s from this isolate or other
+   * isolates are bound to the port, then the incoming connections will be
+   * distributed among all the bound `HttpServer`s. Connections can be
+   * distributed over multiple isolates this way.
+   */
+  static Future<HttpServer> bind(address, int port,
+          {int backlog: 0, bool v6Only: false, bool shared: false}) =>
+      _HttpServer.bind(address, port, backlog, v6Only, shared);
+
+  /**
+   * The [address] can either be a [String] or an
+   * [InternetAddress]. If [address] is a [String], [bind] will
+   * perform a [InternetAddress.lookup] and use the first value in the
+   * list. To listen on the loopback adapter, which will allow only
+   * incoming connections from the local host, use the value
+   * [InternetAddress.loopbackIPv4] or
+   * [InternetAddress.loopbackIPv6]. To allow for incoming
+   * connection from the network use either one of the values
+   * [InternetAddress.anyIPv4] or [InternetAddress.anyIPv6] to
+   * bind to all interfaces or the IP address of a specific interface.
+   *
+   * If an IP version 6 (IPv6) address is used, both IP version 6
+   * (IPv6) and version 4 (IPv4) connections will be accepted. To
+   * restrict this to version 6 (IPv6) only, use [v6Only] to set
+   * version 6 only.
+   *
+   * If [port] has the value [:0:] an ephemeral port will be chosen by
+   * the system. The actual port used can be retrieved using the
+   * [port] getter.
+   *
+   * The optional argument [backlog] can be used to specify the listen
+   * backlog for the underlying OS listen setup. If [backlog] has the
+   * value of [:0:] (the default) a reasonable value will be chosen by
+   * the system.
+   *
+   * If [requestClientCertificate] is true, the server will
+   * request clients to authenticate with a client certificate.
+   * The server will advertise the names of trusted issuers of client
+   * certificates, getting them from a [SecurityContext], where they have been
+   * set using [SecurityContext.setClientAuthorities].
+   *
+   * The optional argument [shared] specifies whether additional HttpServer
+   * objects can bind to the same combination of `address`, `port` and `v6Only`.
+   * If `shared` is `true` and more `HttpServer`s from this isolate or other
+   * isolates are bound to the port, then the incoming connections will be
+   * distributed among all the bound `HttpServer`s. Connections can be
+   * distributed over multiple isolates this way.
+   */
+
+  static Future<HttpServer> bindSecure(
+          address, int port, SecurityContext context,
+          {int backlog: 0,
+          bool v6Only: false,
+          bool requestClientCertificate: false,
+          bool shared: false}) =>
+      _HttpServer.bindSecure(address, port, context, backlog, v6Only,
+          requestClientCertificate, shared);
+
+  /**
+   * Attaches the HTTP server to an existing [ServerSocket]. When the
+   * [HttpServer] is closed, the [HttpServer] will just detach itself,
+   * closing current connections but not closing [serverSocket].
+   */
+  factory HttpServer.listenOn(ServerSocket serverSocket) =>
+      new _HttpServer.listenOn(serverSocket);
+
+  /**
+   * Permanently stops this [HttpServer] from listening for new
+   * connections.  This closes the [Stream] of [HttpRequest]s with a
+   * done event. The returned future completes when the server is
+   * stopped. For a server started using [bind] or [bindSecure] this
+   * means that the port listened on no longer in use.
+   *
+   * If [force] is `true`, active connections will be closed immediately.
+   */
+  Future close({bool force: false});
+
+  /**
+   * Returns the port that the server is listening on. This can be
+   * used to get the actual port used when a value of 0 for [:port:] is
+   * specified in the [bind] or [bindSecure] call.
+   */
+  int get port;
+
+  /**
+   * Returns the address that the server is listening on. This can be
+   * used to get the actual address used, when the address is fetched by
+   * a lookup from a hostname.
+   */
+  InternetAddress get address;
+
+  /**
+   * Sets the timeout, in seconds, for sessions of this [HttpServer].
+   * The default timeout is 20 minutes.
+   */
+  set sessionTimeout(int timeout);
+
+  /**
+   * Returns an [HttpConnectionsInfo] object summarizing the number of
+   * current connections handled by the server.
+   */
+  HttpConnectionsInfo connectionsInfo();
+}
+
+/**
+ * Summary statistics about an [HttpServer]s current socket connections.
+ */
+class HttpConnectionsInfo {
+  /**
+   * Total number of socket connections.
+   */
+  int total = 0;
+
+  /**
+   * Number of active connections where actual request/response
+   * processing is active.
+   */
+  int active = 0;
+
+  /**
+   * Number of idle connections held by clients as persistent connections.
+   */
+  int idle = 0;
+
+  /**
+   * Number of connections which are preparing to close. Note: These
+   * connections are also part of the [:active:] count as they might
+   * still be sending data to the client before finally closing.
+   */
+  int closing = 0;
+}
+
+/**
+ * Headers for HTTP requests and responses.
+ *
+ * In some situations, headers are immutable:
+ *
+ * * HttpRequest and HttpClientResponse always have immutable headers.
+ *
+ * * HttpResponse and HttpClientRequest have immutable headers
+ *   from the moment the body is written to.
+ *
+ * In these situations, the mutating methods throw exceptions.
+ *
+ * For all operations on HTTP headers the header name is
+ * case-insensitive.
+ *
+ * To set the value of a header use the `set()` method:
+ *
+ *     request.headers.set(HttpHeaders.cacheControlHeader,
+ *                         'max-age=3600, must-revalidate');
+ *
+ * To retrieve the value of a header use the `value()` method:
+ *
+ *     print(request.headers.value(HttpHeaders.userAgentHeader));
+ *
+ * An HttpHeaders object holds a list of values for each name
+ * as the standard allows. In most cases a name holds only a single value,
+ * The most common mode of operation is to use `set()` for setting a value,
+ * and `value()` for retrieving a value.
+ */
+abstract class HttpHeaders {
+  static const acceptHeader = "accept";
+  static const acceptCharsetHeader = "accept-charset";
+  static const acceptEncodingHeader = "accept-encoding";
+  static const acceptLanguageHeader = "accept-language";
+  static const acceptRangesHeader = "accept-ranges";
+  static const ageHeader = "age";
+  static const allowHeader = "allow";
+  static const authorizationHeader = "authorization";
+  static const cacheControlHeader = "cache-control";
+  static const connectionHeader = "connection";
+  static const contentEncodingHeader = "content-encoding";
+  static const contentLanguageHeader = "content-language";
+  static const contentLengthHeader = "content-length";
+  static const contentLocationHeader = "content-location";
+  static const contentMD5Header = "content-md5";
+  static const contentRangeHeader = "content-range";
+  static const contentTypeHeader = "content-type";
+  static const dateHeader = "date";
+  static const etagHeader = "etag";
+  static const expectHeader = "expect";
+  static const expiresHeader = "expires";
+  static const fromHeader = "from";
+  static const hostHeader = "host";
+  static const ifMatchHeader = "if-match";
+  static const ifModifiedSinceHeader = "if-modified-since";
+  static const ifNoneMatchHeader = "if-none-match";
+  static const ifRangeHeader = "if-range";
+  static const ifUnmodifiedSinceHeader = "if-unmodified-since";
+  static const lastModifiedHeader = "last-modified";
+  static const locationHeader = "location";
+  static const maxForwardsHeader = "max-forwards";
+  static const pragmaHeader = "pragma";
+  static const proxyAuthenticateHeader = "proxy-authenticate";
+  static const proxyAuthorizationHeader = "proxy-authorization";
+  static const rangeHeader = "range";
+  static const refererHeader = "referer";
+  static const retryAfterHeader = "retry-after";
+  static const serverHeader = "server";
+  static const teHeader = "te";
+  static const trailerHeader = "trailer";
+  static const transferEncodingHeader = "transfer-encoding";
+  static const upgradeHeader = "upgrade";
+  static const userAgentHeader = "user-agent";
+  static const varyHeader = "vary";
+  static const viaHeader = "via";
+  static const warningHeader = "warning";
+  static const wwwAuthenticateHeader = "www-authenticate";
+
+  @Deprecated("Use acceptHeader instead")
+  static const ACCEPT = acceptHeader;
+  @Deprecated("Use acceptCharsetHeader instead")
+  static const ACCEPT_CHARSET = acceptCharsetHeader;
+  @Deprecated("Use acceptEncodingHeader instead")
+  static const ACCEPT_ENCODING = acceptEncodingHeader;
+  @Deprecated("Use acceptLanguageHeader instead")
+  static const ACCEPT_LANGUAGE = acceptLanguageHeader;
+  @Deprecated("Use acceptRangesHeader instead")
+  static const ACCEPT_RANGES = acceptRangesHeader;
+  @Deprecated("Use ageHeader instead")
+  static const AGE = ageHeader;
+  @Deprecated("Use allowHeader instead")
+  static const ALLOW = allowHeader;
+  @Deprecated("Use authorizationHeader instead")
+  static const AUTHORIZATION = authorizationHeader;
+  @Deprecated("Use cacheControlHeader instead")
+  static const CACHE_CONTROL = cacheControlHeader;
+  @Deprecated("Use connectionHeader instead")
+  static const CONNECTION = connectionHeader;
+  @Deprecated("Use contentEncodingHeader instead")
+  static const CONTENT_ENCODING = contentEncodingHeader;
+  @Deprecated("Use contentLanguageHeader instead")
+  static const CONTENT_LANGUAGE = contentLanguageHeader;
+  @Deprecated("Use contentLengthHeader instead")
+  static const CONTENT_LENGTH = contentLengthHeader;
+  @Deprecated("Use contentLocationHeader instead")
+  static const CONTENT_LOCATION = contentLocationHeader;
+  @Deprecated("Use contentMD5Header instead")
+  static const CONTENT_MD5 = contentMD5Header;
+  @Deprecated("Use contentRangeHeader instead")
+  static const CONTENT_RANGE = contentRangeHeader;
+  @Deprecated("Use contentTypeHeader instead")
+  static const CONTENT_TYPE = contentTypeHeader;
+  @Deprecated("Use dateHeader instead")
+  static const DATE = dateHeader;
+  @Deprecated("Use etagHeader instead")
+  static const ETAG = etagHeader;
+  @Deprecated("Use expectHeader instead")
+  static const EXPECT = expectHeader;
+  @Deprecated("Use expiresHeader instead")
+  static const EXPIRES = expiresHeader;
+  @Deprecated("Use fromHeader instead")
+  static const FROM = fromHeader;
+  @Deprecated("Use hostHeader instead")
+  static const HOST = hostHeader;
+  @Deprecated("Use ifMatchHeader instead")
+  static const IF_MATCH = ifMatchHeader;
+  @Deprecated("Use ifModifiedSinceHeader instead")
+  static const IF_MODIFIED_SINCE = ifModifiedSinceHeader;
+  @Deprecated("Use ifNoneMatchHeader instead")
+  static const IF_NONE_MATCH = ifNoneMatchHeader;
+  @Deprecated("Use ifRangeHeader instead")
+  static const IF_RANGE = ifRangeHeader;
+  @Deprecated("Use ifUnmodifiedSinceHeader instead")
+  static const IF_UNMODIFIED_SINCE = ifUnmodifiedSinceHeader;
+  @Deprecated("Use lastModifiedHeader instead")
+  static const LAST_MODIFIED = lastModifiedHeader;
+  @Deprecated("Use locationHeader instead")
+  static const LOCATION = locationHeader;
+  @Deprecated("Use maxForwardsHeader instead")
+  static const MAX_FORWARDS = maxForwardsHeader;
+  @Deprecated("Use pragmaHeader instead")
+  static const PRAGMA = pragmaHeader;
+  @Deprecated("Use proxyAuthenticateHeader instead")
+  static const PROXY_AUTHENTICATE = proxyAuthenticateHeader;
+  @Deprecated("Use proxyAuthorizationHeader instead")
+  static const PROXY_AUTHORIZATION = proxyAuthorizationHeader;
+  @Deprecated("Use rangeHeader instead")
+  static const RANGE = rangeHeader;
+  @Deprecated("Use refererHeader instead")
+  static const REFERER = refererHeader;
+  @Deprecated("Use retryAfterHeader instead")
+  static const RETRY_AFTER = retryAfterHeader;
+  @Deprecated("Use serverHeader instead")
+  static const SERVER = serverHeader;
+  @Deprecated("Use teHeader instead")
+  static const TE = teHeader;
+  @Deprecated("Use trailerHeader instead")
+  static const TRAILER = trailerHeader;
+  @Deprecated("Use transferEncodingHeader instead")
+  static const TRANSFER_ENCODING = transferEncodingHeader;
+  @Deprecated("Use upgradeHeader instead")
+  static const UPGRADE = upgradeHeader;
+  @Deprecated("Use userAgentHeader instead")
+  static const USER_AGENT = userAgentHeader;
+  @Deprecated("Use varyHeader instead")
+  static const VARY = varyHeader;
+  @Deprecated("Use viaHeader instead")
+  static const VIA = viaHeader;
+  @Deprecated("Use warningHeader instead")
+  static const WARNING = warningHeader;
+  @Deprecated("Use wwwAuthenticateHeader instead")
+  static const WWW_AUTHENTICATE = wwwAuthenticateHeader;
+
+  // Cookie headers from RFC 6265.
+  static const cookieHeader = "cookie";
+  static const setCookieHeader = "set-cookie";
+
+  @Deprecated("Use cookieHeader instead")
+  static const COOKIE = cookieHeader;
+  @Deprecated("Use setCookieHeader instead")
+  static const SET_COOKIE = setCookieHeader;
+
+  static const generalHeaders = const [
+    cacheControlHeader,
+    connectionHeader,
+    dateHeader,
+    pragmaHeader,
+    trailerHeader,
+    transferEncodingHeader,
+    upgradeHeader,
+    viaHeader,
+    warningHeader
+  ];
+
+  @Deprecated("Use generalHeaders instead")
+  static const GENERAL_HEADERS = generalHeaders;
+
+  static const entityHeaders = const [
+    allowHeader,
+    contentEncodingHeader,
+    contentLanguageHeader,
+    contentLengthHeader,
+    contentLocationHeader,
+    contentMD5Header,
+    contentRangeHeader,
+    contentTypeHeader,
+    expiresHeader,
+    lastModifiedHeader
+  ];
+
+  @Deprecated("Use entityHeaders instead")
+  static const ENTITY_HEADERS = entityHeaders;
+
+  static const responseHeaders = const [
+    acceptRangesHeader,
+    ageHeader,
+    etagHeader,
+    locationHeader,
+    proxyAuthenticateHeader,
+    retryAfterHeader,
+    serverHeader,
+    varyHeader,
+    wwwAuthenticateHeader
+  ];
+
+  @Deprecated("Use responseHeaders instead")
+  static const RESPONSE_HEADERS = responseHeaders;
+
+  static const requestHeaders = const [
+    acceptHeader,
+    acceptCharsetHeader,
+    acceptEncodingHeader,
+    acceptLanguageHeader,
+    authorizationHeader,
+    expectHeader,
+    fromHeader,
+    hostHeader,
+    ifMatchHeader,
+    ifModifiedSinceHeader,
+    ifNoneMatchHeader,
+    ifRangeHeader,
+    ifUnmodifiedSinceHeader,
+    maxForwardsHeader,
+    proxyAuthorizationHeader,
+    rangeHeader,
+    refererHeader,
+    teHeader,
+    userAgentHeader
+  ];
+
+  @Deprecated("Use requestHeaders instead")
+  static const REQUEST_HEADERS = requestHeaders;
+
+  /**
+   * Gets and sets the date. The value of this property will
+   * reflect the 'date' header.
+   */
+  DateTime date;
+
+  /**
+   * Gets and sets the expiry date. The value of this property will
+   * reflect the 'expires' header.
+   */
+  DateTime expires;
+
+  /**
+   * Gets and sets the "if-modified-since" date. The value of this property will
+   * reflect the "if-modified-since" header.
+   */
+  DateTime ifModifiedSince;
+
+  /**
+   * Gets and sets the host part of the 'host' header for the
+   * connection.
+   */
+  String host;
+
+  /**
+   * Gets and sets the port part of the 'host' header for the
+   * connection.
+   */
+  int port;
+
+  /**
+   * Gets and sets the content type. Note that the content type in the
+   * header will only be updated if this field is set
+   * directly. Mutating the returned current value will have no
+   * effect.
+   */
+  ContentType contentType;
+
+  /**
+   * Gets and sets the content length header value.
+   */
+  int contentLength;
+
+  /**
+   * Gets and sets the persistent connection header value.
+   */
+  bool persistentConnection;
+
+  /**
+   * Gets and sets the chunked transfer encoding header value.
+   */
+  bool chunkedTransferEncoding;
+
+  /**
+   * Returns the list of values for the header named [name]. If there
+   * is no header with the provided name, [:null:] will be returned.
+   */
+  List<String> operator [](String name);
+
+  /**
+   * Convenience method for the value for a single valued header. If
+   * there is no header with the provided name, [:null:] will be
+   * returned. If the header has more than one value an exception is
+   * thrown.
+   */
+  String value(String name);
+
+  /**
+   * Adds a header value. The header named [name] will have the value
+   * [value] added to its list of values. Some headers are single
+   * valued, and for these adding a value will replace the previous
+   * value. If the value is of type DateTime a HTTP date format will be
+   * applied. If the value is a [:List:] each element of the list will
+   * be added separately. For all other types the default [:toString:]
+   * method will be used.
+   */
+  void add(String name, Object value);
+
+  /**
+   * Sets a header. The header named [name] will have all its values
+   * cleared before the value [value] is added as its value.
+   */
+  void set(String name, Object value);
+
+  /**
+   * Removes a specific value for a header name. Some headers have
+   * system supplied values and for these the system supplied values
+   * will still be added to the collection of values for the header.
+   */
+  void remove(String name, Object value);
+
+  /**
+   * Removes all values for the specified header name. Some headers
+   * have system supplied values and for these the system supplied
+   * values will still be added to the collection of values for the
+   * header.
+   */
+  void removeAll(String name);
+
+  /**
+   * Enumerates the headers, applying the function [f] to each
+   * header. The header name passed in [:name:] will be all lower
+   * case.
+   */
+  void forEach(void f(String name, List<String> values));
+
+  /**
+   * Disables folding for the header named [name] when sending the HTTP
+   * header. By default, multiple header values are folded into a
+   * single header line by separating the values with commas. The
+   * 'set-cookie' header has folding disabled by default.
+   */
+  void noFolding(String name);
+
+  /**
+   * Remove all headers. Some headers have system supplied values and
+   * for these the system supplied values will still be added to the
+   * collection of values for the header.
+   */
+  void clear();
+}
+
+/**
+ * Representation of a header value in the form:
+ *
+ *   [:value; parameter1=value1; parameter2=value2:]
+ *
+ * [HeaderValue] can be used to conveniently build and parse header
+ * values on this form.
+ *
+ * To build an [:accepts:] header with the value
+ *
+ *     text/plain; q=0.3, text/html
+ *
+ * use code like this:
+ *
+ *     HttpClientRequest request = ...;
+ *     var v = new HeaderValue("text/plain", {"q": "0.3"});
+ *     request.headers.add(HttpHeaders.acceptHeader, v);
+ *     request.headers.add(HttpHeaders.acceptHeader, "text/html");
+ *
+ * To parse the header values use the [:parse:] static method.
+ *
+ *     HttpRequest request = ...;
+ *     List<String> values = request.headers[HttpHeaders.acceptHeader];
+ *     values.forEach((value) {
+ *       HeaderValue v = HeaderValue.parse(value);
+ *       // Use v.value and v.parameters
+ *     });
+ *
+ * An instance of [HeaderValue] is immutable.
+ */
+abstract class HeaderValue {
+  /**
+   * Creates a new header value object setting the value and parameters.
+   */
+  factory HeaderValue([String value = "", Map<String, String> parameters]) {
+    return new _HeaderValue(value, parameters);
+  }
+
+  /**
+   * Creates a new header value object from parsing a header value
+   * string with both value and optional parameters.
+   */
+  static HeaderValue parse(String value,
+      {String parameterSeparator: ";",
+      String valueSeparator: null,
+      bool preserveBackslash: false}) {
+    return _HeaderValue.parse(value,
+        parameterSeparator: parameterSeparator,
+        valueSeparator: valueSeparator,
+        preserveBackslash: preserveBackslash);
+  }
+
+  /**
+   * Gets the header value.
+   */
+  String get value;
+
+  /**
+   * Gets the map of parameters.
+   *
+   * This map cannot be modified. Invoking any operation which would
+   * modify the map will throw [UnsupportedError].
+   */
+  Map<String, String> get parameters;
+
+  /**
+   * Returns the formatted string representation in the form:
+   *
+   *     value; parameter1=value1; parameter2=value2
+   */
+  String toString();
+}
+
+abstract class HttpSession implements Map {
+  /**
+   * Gets the id for the current session.
+   */
+  String get id;
+
+  /**
+   * Destroys the session. This will terminate the session and any further
+   * connections with this id will be given a new id and session.
+   */
+  void destroy();
+
+  /**
+   * Sets a callback that will be called when the session is timed out.
+   */
+  void set onTimeout(void callback());
+
+  /**
+   * Is true if the session has not been sent to the client yet.
+   */
+  bool get isNew;
+}
+
+/**
+ * Representation of a content type. An instance of [ContentType] is
+ * immutable.
+ */
+abstract class ContentType implements HeaderValue {
+  /**
+   * Content type for plain text using UTF-8 encoding.
+   *
+   *     text/plain; charset=utf-8
+   */
+  static final text = new ContentType("text", "plain", charset: "utf-8");
+  @Deprecated("Use text instead")
+  static final TEXT = text;
+
+  /**
+   *  Content type for HTML using UTF-8 encoding.
+   *
+   *     text/html; charset=utf-8
+   */
+  static final html = new ContentType("text", "html", charset: "utf-8");
+  @Deprecated("Use html instead")
+  static final HTML = html;
+
+  /**
+   *  Content type for JSON using UTF-8 encoding.
+   *
+   *     application/json; charset=utf-8
+   */
+  static final json = new ContentType("application", "json", charset: "utf-8");
+  @Deprecated("Use json instead")
+  static final JSON = json;
+
+  /**
+   *  Content type for binary data.
+   *
+   *     application/octet-stream
+   */
+  static final binary = new ContentType("application", "octet-stream");
+  @Deprecated("Use binary instead")
+  static final BINARY = binary;
+
+  /**
+   * Creates a new content type object setting the primary type and
+   * sub type. The charset and additional parameters can also be set
+   * using [charset] and [parameters]. If charset is passed and
+   * [parameters] contains charset as well the passed [charset] will
+   * override the value in parameters. Keys passed in parameters will be
+   * converted to lower case. The `charset` entry, whether passed as `charset`
+   * or in `parameters`, will have its value converted to lower-case.
+   */
+  factory ContentType(String primaryType, String subType,
+      {String charset, Map<String, String> parameters}) {
+    return new _ContentType(primaryType, subType, charset, parameters);
+  }
+
+  /**
+   * Creates a new content type object from parsing a Content-Type
+   * header value. As primary type, sub type and parameter names and
+   * values are not case sensitive all these values will be converted
+   * to lower case. Parsing this string
+   *
+   *     text/html; charset=utf-8
+   *
+   * will create a content type object with primary type [:text:], sub
+   * type [:html:] and parameter [:charset:] with value [:utf-8:].
+   */
+  static ContentType parse(String value) {
+    return _ContentType.parse(value);
+  }
+
+  /**
+   * Gets the mime-type, without any parameters.
+   */
+  String get mimeType;
+
+  /**
+   * Gets the primary type.
+   */
+  String get primaryType;
+
+  /**
+   * Gets the sub type.
+   */
+  String get subType;
+
+  /**
+   * Gets the character set.
+   */
+  String get charset;
+}
+
+/**
+ * Representation of a cookie. For cookies received by the server as Cookie
+ * header values only [name] and [value] properties will be set. When building a
+ * cookie for the 'set-cookie' header in the server and when receiving cookies
+ * in the client as 'set-cookie' headers all fields can be used.
+ */
+abstract class Cookie {
+  /**
+   * The name of the cookie.
+   *
+   * Must be a `token` as specified in RFC 6265.
+   *
+   * The allowed characters in a `token` are the visible ASCII characters,
+   * U+0021 (`!`) through U+007E (`~`), except the separator characters:
+   * `(`, `)`, `<`, `>`, `@`, `,`, `;`, `:`, `\`, `"`, `/`, `[`, `]`, `?`, `=`,
+   * `{`, and `}`.
+   */
+  String name;
+
+  /**
+   * The value of the cookie.
+   *
+   * Must be a `cookie-value` as specified in RFC 6265.
+   *
+   * The allowed characters in a cookie value are the visible ASCII characters,
+   * U+0021 (`!`) through U+007E (`~`) except the characters:
+   * `"`, `,`, `;` and `\`.
+   * Cookie values may be wrapped in a single pair of double quotes
+   * (U+0022, `"`).
+   */
+  String value;
+
+  /**
+   * The time at which the cookie expires.
+   */
+  DateTime expires;
+
+  /**
+   * The number of seconds until the cookie expires. A zero or negative value
+   * means the cookie has expired.
+   */
+  int maxAge;
+
+  /**
+   * The domain the cookie applies to.
+   */
+  String domain;
+
+  /**
+   * The path within the [domain] the cookie applies to.
+   */
+  String path;
+
+  /**
+   * Whether to only send this cookie on secure connections.
+   */
+  bool secure;
+
+  /**
+   * Whether the cookie is only sent in the HTTP request and is not made
+   * available to client side scripts.
+   */
+  bool httpOnly;
+
+  /**
+   * Creates a new cookie setting the name and value.
+   *
+   * [name] and [value] must be composed of valid characters according to RFC
+   * 6265.
+   *
+   * By default the value of `httpOnly` will be set to `true`.
+   */
+  factory Cookie(String name, String value) => new _Cookie(name, value);
+
+  /**
+   * Creates a new cookie by parsing a header value from a 'set-cookie'
+   * header.
+   */
+  factory Cookie.fromSetCookieValue(String value) {
+    return new _Cookie.fromSetCookieValue(value);
+  }
+
+  /**
+   * Returns the formatted string representation of the cookie. The
+   * string representation can be used for for setting the Cookie or
+   * 'set-cookie' headers
+   */
+  String toString();
+}
+
+/**
+ * A server-side object
+ * that contains the content of and information about an HTTP request.
+ *
+ * __Note__: Check out the
+ * [http_server](https://pub.dartlang.org/packages/http_server)
+ * package, which makes working with the low-level
+ * dart:io HTTP server subsystem easier.
+ *
+ * `HttpRequest` objects are generated by an [HttpServer],
+ * which listens for HTTP requests on a specific host and port.
+ * For each request received, the HttpServer, which is a [Stream],
+ * generates an `HttpRequest` object and adds it to the stream.
+ *
+ * An `HttpRequest` object delivers the body content of the request
+ * as a stream of byte lists.
+ * The object also contains information about the request,
+ * such as the method, URI, and headers.
+ *
+ * In the following code, an HttpServer listens
+ * for HTTP requests. When the server receives a request,
+ * it uses the HttpRequest object's `method` property to dispatch requests.
+ *
+ *     final HOST = InternetAddress.loopbackIPv4;
+ *     final PORT = 80;
+ *
+ *     HttpServer.bind(HOST, PORT).then((_server) {
+ *       _server.listen((HttpRequest request) {
+ *         switch (request.method) {
+ *           case 'GET':
+ *             handleGetRequest(request);
+ *             break;
+ *           case 'POST':
+ *             ...
+ *         }
+ *       },
+ *       onError: handleError);    // listen() failed.
+ *     }).catchError(handleError);
+ *
+ * An HttpRequest object provides access to the associated [HttpResponse]
+ * object through the response property.
+ * The server writes its response to the body of the HttpResponse object.
+ * For example, here's a function that responds to a request:
+ *
+ *     void handleGetRequest(HttpRequest req) {
+ *       HttpResponse res = req.response;
+ *       res.write('Received request ${req.method}: ${req.uri.path}');
+ *       res.close();
+ *     }
+ */
+abstract class HttpRequest implements Stream<Uint8List> {
+  /**
+   * The content length of the request body.
+   *
+   * If the size of the request body is not known in advance,
+   * this value is -1.
+   */
+  int get contentLength;
+
+  /**
+   * The method, such as 'GET' or 'POST', for the request.
+   */
+  String get method;
+
+  /**
+   * The URI for the request.
+   *
+   * This provides access to the
+   * path and query string for the request.
+   */
+  Uri get uri;
+
+  /**
+   * The requested URI for the request.
+   *
+   * The returned URI is reconstructed by using http-header fields, to access
+   * otherwise lost information, e.g. host and scheme.
+   *
+   * To reconstruct the scheme, first 'X-Forwarded-Proto' is checked, and then
+   * falling back to server type.
+   *
+   * To reconstruct the host, first 'X-Forwarded-Host' is checked, then 'Host'
+   * and finally calling back to server.
+   */
+  Uri get requestedUri;
+
+  /**
+   * The request headers.
+   *
+   * The returned [HttpHeaders] are immutable.
+   */
+  HttpHeaders get headers;
+
+  /**
+   * The cookies in the request, from the Cookie headers.
+   */
+  List<Cookie> get cookies;
+
+  /**
+   * The persistent connection state signaled by the client.
+   */
+  bool get persistentConnection;
+
+  /**
+   * The client certificate of the client making the request.
+   *
+   * This value is null if the connection is not a secure TLS or SSL connection,
+   * or if the server does not request a client certificate, or if the client
+   * does not provide one.
+   */
+  X509Certificate get certificate;
+
+  /**
+   * The session for the given request.
+   *
+   * If the session is
+   * being initialized by this call, [:isNew:] is true for the returned
+   * session.
+   * See [HttpServer.sessionTimeout] on how to change default timeout.
+   */
+  HttpSession get session;
+
+  /**
+   * The HTTP protocol version used in the request,
+   * either "1.0" or "1.1".
+   */
+  String get protocolVersion;
+
+  /**
+   * Information about the client connection.
+   *
+   * Returns [:null:] if the socket is not available.
+   */
+  HttpConnectionInfo get connectionInfo;
+
+  /**
+   * The [HttpResponse] object, used for sending back the response to the
+   * client.
+   *
+   * If the [contentLength] of the body isn't 0, and the body isn't being read,
+   * any write calls on the [HttpResponse] automatically drain the request
+   * body.
+   */
+  HttpResponse get response;
+}
+
+/**
+ * An HTTP response, which returns the headers and data
+ * from the server to the client in response to an HTTP request.
+ *
+ * Every HttpRequest object provides access to the associated [HttpResponse]
+ * object through the `response` property.
+ * The server sends its response to the client by writing to the
+ * HttpResponse object.
+ *
+ * ## Writing the response
+ *
+ * This class implements [IOSink].
+ * After the header has been set up, the methods
+ * from IOSink, such as `writeln()`, can be used to write
+ * the body of the HTTP response.
+ * Use the `close()` method to close the response and send it to the client.
+ *
+ *     server.listen((HttpRequest request) {
+ *       request.response.write('Hello, world!');
+ *       request.response.close();
+ *     });
+ *
+ * When one of the IOSink methods is used for the
+ * first time, the request header is sent. Calling any methods that
+ * change the header after it is sent throws an exception.
+ *
+ * ## Setting the headers
+ *
+ * The HttpResponse object has a number of properties for setting up
+ * the HTTP headers of the response.
+ * When writing string data through the IOSink, the encoding used
+ * is determined from the "charset" parameter of the
+ * "Content-Type" header.
+ *
+ *     HttpResponse response = ...
+ *     response.headers.contentType
+ *         = new ContentType("application", "json", charset: "utf-8");
+ *     response.write(...);  // Strings written will be UTF-8 encoded.
+ *
+ * If no charset is provided the default of ISO-8859-1 (Latin 1) will
+ * be used.
+ *
+ *     HttpResponse response = ...
+ *     response.headers.add(HttpHeaders.contentTypeHeader, "text/plain");
+ *     response.write(...);  // Strings written will be ISO-8859-1 encoded.
+ *
+ * An exception is thrown if you use the `write()` method
+ * while an unsupported content-type is set.
+ */
+abstract class HttpResponse implements IOSink {
+  // TODO(ajohnsen): Add documentation of how to pipe a file to the response.
+  /**
+   * Gets and sets the content length of the response. If the size of
+   * the response is not known in advance set the content length to
+   * -1, which is also the default if not set.
+   */
+  int contentLength;
+
+  /**
+   * Gets and sets the status code. Any integer value is accepted. For
+   * the official HTTP status codes use the fields from
+   * [HttpStatus]. If no status code is explicitly set the default
+   * value [HttpStatus.ok] is used.
+   *
+   * The status code must be set before the body is written
+   * to. Setting the status code after writing to the response body or
+   * closing the response will throw a `StateError`.
+   */
+  int statusCode;
+
+  /**
+   * Gets and sets the reason phrase. If no reason phrase is explicitly
+   * set a default reason phrase is provided.
+   *
+   * The reason phrase must be set before the body is written
+   * to. Setting the reason phrase after writing to the response body
+   * or closing the response will throw a `StateError`.
+   */
+  String reasonPhrase;
+
+  /**
+   * Gets and sets the persistent connection state. The initial value
+   * of this property is the persistent connection state from the
+   * request.
+   */
+  bool persistentConnection;
+
+  /**
+   * Set and get the [deadline] for the response. The deadline is timed from the
+   * time it's set. Setting a new deadline will override any previous deadline.
+   * When a deadline is exceeded, the response will be closed and any further
+   * data ignored.
+   *
+   * To disable a deadline, set the [deadline] to `null`.
+   *
+   * The [deadline] is `null` by default.
+   */
+  Duration deadline;
+
+  /**
+   * Gets or sets if the [HttpResponse] should buffer output.
+   *
+   * Default value is `true`.
+   *
+   * __Note__: Disabling buffering of the output can result in very poor
+   * performance, when writing many small chunks.
+   */
+  bool bufferOutput;
+
+  /**
+   * Returns the response headers.
+   *
+   * The response headers can be modified until the response body is
+   * written to or closed. After that they become immutable.
+   */
+  HttpHeaders get headers;
+
+  /**
+   * Cookies to set in the client (in the 'set-cookie' header).
+   */
+  List<Cookie> get cookies;
+
+  /**
+   * Respond with a redirect to [location].
+   *
+   * The URI in [location] should be absolute, but there are no checks
+   * to enforce that.
+   *
+   * By default the HTTP status code `HttpStatus.movedTemporarily`
+   * (`302`) is used for the redirect, but an alternative one can be
+   * specified using the [status] argument.
+   *
+   * This method will also call `close`, and the returned future is
+   * the future returned by `close`.
+   */
+  Future redirect(Uri location, {int status: HttpStatus.movedTemporarily});
+
+  /**
+   * Detaches the underlying socket from the HTTP server. When the
+   * socket is detached the HTTP server will no longer perform any
+   * operations on it.
+   *
+   * This is normally used when a HTTP upgrade request is received
+   * and the communication should continue with a different protocol.
+   *
+   * If [writeHeaders] is `true`, the status line and [headers] will be written
+   * to the socket before it's detached. If `false`, the socket is detached
+   * immediately, without any data written to the socket. Default is `true`.
+   */
+  Future<Socket> detachSocket({bool writeHeaders: true});
+
+  /**
+   * Gets information about the client connection. Returns [:null:] if the
+   * socket is not available.
+   */
+  HttpConnectionInfo get connectionInfo;
+}
+
+/**
+ * A client that receives content, such as web pages, from
+ * a server using the HTTP protocol.
+ *
+ * HttpClient contains a number of methods to send an [HttpClientRequest]
+ * to an Http server and receive an [HttpClientResponse] back.
+ * For example, you can use the [get], [getUrl], [post], and [postUrl] methods
+ * for GET and POST requests, respectively.
+ *
+ * ## Making a simple GET request: an example
+ *
+ * A `getUrl` request is a two-step process, triggered by two [Future]s.
+ * When the first future completes with a [HttpClientRequest], the underlying
+ * network connection has been established, but no data has been sent.
+ * In the callback function for the first future, the HTTP headers and body
+ * can be set on the request. Either the first write to the request object
+ * or a call to [close] sends the request to the server.
+ *
+ * When the HTTP response is received from the server,
+ * the second future, which is returned by close,
+ * completes with an [HttpClientResponse] object.
+ * This object provides access to the headers and body of the response.
+ * The body is available as a stream implemented by HttpClientResponse.
+ * If a body is present, it must be read. Otherwise, it leads to resource
+ * leaks. Consider using [HttpClientResponse.drain] if the body is unused.
+ *
+ *     HttpClient client = new HttpClient();
+ *     client.getUrl(Uri.parse("http://www.example.com/"))
+ *         .then((HttpClientRequest request) {
+ *           // Optionally set up headers...
+ *           // Optionally write to the request object...
+ *           // Then call close.
+ *           ...
+ *           return request.close();
+ *         })
+ *         .then((HttpClientResponse response) {
+ *           // Process the response.
+ *           ...
+ *         });
+ *
+ * The future for [HttpClientRequest] is created by methods such as
+ * [getUrl] and [open].
+ *
+ * ## HTTPS connections
+ *
+ * An HttpClient can make HTTPS requests, connecting to a server using
+ * the TLS (SSL) secure networking protocol. Calling [getUrl] with an
+ * https: scheme will work automatically, if the server's certificate is
+ * signed by a root CA (certificate authority) on the default list of
+ * well-known trusted CAs, compiled by Mozilla.
+ *
+ * To add a custom trusted certificate authority, or to send a client
+ * certificate to servers that request one, pass a [SecurityContext] object
+ * as the optional `context` argument to the `HttpClient` constructor.
+ * The desired security options can be set on the [SecurityContext] object.
+ *
+ * ## Headers
+ *
+ * All HttpClient requests set the following header by default:
+ *
+ *     Accept-Encoding: gzip
+ *
+ * This allows the HTTP server to use gzip compression for the body if
+ * possible. If this behavior is not desired set the
+ * `Accept-Encoding` header to something else.
+ * To turn off gzip compression of the response, clear this header:
+ *
+ *      request.headers.removeAll(HttpHeaders.acceptEncodingHeader)
+ *
+ * ## Closing the HttpClient
+ *
+ * The HttpClient supports persistent connections and caches network
+ * connections to reuse them for multiple requests whenever
+ * possible. This means that network connections can be kept open for
+ * some time after a request has completed. Use HttpClient.close
+ * to force the HttpClient object to shut down and to close the idle
+ * network connections.
+ *
+ * ## Turning proxies on and off
+ *
+ * By default the HttpClient uses the proxy configuration available
+ * from the environment, see [findProxyFromEnvironment]. To turn off
+ * the use of proxies set the [findProxy] property to
+ * [:null:].
+ *
+ *     HttpClient client = new HttpClient();
+ *     client.findProxy = null;
+ */
+abstract class HttpClient {
+  static const int defaultHttpPort = 80;
+  @Deprecated("Use defaultHttpPort instead")
+  static const int DEFAULT_HTTP_PORT = defaultHttpPort;
+
+  static const int defaultHttpsPort = 443;
+  @Deprecated("Use defaultHttpsPort instead")
+  static const int DEFAULT_HTTPS_PORT = defaultHttpsPort;
+
+  /// Gets and sets the idle timeout of non-active persistent (keep-alive)
+  /// connections.
+  ///
+  /// The default value is 15 seconds.
+  Duration idleTimeout;
+
+  /// Gets and sets the connection timeout.
+  ///
+  /// When connecting to a new host exceeds this timeout, a [SocketException]
+  /// is thrown. The timeout applies only to connections initiated after the
+  /// timeout is set.
+  ///
+  /// When this is `null`, the OS default timeout is used. The default is
+  /// `null`.
+  Duration connectionTimeout;
+
+  /**
+   * Gets and sets the maximum number of live connections, to a single host.
+   *
+   * Increasing this number may lower performance and take up unwanted
+   * system resources.
+   *
+   * To disable, set to `null`.
+   *
+   * Default is `null`.
+   */
+  int maxConnectionsPerHost;
+
+  /**
+   * Gets and sets whether the body of a response will be automatically
+   * uncompressed.
+   *
+   * The body of an HTTP response can be compressed. In most
+   * situations providing the un-compressed body is most
+   * convenient. Therefore the default behavior is to un-compress the
+   * body. However in some situations (e.g. implementing a transparent
+   * proxy) keeping the uncompressed stream is required.
+   *
+   * NOTE: Headers in the response are never modified. This means
+   * that when automatic un-compression is turned on the value of the
+   * header `Content-Length` will reflect the length of the original
+   * compressed body. Likewise the header `Content-Encoding` will also
+   * have the original value indicating compression.
+   *
+   * NOTE: Automatic un-compression is only performed if the
+   * `Content-Encoding` header value is `gzip`.
+   *
+   * This value affects all responses produced by this client after the
+   * value is changed.
+   *
+   * To disable, set to `false`.
+   *
+   * Default is `true`.
+   */
+  bool autoUncompress;
+
+  /// Gets and sets the default value of the `User-Agent` header for all requests
+  /// generated by this [HttpClient].
+  ///
+  /// The default value is `Dart/<version> (dart:io)`.
+  ///
+  /// If the userAgent is set to `null`, no default `User-Agent` header will be
+  /// added to each request.
+  String userAgent;
+
+  factory HttpClient({SecurityContext context}) {
+    HttpOverrides overrides = HttpOverrides.current;
+    if (overrides == null) {
+      return new _HttpClient(context);
+    }
+    return overrides.createHttpClient(context);
+  }
+
+  /**
+   * Opens a HTTP connection.
+   *
+   * The HTTP method to use is specified in [method], the server is
+   * specified using [host] and [port], and the path (including
+   * a possible query) is specified using [path].
+   * The path may also contain a URI fragment, which will be ignored.
+   *
+   * The `Host` header for the request will be set to the value [host]:[port]
+   * (if [host] is an IP address, it will still be used in the `Host` header).
+   * This can be overridden through the [HttpClientRequest] interface before
+   * the request is sent.
+   *
+   * For additional information on the sequence of events during an
+   * HTTP transaction, and the objects returned by the futures, see
+   * the overall documentation for the class [HttpClient].
+   */
+  Future<HttpClientRequest> open(
+      String method, String host, int port, String path);
+
+  /**
+   * Opens a HTTP connection.
+   *
+   * The HTTP method is specified in [method] and the URL to use in
+   * [url].
+   *
+   * The `Host` header for the request will be set to the value
+   * [Uri.host]:[Uri.port] from [url] (if [url.host] is an IP address, it will
+   * still be used in the `Host` header). This can be overridden through the
+   * [HttpClientRequest] interface before the request is sent.
+   *
+   * For additional information on the sequence of events during an
+   * HTTP transaction, and the objects returned by the futures, see
+   * the overall documentation for the class [HttpClient].
+   */
+  Future<HttpClientRequest> openUrl(String method, Uri url);
+
+  /**
+   * Opens a HTTP connection using the GET method.
+   *
+   * The server is specified using [host] and [port], and the path
+   * (including a possible query) is specified using
+   * [path].
+   *
+   * See [open] for details.
+   */
+  Future<HttpClientRequest> get(String host, int port, String path);
+
+  /**
+   * Opens a HTTP connection using the GET method.
+   *
+   * The URL to use is specified in [url].
+   *
+   * See [openUrl] for details.
+   */
+  Future<HttpClientRequest> getUrl(Uri url);
+
+  /**
+   * Opens a HTTP connection using the POST method.
+   *
+   * The server is specified using [host] and [port], and the path
+   * (including a possible query) is specified using
+   * [path].
+   *
+   * See [open] for details.
+   */
+  Future<HttpClientRequest> post(String host, int port, String path);
+
+  /**
+   * Opens a HTTP connection using the POST method.
+   *
+   * The URL to use is specified in [url].
+   *
+   * See [openUrl] for details.
+   */
+  Future<HttpClientRequest> postUrl(Uri url);
+
+  /**
+   * Opens a HTTP connection using the PUT method.
+   *
+   * The server is specified using [host] and [port], and the path
+   * (including a possible query) is specified using [path].
+   *
+   * See [open] for details.
+   */
+  Future<HttpClientRequest> put(String host, int port, String path);
+
+  /**
+   * Opens a HTTP connection using the PUT method.
+   *
+   * The URL to use is specified in [url].
+   *
+   * See [openUrl] for details.
+   */
+  Future<HttpClientRequest> putUrl(Uri url);
+
+  /**
+   * Opens a HTTP connection using the DELETE method.
+   *
+   * The server is specified using [host] and [port], and the path
+   * (including a possible query) is specified using [path].
+   *
+   * See [open] for details.
+   */
+  Future<HttpClientRequest> delete(String host, int port, String path);
+
+  /**
+   * Opens a HTTP connection using the DELETE method.
+   *
+   * The URL to use is specified in [url].
+   *
+   * See [openUrl] for details.
+   */
+  Future<HttpClientRequest> deleteUrl(Uri url);
+
+  /**
+   * Opens a HTTP connection using the PATCH method.
+   *
+   * The server is specified using [host] and [port], and the path
+   * (including a possible query) is specified using [path].
+   *
+   * See [open] for details.
+   */
+  Future<HttpClientRequest> patch(String host, int port, String path);
+
+  /**
+   * Opens a HTTP connection using the PATCH method.
+   *
+   * The URL to use is specified in [url].
+   *
+   * See [openUrl] for details.
+   */
+  Future<HttpClientRequest> patchUrl(Uri url);
+
+  /**
+   * Opens a HTTP connection using the HEAD method.
+   *
+   * The server is specified using [host] and [port], and the path
+   * (including a possible query) is specified using [path].
+   *
+   * See [open] for details.
+   */
+  Future<HttpClientRequest> head(String host, int port, String path);
+
+  /**
+   * Opens a HTTP connection using the HEAD method.
+   *
+   * The URL to use is specified in [url].
+   *
+   * See [openUrl] for details.
+   */
+  Future<HttpClientRequest> headUrl(Uri url);
+
+  /**
+   * Sets the function to be called when a site is requesting
+   * authentication. The URL requested and the security realm from the
+   * server are passed in the arguments [url] and [realm].
+   *
+   * The function returns a [Future] which should complete when the
+   * authentication has been resolved. If credentials cannot be
+   * provided the [Future] should complete with [:false:]. If
+   * credentials are available the function should add these using
+   * [addCredentials] before completing the [Future] with the value
+   * [:true:].
+   *
+   * If the [Future] completes with [:true:] the request will be retried
+   * using the updated credentials, however, the retried request will not
+   * carry the original request payload. Otherwise response processing will
+   * continue normally.
+   *
+   * If it is known that the remote server requires authentication for all
+   * requests, it is advisable to use [addCredentials] directly, or manually
+   * set the `'authorization'` header on the request to avoid the overhead
+   * of a failed request, or issues due to missing request payload on retried
+   * request.
+   */
+  set authenticate(Future<bool> f(Uri url, String scheme, String realm));
+
+  /**
+   * Add credentials to be used for authorizing HTTP requests.
+   */
+  void addCredentials(Uri url, String realm, HttpClientCredentials credentials);
+
+  /**
+   * Sets the function used to resolve the proxy server to be used for
+   * opening a HTTP connection to the specified [url]. If this
+   * function is not set, direct connections will always be used.
+   *
+   * The string returned by [f] must be in the format used by browser
+   * PAC (proxy auto-config) scripts. That is either
+   *
+   *     "DIRECT"
+   *
+   * for using a direct connection or
+   *
+   *     "PROXY host:port"
+   *
+   * for using the proxy server [:host:] on port [:port:].
+   *
+   * A configuration can contain several configuration elements
+   * separated by semicolons, e.g.
+   *
+   *     "PROXY host:port; PROXY host2:port2; DIRECT"
+   *
+   * The static function [findProxyFromEnvironment] on this class can
+   * be used to implement proxy server resolving based on environment
+   * variables.
+   */
+  set findProxy(String f(Uri url));
+
+  /**
+   * Function for resolving the proxy server to be used for a HTTP
+   * connection from the proxy configuration specified through
+   * environment variables.
+   *
+   * The following environment variables are taken into account:
+   *
+   *     http_proxy
+   *     https_proxy
+   *     no_proxy
+   *     HTTP_PROXY
+   *     HTTPS_PROXY
+   *     NO_PROXY
+   *
+   * [:http_proxy:] and [:HTTP_PROXY:] specify the proxy server to use for
+   * http:// urls. Use the format [:hostname:port:]. If no port is used a
+   * default of 1080 will be used. If both are set the lower case one takes
+   * precedence.
+   *
+   * [:https_proxy:] and [:HTTPS_PROXY:] specify the proxy server to use for
+   * https:// urls. Use the format [:hostname:port:]. If no port is used a
+   * default of 1080 will be used. If both are set the lower case one takes
+   * precedence.
+   *
+   * [:no_proxy:] and [:NO_PROXY:] specify a comma separated list of
+   * postfixes of hostnames for which not to use the proxy
+   * server. E.g. the value "localhost,127.0.0.1" will make requests
+   * to both "localhost" and "127.0.0.1" not use a proxy. If both are set
+   * the lower case one takes precedence.
+   *
+   * To activate this way of resolving proxies assign this function to
+   * the [findProxy] property on the [HttpClient].
+   *
+   *     HttpClient client = new HttpClient();
+   *     client.findProxy = HttpClient.findProxyFromEnvironment;
+   *
+   * If you don't want to use the system environment you can use a
+   * different one by wrapping the function.
+   *
+   *     HttpClient client = new HttpClient();
+   *     client.findProxy = (url) {
+   *       return HttpClient.findProxyFromEnvironment(
+   *           url, environment: {"http_proxy": ..., "no_proxy": ...});
+   *     }
+   *
+   * If a proxy requires authentication it is possible to configure
+   * the username and password as well. Use the format
+   * [:username:password@hostname:port:] to include the username and
+   * password. Alternatively the API [addProxyCredentials] can be used
+   * to set credentials for proxies which require authentication.
+   */
+  static String findProxyFromEnvironment(Uri url,
+      {Map<String, String> environment}) {
+    HttpOverrides overrides = HttpOverrides.current;
+    if (overrides == null) {
+      return _HttpClient._findProxyFromEnvironment(url, environment);
+    }
+    return overrides.findProxyFromEnvironment(url, environment);
+  }
+
+  /**
+   * Sets the function to be called when a proxy is requesting
+   * authentication. Information on the proxy in use and the security
+   * realm for the authentication are passed in the arguments [host],
+   * [port] and [realm].
+   *
+   * The function returns a [Future] which should complete when the
+   * authentication has been resolved. If credentials cannot be
+   * provided the [Future] should complete with [:false:]. If
+   * credentials are available the function should add these using
+   * [addProxyCredentials] before completing the [Future] with the value
+   * [:true:].
+   *
+   * If the [Future] completes with [:true:] the request will be retried
+   * using the updated credentials. Otherwise response processing will
+   * continue normally.
+   */
+  set authenticateProxy(
+      Future<bool> f(String host, int port, String scheme, String realm));
+
+  /**
+   * Add credentials to be used for authorizing HTTP proxies.
+   */
+  void addProxyCredentials(
+      String host, int port, String realm, HttpClientCredentials credentials);
+
+  /**
+   * Sets a callback that will decide whether to accept a secure connection
+   * with a server certificate that cannot be authenticated by any of our
+   * trusted root certificates.
+   *
+   * When an secure HTTP request if made, using this HttpClient, and the
+   * server returns a server certificate that cannot be authenticated, the
+   * callback is called asynchronously with the [X509Certificate] object and
+   * the server's hostname and port.  If the value of [badCertificateCallback]
+   * is [:null:], the bad certificate is rejected, as if the callback
+   * returned [:false:]
+   *
+   * If the callback returns true, the secure connection is accepted and the
+   * [:Future<HttpClientRequest>:] that was returned from the call making the
+   * request completes with a valid HttpRequest object. If the callback returns
+   * false, the [:Future<HttpClientRequest>:] completes with an exception.
+   *
+   * If a bad certificate is received on a connection attempt, the library calls
+   * the function that was the value of badCertificateCallback at the time
+   * the request is made, even if the value of badCertificateCallback
+   * has changed since then.
+   */
+  set badCertificateCallback(
+      bool callback(X509Certificate cert, String host, int port));
+
+  /// Shuts down the HTTP client.
+  ///
+  /// If [force] is `false` (the default) the [HttpClient] will be kept alive
+  /// until all active connections are done. If [force] is `true` any active
+  /// connections will be closed to immediately release all resources. These
+  /// closed connections will receive an error event to indicate that the client
+  /// was shut down. In both cases trying to establish a new connection after
+  /// calling [close] will throw an exception.
+  void close({bool force: false});
+}
+
+/**
+ * HTTP request for a client connection.
+ *
+ * To set up a request, set the headers using the headers property
+ * provided in this class and write the data to the body of the request.
+ * HttpClientRequest is an [IOSink]. Use the methods from IOSink,
+ * such as writeCharCode(), to write the body of the HTTP
+ * request. When one of the IOSink methods is used for the first
+ * time, the request header is sent. Calling any methods that
+ * change the header after it is sent throws an exception.
+ *
+ * When writing string data through the [IOSink] the
+ * encoding used is determined from the "charset" parameter of
+ * the "Content-Type" header.
+ *
+ *     HttpClientRequest request = ...
+ *     request.headers.contentType
+ *         = new ContentType("application", "json", charset: "utf-8");
+ *     request.write(...);  // Strings written will be UTF-8 encoded.
+ *
+ * If no charset is provided the default of ISO-8859-1 (Latin 1) is
+ * be used.
+ *
+ *     HttpClientRequest request = ...
+ *     request.headers.add(HttpHeaders.contentTypeHeader, "text/plain");
+ *     request.write(...);  // Strings written will be ISO-8859-1 encoded.
+ *
+ * An exception is thrown if you use an unsupported encoding and the
+ * `write()` method being used takes a string parameter.
+ */
+abstract class HttpClientRequest implements IOSink {
+  /**
+   * Gets and sets the requested persistent connection state.
+   *
+   * The default value is [:true:].
+   */
+  bool persistentConnection;
+
+  /**
+   * Set this property to [:true:] if this request should
+   * automatically follow redirects. The default is [:true:].
+   *
+   * Automatic redirect will only happen for "GET" and "HEAD" requests
+   * and only for the status codes [:HttpStatus.movedPermanently:]
+   * (301), [:HttpStatus.found:] (302),
+   * [:HttpStatus.movedTemporarily:] (302, alias for
+   * [:HttpStatus.found:]), [:HttpStatus.seeOther:] (303) and
+   * [:HttpStatus.temporaryRedirect:] (307). For
+   * [:HttpStatus.seeOther:] (303) automatic redirect will also happen
+   * for "POST" requests with the method changed to "GET" when
+   * following the redirect.
+   *
+   * All headers added to the request will be added to the redirection
+   * request(s). However, any body send with the request will not be
+   * part of the redirection request(s).
+   */
+  bool followRedirects;
+
+  /**
+   * Set this property to the maximum number of redirects to follow
+   * when [followRedirects] is `true`. If this number is exceeded
+   * an error event will be added with a [RedirectException].
+   *
+   * The default value is 5.
+   */
+  int maxRedirects;
+
+  /**
+   * The method of the request.
+   */
+  String get method;
+
+  /**
+   * The uri of the request.
+   */
+  Uri get uri;
+
+  /// Gets and sets the content length of the request.
+  ///
+  /// If the size of the request is not known in advance set content length to
+  /// -1, which is also the default.
+  int contentLength;
+
+  /**
+   * Gets or sets if the [HttpClientRequest] should buffer output.
+   *
+   * Default value is `true`.
+   *
+   * __Note__: Disabling buffering of the output can result in very poor
+   * performance, when writing many small chunks.
+   */
+  bool bufferOutput;
+
+  /**
+   * Returns the client request headers.
+   *
+   * The client request headers can be modified until the client
+   * request body is written to or closed. After that they become
+   * immutable.
+   */
+  HttpHeaders get headers;
+
+  /**
+   * Cookies to present to the server (in the 'cookie' header).
+   */
+  List<Cookie> get cookies;
+
+  /// A [HttpClientResponse] future that will complete once the response is
+  /// available.
+  ///
+  /// If an error occurs before the response is available, this future will
+  /// complete with an error.
+  Future<HttpClientResponse> get done;
+
+  /**
+   * Close the request for input. Returns the value of [done].
+   */
+  Future<HttpClientResponse> close();
+
+  /// Gets information about the client connection.
+  ///
+  /// Returns [:null:] if the socket is not available.
+  HttpConnectionInfo get connectionInfo;
+}
+
+/**
+ * HTTP response for a client connection.
+ *
+ * The body of a [HttpClientResponse] object is a
+ * [Stream] of data from the server. Listen to the body to handle
+ * the data and be notified when the entire body is received.
+ *
+ *     new HttpClient().get('localhost', 80, '/file.txt')
+ *          .then((HttpClientRequest request) => request.close())
+ *          .then((HttpClientResponse response) {
+ *            response.transform(utf8.decoder).listen((contents) {
+ *              // handle data
+ *            });
+ *          });
+ */
+abstract class HttpClientResponse implements Stream<List<int>> {
+  /**
+   * Returns the status code.
+   *
+   * The status code must be set before the body is written
+   * to. Setting the status code after writing to the body will throw
+   * a `StateError`.
+   */
+  int get statusCode;
+
+  /**
+   * Returns the reason phrase associated with the status code.
+   *
+   * The reason phrase must be set before the body is written
+   * to. Setting the reason phrase after writing to the body will throw
+   * a `StateError`.
+   */
+  String get reasonPhrase;
+
+  /**
+   * Returns the content length of the response body. Returns -1 if the size of
+   * the response body is not known in advance.
+   *
+   * If the content length needs to be set, it must be set before the
+   * body is written to. Setting the content length after writing to the body
+   * will throw a `StateError`.
+   */
+  int get contentLength;
+
+  /// The compression state of the response.
+  ///
+  /// This specifies whether the response bytes were compressed when they were
+  /// received across the wire and whether callers will receive compressed
+  /// or uncompressed bytes when they listed to this response's byte stream.
+  @Since("2.4")
+  HttpClientResponseCompressionState get compressionState;
+
+  /**
+   * Gets the persistent connection state returned by the server.
+   *
+   * If the persistent connection state needs to be set, it must be
+   * set before the body is written to. Setting the persistent connection state
+   * after writing to the body will throw a `StateError`.
+   */
+  bool get persistentConnection;
+
+  /**
+   * Returns whether the status code is one of the normal redirect
+   * codes [HttpStatus.movedPermanently], [HttpStatus.found],
+   * [HttpStatus.movedTemporarily], [HttpStatus.seeOther] and
+   * [HttpStatus.temporaryRedirect].
+   */
+  bool get isRedirect;
+
+  /**
+   * Returns the series of redirects this connection has been through. The
+   * list will be empty if no redirects were followed. [redirects] will be
+   * updated both in the case of an automatic and a manual redirect.
+   */
+  List<RedirectInfo> get redirects;
+
+  /**
+   * Redirects this connection to a new URL. The default value for
+   * [method] is the method for the current request. The default value
+   * for [url] is the value of the [HttpHeaders.locationHeader] header of
+   * the current response. All body data must have been read from the
+   * current response before calling [redirect].
+   *
+   * All headers added to the request will be added to the redirection
+   * request. However, any body sent with the request will not be
+   * part of the redirection request.
+   *
+   * If [followLoops] is set to [:true:], redirect will follow the redirect,
+   * even if the URL was already visited. The default value is [:false:].
+   *
+   * The method will ignore [HttpClientRequest.maxRedirects]
+   * and will always perform the redirect.
+   */
+  Future<HttpClientResponse> redirect(
+      [String method, Uri url, bool followLoops]);
+
+  /**
+   * Returns the client response headers.
+   *
+   * The client response headers are immutable.
+   */
+  HttpHeaders get headers;
+
+  /**
+   * Detach the underlying socket from the HTTP client. When the
+   * socket is detached the HTTP client will no longer perform any
+   * operations on it.
+   *
+   * This is normally used when a HTTP upgrade is negotiated and the
+   * communication should continue with a different protocol.
+   */
+  Future<Socket> detachSocket();
+
+  /**
+   * Cookies set by the server (from the 'set-cookie' header).
+   */
+  List<Cookie> get cookies;
+
+  /**
+   * Returns the certificate of the HTTPS server providing the response.
+   * Returns null if the connection is not a secure TLS or SSL connection.
+   */
+  X509Certificate get certificate;
+
+  /**
+   * Gets information about the client connection. Returns [:null:] if the socket
+   * is not available.
+   */
+  HttpConnectionInfo get connectionInfo;
+}
+
+/// Enum that specifies the compression state of the byte stream of an
+/// [HttpClientResponse].
+///
+/// The values herein allow callers to answer the following questions as they
+/// pertain to an [HttpClientResponse]:
+///
+///  * Can the value of the response's `Content-Length` HTTP header be trusted?
+///  * Does the caller need to manually decompress the response's byte stream?
+///
+/// This enum is accessed via the [HttpClientResponse.compressionState] value.
+@Since("2.4")
+enum HttpClientResponseCompressionState {
+  /// The body of the HTTP response was received and remains in an uncompressed
+  /// state.
+  ///
+  /// In this state, the value of the `Content-Length` HTTP header, if
+  /// specified (non-negative), should match the number of bytes produced by
+  /// the response's byte stream.
+  notCompressed,
+
+  /// The body of the HTTP response was originally compressed, but by virtue of
+  /// the [HttpClient.autoUncompress] configuration option, it has been
+  /// automatically uncompressed.
+  ///
+  /// HTTP headers are not modified, so when a response has been uncompressed
+  /// in this way, the value of the `Content-Length` HTTP header cannot be
+  /// trusted, as it will contain the compressed content length, whereas the
+  /// stream of bytes produced by the response will contain uncompressed bytes.
+  decompressed,
+
+  /// The body of the HTTP response contains compressed bytes.
+  ///
+  /// In this state, the value of the `Content-Length` HTTP header, if
+  /// specified (non-negative), should match the number of bytes produced by
+  /// the response's byte stream.
+  ///
+  /// If the caller wishes to manually uncompress the body of the response,
+  /// it should consult the value of the `Content-Encoding` HTTP header to see
+  /// what type of compression has been applied. See
+  /// <https://tools.ietf.org/html/rfc2616#section-14.11> for more information.
+  compressed,
+}
+
+abstract class HttpClientCredentials {}
+
+/**
+ * Represents credentials for basic authentication.
+ */
+abstract class HttpClientBasicCredentials extends HttpClientCredentials {
+  factory HttpClientBasicCredentials(String username, String password) =>
+      new _HttpClientBasicCredentials(username, password);
+}
+
+/**
+ * Represents credentials for digest authentication. Digest
+ * authentication is only supported for servers using the MD5
+ * algorithm and quality of protection (qop) of either "none" or
+ * "auth".
+ */
+abstract class HttpClientDigestCredentials extends HttpClientCredentials {
+  factory HttpClientDigestCredentials(String username, String password) =>
+      new _HttpClientDigestCredentials(username, password);
+}
+
+/**
+ * Information about an [HttpRequest], [HttpResponse], [HttpClientRequest], or
+ * [HttpClientResponse] connection.
+ */
+abstract class HttpConnectionInfo {
+  InternetAddress get remoteAddress;
+  int get remotePort;
+  int get localPort;
+}
+
+/**
+ * Redirect information.
+ */
+abstract class RedirectInfo {
+  /**
+   * Returns the status code used for the redirect.
+   */
+  int get statusCode;
+
+  /**
+   * Returns the method used for the redirect.
+   */
+  String get method;
+
+  /**
+   * Returns the location for the redirect.
+   */
+  Uri get location;
+}
+
+/**
+ * When detaching a socket from either the [:HttpServer:] or the
+ * [:HttpClient:] due to a HTTP connection upgrade there might be
+ * unparsed data already read from the socket. This unparsed data
+ * together with the detached socket is returned in an instance of
+ * this class.
+ */
+abstract class DetachedSocket {
+  Socket get socket;
+  List<int> get unparsedData;
+}
+
+class HttpException implements IOException {
+  final String message;
+  final Uri uri;
+
+  const HttpException(this.message, {this.uri});
+
+  String toString() {
+    var b = new StringBuffer()..write('HttpException: ')..write(message);
+    if (uri != null) {
+      b.write(', uri = $uri');
+    }
+    return b.toString();
+  }
+}
+
+class RedirectException implements HttpException {
+  final String message;
+  final List<RedirectInfo> redirects;
+
+  const RedirectException(this.message, this.redirects);
+
+  String toString() => "RedirectException: $message";
+
+  Uri get uri => redirects.last.location;
+}
diff --git a/sdk_nnbd/lib/_http/http_date.dart b/sdk_nnbd/lib/_http/http_date.dart
new file mode 100644
index 0000000..d9301b4
--- /dev/null
+++ b/sdk_nnbd/lib/_http/http_date.dart
@@ -0,0 +1,388 @@
+// Copyright (c) 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 dart._http;
+
+/**
+ * Utility functions for working with dates with HTTP specific date
+ * formats.
+ */
+class HttpDate {
+  // From RFC-2616 section "3.3.1 Full Date",
+  // http://tools.ietf.org/html/rfc2616#section-3.3.1
+  //
+  // HTTP-date    = rfc1123-date | rfc850-date | asctime-date
+  // rfc1123-date = wkday "," SP date1 SP time SP "GMT"
+  // rfc850-date  = weekday "," SP date2 SP time SP "GMT"
+  // asctime-date = wkday SP date3 SP time SP 4DIGIT
+  // date1        = 2DIGIT SP month SP 4DIGIT
+  //                ; day month year (e.g., 02 Jun 1982)
+  // date2        = 2DIGIT "-" month "-" 2DIGIT
+  //                ; day-month-year (e.g., 02-Jun-82)
+  // date3        = month SP ( 2DIGIT | ( SP 1DIGIT ))
+  //                ; month day (e.g., Jun  2)
+  // time         = 2DIGIT ":" 2DIGIT ":" 2DIGIT
+  //                ; 00:00:00 - 23:59:59
+  // wkday        = "Mon" | "Tue" | "Wed"
+  //              | "Thu" | "Fri" | "Sat" | "Sun"
+  // weekday      = "Monday" | "Tuesday" | "Wednesday"
+  //              | "Thursday" | "Friday" | "Saturday" | "Sunday"
+  // month        = "Jan" | "Feb" | "Mar" | "Apr"
+  //              | "May" | "Jun" | "Jul" | "Aug"
+  //              | "Sep" | "Oct" | "Nov" | "Dec"
+
+  /**
+   * Format a date according to
+   * [RFC-1123](http://tools.ietf.org/html/rfc1123 "RFC-1123"),
+   * e.g. `Thu, 1 Jan 1970 00:00:00 GMT`.
+   */
+  static String format(DateTime date) {
+    const List wkday = const ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
+    const List month = const [
+      "Jan",
+      "Feb",
+      "Mar",
+      "Apr",
+      "May",
+      "Jun",
+      "Jul",
+      "Aug",
+      "Sep",
+      "Oct",
+      "Nov",
+      "Dec"
+    ];
+
+    DateTime d = date.toUtc();
+    StringBuffer sb = new StringBuffer()
+      ..write(wkday[d.weekday - 1])
+      ..write(", ")
+      ..write(d.day <= 9 ? "0" : "")
+      ..write(d.day.toString())
+      ..write(" ")
+      ..write(month[d.month - 1])
+      ..write(" ")
+      ..write(d.year.toString())
+      ..write(d.hour <= 9 ? " 0" : " ")
+      ..write(d.hour.toString())
+      ..write(d.minute <= 9 ? ":0" : ":")
+      ..write(d.minute.toString())
+      ..write(d.second <= 9 ? ":0" : ":")
+      ..write(d.second.toString())
+      ..write(" GMT");
+    return sb.toString();
+  }
+
+  /**
+   * Parse a date string in either of the formats
+   * [RFC-1123](http://tools.ietf.org/html/rfc1123 "RFC-1123"),
+   * [RFC-850](http://tools.ietf.org/html/rfc850 "RFC-850") or
+   * ANSI C's asctime() format. These formats are listed here.
+   *
+   *     Thu, 1 Jan 1970 00:00:00 GMT
+   *     Thursday, 1-Jan-1970 00:00:00 GMT
+   *     Thu Jan  1 00:00:00 1970
+   *
+   * For more information see [RFC-2616 section
+   * 3.1.1](http://tools.ietf.org/html/rfc2616#section-3.3.1
+   * "RFC-2616 section 3.1.1").
+   */
+  static DateTime parse(String date) {
+    final int SP = 32;
+    const List wkdays = const ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
+    const List weekdays = const [
+      "Monday",
+      "Tuesday",
+      "Wednesday",
+      "Thursday",
+      "Friday",
+      "Saturday",
+      "Sunday"
+    ];
+    const List months = const [
+      "Jan",
+      "Feb",
+      "Mar",
+      "Apr",
+      "May",
+      "Jun",
+      "Jul",
+      "Aug",
+      "Sep",
+      "Oct",
+      "Nov",
+      "Dec"
+    ];
+    const List wkdaysLowerCase = const [
+      "mon",
+      "tue",
+      "wed",
+      "thu",
+      "fri",
+      "sat",
+      "sun"
+    ];
+    const List weekdaysLowerCase = const [
+      "monday",
+      "tuesday",
+      "wednesday",
+      "thursday",
+      "friday",
+      "saturday",
+      "sunday"
+    ];
+    const List monthsLowerCase = const [
+      "jan",
+      "feb",
+      "mar",
+      "apr",
+      "may",
+      "jun",
+      "jul",
+      "aug",
+      "sep",
+      "oct",
+      "nov",
+      "dec"
+    ];
+
+    final int formatRfc1123 = 0;
+    final int formatRfc850 = 1;
+    final int formatAsctime = 2;
+
+    int index = 0;
+    String tmp;
+    int format;
+
+    void expect(String s) {
+      if (date.length - index < s.length) {
+        throw new HttpException("Invalid HTTP date $date");
+      }
+      String tmp = date.substring(index, index + s.length);
+      if (tmp != s) {
+        throw new HttpException("Invalid HTTP date $date");
+      }
+      index += s.length;
+    }
+
+    int expectWeekday() {
+      int weekday;
+      // The formatting of the weekday signals the format of the date string.
+      int pos = date.indexOf(",", index);
+      if (pos == -1) {
+        int pos = date.indexOf(" ", index);
+        if (pos == -1) throw new HttpException("Invalid HTTP date $date");
+        tmp = date.substring(index, pos);
+        index = pos + 1;
+        weekday = wkdays.indexOf(tmp);
+        if (weekday != -1) {
+          format = formatAsctime;
+          return weekday;
+        }
+      } else {
+        tmp = date.substring(index, pos);
+        index = pos + 1;
+        weekday = wkdays.indexOf(tmp);
+        if (weekday != -1) {
+          format = formatRfc1123;
+          return weekday;
+        }
+        weekday = weekdays.indexOf(tmp);
+        if (weekday != -1) {
+          format = formatRfc850;
+          return weekday;
+        }
+      }
+      throw new HttpException("Invalid HTTP date $date");
+    }
+
+    int expectMonth(String separator) {
+      int pos = date.indexOf(separator, index);
+      if (pos - index != 3) throw new HttpException("Invalid HTTP date $date");
+      tmp = date.substring(index, pos);
+      index = pos + 1;
+      int month = months.indexOf(tmp);
+      if (month != -1) return month;
+      throw new HttpException("Invalid HTTP date $date");
+    }
+
+    int expectNum(String separator) {
+      int pos;
+      if (separator.length > 0) {
+        pos = date.indexOf(separator, index);
+      } else {
+        pos = date.length;
+      }
+      String tmp = date.substring(index, pos);
+      index = pos + separator.length;
+      try {
+        int value = int.parse(tmp);
+        return value;
+      } on FormatException catch (e) {
+        throw new HttpException("Invalid HTTP date $date");
+      }
+    }
+
+    void expectEnd() {
+      if (index != date.length) {
+        throw new HttpException("Invalid HTTP date $date");
+      }
+    }
+
+    int weekday = expectWeekday();
+    int day;
+    int month;
+    int year;
+    int hours;
+    int minutes;
+    int seconds;
+    if (format == formatAsctime) {
+      month = expectMonth(" ");
+      if (date.codeUnitAt(index) == SP) index++;
+      day = expectNum(" ");
+      hours = expectNum(":");
+      minutes = expectNum(":");
+      seconds = expectNum(" ");
+      year = expectNum("");
+    } else {
+      expect(" ");
+      day = expectNum(format == formatRfc1123 ? " " : "-");
+      month = expectMonth(format == formatRfc1123 ? " " : "-");
+      year = expectNum(" ");
+      hours = expectNum(":");
+      minutes = expectNum(":");
+      seconds = expectNum(" ");
+      expect("GMT");
+    }
+    expectEnd();
+    return new DateTime.utc(year, month + 1, day, hours, minutes, seconds, 0);
+  }
+
+  // Parse a cookie date string.
+  static DateTime _parseCookieDate(String date) {
+    const List monthsLowerCase = const [
+      "jan",
+      "feb",
+      "mar",
+      "apr",
+      "may",
+      "jun",
+      "jul",
+      "aug",
+      "sep",
+      "oct",
+      "nov",
+      "dec"
+    ];
+
+    int position = 0;
+
+    void error() {
+      throw new HttpException("Invalid cookie date $date");
+    }
+
+    bool isEnd() => position == date.length;
+
+    bool isDelimiter(String s) {
+      int char = s.codeUnitAt(0);
+      if (char == 0x09) return true;
+      if (char >= 0x20 && char <= 0x2F) return true;
+      if (char >= 0x3B && char <= 0x40) return true;
+      if (char >= 0x5B && char <= 0x60) return true;
+      if (char >= 0x7B && char <= 0x7E) return true;
+      return false;
+    }
+
+    bool isNonDelimiter(String s) {
+      int char = s.codeUnitAt(0);
+      if (char >= 0x00 && char <= 0x08) return true;
+      if (char >= 0x0A && char <= 0x1F) return true;
+      if (char >= 0x30 && char <= 0x39) return true; // Digit
+      if (char == 0x3A) return true; // ':'
+      if (char >= 0x41 && char <= 0x5A) return true; // Alpha
+      if (char >= 0x61 && char <= 0x7A) return true; // Alpha
+      if (char >= 0x7F && char <= 0xFF) return true; // Alpha
+      return false;
+    }
+
+    bool isDigit(String s) {
+      int char = s.codeUnitAt(0);
+      if (char > 0x2F && char < 0x3A) return true;
+      return false;
+    }
+
+    int getMonth(String month) {
+      if (month.length < 3) return -1;
+      return monthsLowerCase.indexOf(month.substring(0, 3));
+    }
+
+    int toInt(String s) {
+      int index = 0;
+      for (; index < s.length && isDigit(s[index]); index++);
+      return int.parse(s.substring(0, index));
+    }
+
+    var tokens = [];
+    while (!isEnd()) {
+      while (!isEnd() && isDelimiter(date[position])) position++;
+      int start = position;
+      while (!isEnd() && isNonDelimiter(date[position])) position++;
+      tokens.add(date.substring(start, position).toLowerCase());
+      while (!isEnd() && isDelimiter(date[position])) position++;
+    }
+
+    String timeStr;
+    String dayOfMonthStr;
+    String monthStr;
+    String yearStr;
+
+    for (var token in tokens) {
+      if (token.length < 1) continue;
+      if (timeStr == null &&
+          token.length >= 5 &&
+          isDigit(token[0]) &&
+          (token[1] == ":" || (isDigit(token[1]) && token[2] == ":"))) {
+        timeStr = token;
+      } else if (dayOfMonthStr == null && isDigit(token[0])) {
+        dayOfMonthStr = token;
+      } else if (monthStr == null && getMonth(token) >= 0) {
+        monthStr = token;
+      } else if (yearStr == null &&
+          token.length >= 2 &&
+          isDigit(token[0]) &&
+          isDigit(token[1])) {
+        yearStr = token;
+      }
+    }
+
+    if (timeStr == null ||
+        dayOfMonthStr == null ||
+        monthStr == null ||
+        yearStr == null) {
+      error();
+    }
+
+    int year = toInt(yearStr);
+    if (year >= 70 && year <= 99)
+      year += 1900;
+    else if (year >= 0 && year <= 69) year += 2000;
+    if (year < 1601) error();
+
+    int dayOfMonth = toInt(dayOfMonthStr);
+    if (dayOfMonth < 1 || dayOfMonth > 31) error();
+
+    int month = getMonth(monthStr) + 1;
+
+    var timeList = timeStr.split(":");
+    if (timeList.length != 3) error();
+    int hour = toInt(timeList[0]);
+    int minute = toInt(timeList[1]);
+    int second = toInt(timeList[2]);
+    if (hour > 23) error();
+    if (minute > 59) error();
+    if (second > 59) error();
+
+    return new DateTime.utc(year, month, dayOfMonth, hour, minute, second, 0);
+  }
+}
diff --git a/sdk_nnbd/lib/_http/http_headers.dart b/sdk_nnbd/lib/_http/http_headers.dart
new file mode 100644
index 0000000..7601485
--- /dev/null
+++ b/sdk_nnbd/lib/_http/http_headers.dart
@@ -0,0 +1,1033 @@
+// 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 dart._http;
+
+class _HttpHeaders implements HttpHeaders {
+  final Map<String, List<String>> _headers;
+  final String protocolVersion;
+
+  bool _mutable = true; // Are the headers currently mutable?
+  List<String> _noFoldingHeaders;
+
+  int _contentLength = -1;
+  bool _persistentConnection = true;
+  bool _chunkedTransferEncoding = false;
+  String _host;
+  int _port;
+
+  final int _defaultPortForScheme;
+
+  _HttpHeaders(this.protocolVersion,
+      {int defaultPortForScheme: HttpClient.defaultHttpPort,
+      _HttpHeaders initialHeaders})
+      : _headers = new HashMap<String, List<String>>(),
+        _defaultPortForScheme = defaultPortForScheme {
+    if (initialHeaders != null) {
+      initialHeaders._headers.forEach((name, value) => _headers[name] = value);
+      _contentLength = initialHeaders._contentLength;
+      _persistentConnection = initialHeaders._persistentConnection;
+      _chunkedTransferEncoding = initialHeaders._chunkedTransferEncoding;
+      _host = initialHeaders._host;
+      _port = initialHeaders._port;
+    }
+    if (protocolVersion == "1.0") {
+      _persistentConnection = false;
+      _chunkedTransferEncoding = false;
+    }
+  }
+
+  List<String> operator [](String name) => _headers[name.toLowerCase()];
+
+  String value(String name) {
+    name = name.toLowerCase();
+    List<String> values = _headers[name];
+    if (values == null) return null;
+    if (values.length > 1) {
+      throw new HttpException("More than one value for header $name");
+    }
+    return values[0];
+  }
+
+  void add(String name, value) {
+    _checkMutable();
+    _addAll(_validateField(name), value);
+  }
+
+  void _addAll(String name, value) {
+    assert(name == _validateField(name));
+    if (value is Iterable) {
+      for (var v in value) {
+        _add(name, _validateValue(v));
+      }
+    } else {
+      _add(name, _validateValue(value));
+    }
+  }
+
+  void set(String name, Object value) {
+    _checkMutable();
+    name = _validateField(name);
+    _headers.remove(name);
+    if (name == HttpHeaders.transferEncodingHeader) {
+      _chunkedTransferEncoding = false;
+    }
+    _addAll(name, value);
+  }
+
+  void remove(String name, Object value) {
+    _checkMutable();
+    name = _validateField(name);
+    value = _validateValue(value);
+    List<String> values = _headers[name];
+    if (values != null) {
+      int index = values.indexOf(value);
+      if (index != -1) {
+        values.removeRange(index, index + 1);
+      }
+      if (values.length == 0) _headers.remove(name);
+    }
+    if (name == HttpHeaders.transferEncodingHeader && value == "chunked") {
+      _chunkedTransferEncoding = false;
+    }
+  }
+
+  void removeAll(String name) {
+    _checkMutable();
+    name = _validateField(name);
+    _headers.remove(name);
+  }
+
+  void forEach(void f(String name, List<String> values)) {
+    _headers.forEach(f);
+  }
+
+  void noFolding(String name) {
+    if (_noFoldingHeaders == null) _noFoldingHeaders = new List<String>();
+    _noFoldingHeaders.add(name);
+  }
+
+  bool get persistentConnection => _persistentConnection;
+
+  void set persistentConnection(bool persistentConnection) {
+    _checkMutable();
+    if (persistentConnection == _persistentConnection) return;
+    if (persistentConnection) {
+      if (protocolVersion == "1.1") {
+        remove(HttpHeaders.connectionHeader, "close");
+      } else {
+        if (_contentLength == -1) {
+          throw new HttpException(
+              "Trying to set 'Connection: Keep-Alive' on HTTP 1.0 headers with "
+              "no ContentLength");
+        }
+        add(HttpHeaders.connectionHeader, "keep-alive");
+      }
+    } else {
+      if (protocolVersion == "1.1") {
+        add(HttpHeaders.connectionHeader, "close");
+      } else {
+        remove(HttpHeaders.connectionHeader, "keep-alive");
+      }
+    }
+    _persistentConnection = persistentConnection;
+  }
+
+  int get contentLength => _contentLength;
+
+  void set contentLength(int contentLength) {
+    _checkMutable();
+    if (protocolVersion == "1.0" &&
+        persistentConnection &&
+        contentLength == -1) {
+      throw new HttpException(
+          "Trying to clear ContentLength on HTTP 1.0 headers with "
+          "'Connection: Keep-Alive' set");
+    }
+    if (_contentLength == contentLength) return;
+    _contentLength = contentLength;
+    if (_contentLength >= 0) {
+      if (chunkedTransferEncoding) chunkedTransferEncoding = false;
+      _set(HttpHeaders.contentLengthHeader, contentLength.toString());
+    } else {
+      removeAll(HttpHeaders.contentLengthHeader);
+      if (protocolVersion == "1.1") {
+        chunkedTransferEncoding = true;
+      }
+    }
+  }
+
+  bool get chunkedTransferEncoding => _chunkedTransferEncoding;
+
+  void set chunkedTransferEncoding(bool chunkedTransferEncoding) {
+    _checkMutable();
+    if (chunkedTransferEncoding && protocolVersion == "1.0") {
+      throw new HttpException(
+          "Trying to set 'Transfer-Encoding: Chunked' on HTTP 1.0 headers");
+    }
+    if (chunkedTransferEncoding == _chunkedTransferEncoding) return;
+    if (chunkedTransferEncoding) {
+      List<String> values = _headers[HttpHeaders.transferEncodingHeader];
+      if ((values == null || values.last != "chunked")) {
+        // Headers does not specify chunked encoding - add it if set.
+        _addValue(HttpHeaders.transferEncodingHeader, "chunked");
+      }
+      contentLength = -1;
+    } else {
+      // Headers does specify chunked encoding - remove it if not set.
+      remove(HttpHeaders.transferEncodingHeader, "chunked");
+    }
+    _chunkedTransferEncoding = chunkedTransferEncoding;
+  }
+
+  String get host => _host;
+
+  void set host(String host) {
+    _checkMutable();
+    _host = host;
+    _updateHostHeader();
+  }
+
+  int get port => _port;
+
+  void set port(int port) {
+    _checkMutable();
+    _port = port;
+    _updateHostHeader();
+  }
+
+  DateTime get ifModifiedSince {
+    List<String> values = _headers[HttpHeaders.ifModifiedSinceHeader];
+    if (values != null) {
+      try {
+        return HttpDate.parse(values[0]);
+      } on Exception catch (e) {
+        return null;
+      }
+    }
+    return null;
+  }
+
+  void set ifModifiedSince(DateTime ifModifiedSince) {
+    _checkMutable();
+    // Format "ifModifiedSince" header with date in Greenwich Mean Time (GMT).
+    String formatted = HttpDate.format(ifModifiedSince.toUtc());
+    _set(HttpHeaders.ifModifiedSinceHeader, formatted);
+  }
+
+  DateTime get date {
+    List<String> values = _headers[HttpHeaders.dateHeader];
+    if (values != null) {
+      try {
+        return HttpDate.parse(values[0]);
+      } on Exception catch (e) {
+        return null;
+      }
+    }
+    return null;
+  }
+
+  void set date(DateTime date) {
+    _checkMutable();
+    // Format "DateTime" header with date in Greenwich Mean Time (GMT).
+    String formatted = HttpDate.format(date.toUtc());
+    _set("date", formatted);
+  }
+
+  DateTime get expires {
+    List<String> values = _headers[HttpHeaders.expiresHeader];
+    if (values != null) {
+      try {
+        return HttpDate.parse(values[0]);
+      } on Exception catch (e) {
+        return null;
+      }
+    }
+    return null;
+  }
+
+  void set expires(DateTime expires) {
+    _checkMutable();
+    // Format "Expires" header with date in Greenwich Mean Time (GMT).
+    String formatted = HttpDate.format(expires.toUtc());
+    _set(HttpHeaders.expiresHeader, formatted);
+  }
+
+  ContentType get contentType {
+    var values = _headers["content-type"];
+    if (values != null) {
+      return ContentType.parse(values[0]);
+    } else {
+      return null;
+    }
+  }
+
+  void set contentType(ContentType contentType) {
+    _checkMutable();
+    _set(HttpHeaders.contentTypeHeader, contentType.toString());
+  }
+
+  void clear() {
+    _checkMutable();
+    _headers.clear();
+    _contentLength = -1;
+    _persistentConnection = true;
+    _chunkedTransferEncoding = false;
+    _host = null;
+    _port = null;
+  }
+
+  // [name] must be a lower-case version of the name.
+  void _add(String name, value) {
+    assert(name == _validateField(name));
+    // Use the length as index on what method to call. This is notable
+    // faster than computing hash and looking up in a hash-map.
+    switch (name.length) {
+      case 4:
+        if (HttpHeaders.dateHeader == name) {
+          _addDate(name, value);
+          return;
+        }
+        if (HttpHeaders.hostHeader == name) {
+          _addHost(name, value);
+          return;
+        }
+        break;
+      case 7:
+        if (HttpHeaders.expiresHeader == name) {
+          _addExpires(name, value);
+          return;
+        }
+        break;
+      case 10:
+        if (HttpHeaders.connectionHeader == name) {
+          _addConnection(name, value);
+          return;
+        }
+        break;
+      case 12:
+        if (HttpHeaders.contentTypeHeader == name) {
+          _addContentType(name, value);
+          return;
+        }
+        break;
+      case 14:
+        if (HttpHeaders.contentLengthHeader == name) {
+          _addContentLength(name, value);
+          return;
+        }
+        break;
+      case 17:
+        if (HttpHeaders.transferEncodingHeader == name) {
+          _addTransferEncoding(name, value);
+          return;
+        }
+        if (HttpHeaders.ifModifiedSinceHeader == name) {
+          _addIfModifiedSince(name, value);
+          return;
+        }
+    }
+    _addValue(name, value);
+  }
+
+  void _addContentLength(String name, value) {
+    if (value is int) {
+      contentLength = value;
+    } else if (value is String) {
+      contentLength = int.parse(value);
+    } else {
+      throw new HttpException("Unexpected type for header named $name");
+    }
+  }
+
+  void _addTransferEncoding(String name, value) {
+    if (value == "chunked") {
+      chunkedTransferEncoding = true;
+    } else {
+      _addValue(HttpHeaders.transferEncodingHeader, value);
+    }
+  }
+
+  void _addDate(String name, value) {
+    if (value is DateTime) {
+      date = value;
+    } else if (value is String) {
+      _set(HttpHeaders.dateHeader, value);
+    } else {
+      throw new HttpException("Unexpected type for header named $name");
+    }
+  }
+
+  void _addExpires(String name, value) {
+    if (value is DateTime) {
+      expires = value;
+    } else if (value is String) {
+      _set(HttpHeaders.expiresHeader, value);
+    } else {
+      throw new HttpException("Unexpected type for header named $name");
+    }
+  }
+
+  void _addIfModifiedSince(String name, value) {
+    if (value is DateTime) {
+      ifModifiedSince = value;
+    } else if (value is String) {
+      _set(HttpHeaders.ifModifiedSinceHeader, value);
+    } else {
+      throw new HttpException("Unexpected type for header named $name");
+    }
+  }
+
+  void _addHost(String name, value) {
+    if (value is String) {
+      int pos = value.indexOf(":");
+      if (pos == -1) {
+        _host = value;
+        _port = HttpClient.defaultHttpPort;
+      } else {
+        if (pos > 0) {
+          _host = value.substring(0, pos);
+        } else {
+          _host = null;
+        }
+        if (pos + 1 == value.length) {
+          _port = HttpClient.defaultHttpPort;
+        } else {
+          try {
+            _port = int.parse(value.substring(pos + 1));
+          } on FormatException catch (e) {
+            _port = null;
+          }
+        }
+      }
+      _set(HttpHeaders.hostHeader, value);
+    } else {
+      throw new HttpException("Unexpected type for header named $name");
+    }
+  }
+
+  void _addConnection(String name, value) {
+    var lowerCaseValue = value.toLowerCase();
+    if (lowerCaseValue == 'close') {
+      _persistentConnection = false;
+    } else if (lowerCaseValue == 'keep-alive') {
+      _persistentConnection = true;
+    }
+    _addValue(name, value);
+  }
+
+  void _addContentType(String name, value) {
+    _set(HttpHeaders.contentTypeHeader, value);
+  }
+
+  void _addValue(String name, Object value) {
+    List<String> values = _headers[name];
+    if (values == null) {
+      values = new List<String>();
+      _headers[name] = values;
+    }
+    if (value is DateTime) {
+      values.add(HttpDate.format(value));
+    } else if (value is String) {
+      values.add(value);
+    } else {
+      values.add(_validateValue(value.toString()));
+    }
+  }
+
+  void _set(String name, String value) {
+    assert(name == _validateField(name));
+    List<String> values = new List<String>();
+    _headers[name] = values;
+    values.add(value);
+  }
+
+  _checkMutable() {
+    if (!_mutable) throw new HttpException("HTTP headers are not mutable");
+  }
+
+  _updateHostHeader() {
+    bool defaultPort = _port == null || _port == _defaultPortForScheme;
+    _set("host", defaultPort ? host : "$host:$_port");
+  }
+
+  _foldHeader(String name) {
+    if (name == HttpHeaders.setCookieHeader ||
+        (_noFoldingHeaders != null && _noFoldingHeaders.indexOf(name) != -1)) {
+      return false;
+    }
+    return true;
+  }
+
+  void _finalize() {
+    _mutable = false;
+  }
+
+  void _build(BytesBuilder builder) {
+    for (String name in _headers.keys) {
+      List<String> values = _headers[name];
+      bool fold = _foldHeader(name);
+      var nameData = name.codeUnits;
+      builder.add(nameData);
+      builder.addByte(_CharCode.COLON);
+      builder.addByte(_CharCode.SP);
+      for (int i = 0; i < values.length; i++) {
+        if (i > 0) {
+          if (fold) {
+            builder.addByte(_CharCode.COMMA);
+            builder.addByte(_CharCode.SP);
+          } else {
+            builder.addByte(_CharCode.CR);
+            builder.addByte(_CharCode.LF);
+            builder.add(nameData);
+            builder.addByte(_CharCode.COLON);
+            builder.addByte(_CharCode.SP);
+          }
+        }
+        builder.add(values[i].codeUnits);
+      }
+      builder.addByte(_CharCode.CR);
+      builder.addByte(_CharCode.LF);
+    }
+  }
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    _headers.forEach((String name, List<String> values) {
+      sb..write(name)..write(": ");
+      bool fold = _foldHeader(name);
+      for (int i = 0; i < values.length; i++) {
+        if (i > 0) {
+          if (fold) {
+            sb.write(", ");
+          } else {
+            sb..write("\n")..write(name)..write(": ");
+          }
+        }
+        sb.write(values[i]);
+      }
+      sb.write("\n");
+    });
+    return sb.toString();
+  }
+
+  List<Cookie> _parseCookies() {
+    // Parse a Cookie header value according to the rules in RFC 6265.
+    var cookies = new List<Cookie>();
+    void parseCookieString(String s) {
+      int index = 0;
+
+      bool done() => index == -1 || index == s.length;
+
+      void skipWS() {
+        while (!done()) {
+          if (s[index] != " " && s[index] != "\t") return;
+          index++;
+        }
+      }
+
+      String parseName() {
+        int start = index;
+        while (!done()) {
+          if (s[index] == " " || s[index] == "\t" || s[index] == "=") break;
+          index++;
+        }
+        return s.substring(start, index);
+      }
+
+      String parseValue() {
+        int start = index;
+        while (!done()) {
+          if (s[index] == " " || s[index] == "\t" || s[index] == ";") break;
+          index++;
+        }
+        return s.substring(start, index);
+      }
+
+      bool expect(String expected) {
+        if (done()) return false;
+        if (s[index] != expected) return false;
+        index++;
+        return true;
+      }
+
+      while (!done()) {
+        skipWS();
+        if (done()) return;
+        String name = parseName();
+        skipWS();
+        if (!expect("=")) {
+          index = s.indexOf(';', index);
+          continue;
+        }
+        skipWS();
+        String value = parseValue();
+        try {
+          cookies.add(new _Cookie(name, value));
+        } catch (_) {
+          // Skip it, invalid cookie data.
+        }
+        skipWS();
+        if (done()) return;
+        if (!expect(";")) {
+          index = s.indexOf(';', index);
+          continue;
+        }
+      }
+    }
+
+    List<String> values = _headers[HttpHeaders.cookieHeader];
+    if (values != null) {
+      values.forEach((headerValue) => parseCookieString(headerValue));
+    }
+    return cookies;
+  }
+
+  static String _validateField(String field) {
+    for (var i = 0; i < field.length; i++) {
+      if (!_HttpParser._isTokenChar(field.codeUnitAt(i))) {
+        throw new FormatException(
+            "Invalid HTTP header field name: ${json.encode(field)}");
+      }
+    }
+    return field.toLowerCase();
+  }
+
+  static _validateValue(value) {
+    if (value is! String) return value;
+    for (var i = 0; i < value.length; i++) {
+      if (!_HttpParser._isValueChar(value.codeUnitAt(i))) {
+        throw new FormatException(
+            "Invalid HTTP header field value: ${json.encode(value)}");
+      }
+    }
+    return value;
+  }
+}
+
+class _HeaderValue implements HeaderValue {
+  String _value;
+  Map<String, String> _parameters;
+  Map<String, String> _unmodifiableParameters;
+
+  _HeaderValue([this._value = "", Map<String, String> parameters]) {
+    if (parameters != null) {
+      _parameters = new HashMap<String, String>.from(parameters);
+    }
+  }
+
+  static _HeaderValue parse(String value,
+      {parameterSeparator: ";",
+      valueSeparator: null,
+      preserveBackslash: false}) {
+    // Parse the string.
+    var result = new _HeaderValue();
+    result._parse(value, parameterSeparator, valueSeparator, preserveBackslash);
+    return result;
+  }
+
+  String get value => _value;
+
+  void _ensureParameters() {
+    if (_parameters == null) {
+      _parameters = new HashMap<String, String>();
+    }
+  }
+
+  Map<String, String> get parameters {
+    _ensureParameters();
+    if (_unmodifiableParameters == null) {
+      _unmodifiableParameters = new UnmodifiableMapView(_parameters);
+    }
+    return _unmodifiableParameters;
+  }
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write(_value);
+    if (parameters != null && parameters.length > 0) {
+      _parameters.forEach((String name, String value) {
+        sb..write("; ")..write(name)..write("=")..write(value);
+      });
+    }
+    return sb.toString();
+  }
+
+  void _parse(String s, String parameterSeparator, String valueSeparator,
+      bool preserveBackslash) {
+    int index = 0;
+
+    bool done() => index == s.length;
+
+    void skipWS() {
+      while (!done()) {
+        if (s[index] != " " && s[index] != "\t") return;
+        index++;
+      }
+    }
+
+    String parseValue() {
+      int start = index;
+      while (!done()) {
+        if (s[index] == " " ||
+            s[index] == "\t" ||
+            s[index] == valueSeparator ||
+            s[index] == parameterSeparator) break;
+        index++;
+      }
+      return s.substring(start, index);
+    }
+
+    void expect(String expected) {
+      if (done() || s[index] != expected) {
+        throw new HttpException("Failed to parse header value");
+      }
+      index++;
+    }
+
+    void maybeExpect(String expected) {
+      if (s[index] == expected) index++;
+    }
+
+    void parseParameters() {
+      var parameters = new HashMap<String, String>();
+      _parameters = new UnmodifiableMapView(parameters);
+
+      String parseParameterName() {
+        int start = index;
+        while (!done()) {
+          if (s[index] == " " ||
+              s[index] == "\t" ||
+              s[index] == "=" ||
+              s[index] == parameterSeparator ||
+              s[index] == valueSeparator) break;
+          index++;
+        }
+        return s.substring(start, index).toLowerCase();
+      }
+
+      String parseParameterValue() {
+        if (!done() && s[index] == "\"") {
+          // Parse quoted value.
+          StringBuffer sb = new StringBuffer();
+          index++;
+          while (!done()) {
+            if (s[index] == "\\") {
+              if (index + 1 == s.length) {
+                throw new HttpException("Failed to parse header value");
+              }
+              if (preserveBackslash && s[index + 1] != "\"") {
+                sb.write(s[index]);
+              }
+              index++;
+            } else if (s[index] == "\"") {
+              index++;
+              break;
+            }
+            sb.write(s[index]);
+            index++;
+          }
+          return sb.toString();
+        } else {
+          // Parse non-quoted value.
+          var val = parseValue();
+          return val == "" ? null : val;
+        }
+      }
+
+      while (!done()) {
+        skipWS();
+        if (done()) return;
+        String name = parseParameterName();
+        skipWS();
+        if (done()) {
+          parameters[name] = null;
+          return;
+        }
+        maybeExpect("=");
+        skipWS();
+        if (done()) {
+          parameters[name] = null;
+          return;
+        }
+        String value = parseParameterValue();
+        if (name == 'charset' && this is _ContentType && value != null) {
+          // Charset parameter of ContentTypes are always lower-case.
+          value = value.toLowerCase();
+        }
+        parameters[name] = value;
+        skipWS();
+        if (done()) return;
+        // TODO: Implement support for multi-valued parameters.
+        if (s[index] == valueSeparator) return;
+        expect(parameterSeparator);
+      }
+    }
+
+    skipWS();
+    _value = parseValue();
+    skipWS();
+    if (done()) return;
+    maybeExpect(parameterSeparator);
+    parseParameters();
+  }
+}
+
+class _ContentType extends _HeaderValue implements ContentType {
+  String _primaryType = "";
+  String _subType = "";
+
+  _ContentType(String primaryType, String subType, String charset,
+      Map<String, String> parameters)
+      : _primaryType = primaryType,
+        _subType = subType,
+        super("") {
+    if (_primaryType == null) _primaryType = "";
+    if (_subType == null) _subType = "";
+    _value = "$_primaryType/$_subType";
+    if (parameters != null) {
+      _ensureParameters();
+      parameters.forEach((String key, String value) {
+        String lowerCaseKey = key.toLowerCase();
+        if (lowerCaseKey == "charset") {
+          value = value.toLowerCase();
+        }
+        this._parameters[lowerCaseKey] = value;
+      });
+    }
+    if (charset != null) {
+      _ensureParameters();
+      this._parameters["charset"] = charset.toLowerCase();
+    }
+  }
+
+  _ContentType._();
+
+  static _ContentType parse(String value) {
+    var result = new _ContentType._();
+    result._parse(value, ";", null, false);
+    int index = result._value.indexOf("/");
+    if (index == -1 || index == (result._value.length - 1)) {
+      result._primaryType = result._value.trim().toLowerCase();
+      result._subType = "";
+    } else {
+      result._primaryType =
+          result._value.substring(0, index).trim().toLowerCase();
+      result._subType = result._value.substring(index + 1).trim().toLowerCase();
+    }
+    return result;
+  }
+
+  String get mimeType => '$primaryType/$subType';
+
+  String get primaryType => _primaryType;
+
+  String get subType => _subType;
+
+  String get charset => parameters["charset"];
+}
+
+class _Cookie implements Cookie {
+  String _name;
+  String _value;
+  DateTime expires;
+  int maxAge;
+  String domain;
+  String path;
+  bool httpOnly = false;
+  bool secure = false;
+
+  _Cookie(String name, String value)
+      : _name = _validateName(name),
+        _value = _validateValue(value),
+        httpOnly = true;
+
+  String get name => _name;
+  String get value => _value;
+
+  set name(String newName) {
+    _validateName(newName);
+    _name = newName;
+  }
+
+  set value(String newValue) {
+    _validateValue(newValue);
+    _value = newValue;
+  }
+
+  _Cookie.fromSetCookieValue(String value) {
+    // Parse the 'set-cookie' header value.
+    _parseSetCookieValue(value);
+  }
+
+  // Parse a 'set-cookie' header value according to the rules in RFC 6265.
+  void _parseSetCookieValue(String s) {
+    int index = 0;
+
+    bool done() => index == s.length;
+
+    String parseName() {
+      int start = index;
+      while (!done()) {
+        if (s[index] == "=") break;
+        index++;
+      }
+      return s.substring(start, index).trim();
+    }
+
+    String parseValue() {
+      int start = index;
+      while (!done()) {
+        if (s[index] == ";") break;
+        index++;
+      }
+      return s.substring(start, index).trim();
+    }
+
+    void expect(String expected) {
+      if (done()) throw new HttpException("Failed to parse header value [$s]");
+      if (s[index] != expected) {
+        throw new HttpException("Failed to parse header value [$s]");
+      }
+      index++;
+    }
+
+    void parseAttributes() {
+      String parseAttributeName() {
+        int start = index;
+        while (!done()) {
+          if (s[index] == "=" || s[index] == ";") break;
+          index++;
+        }
+        return s.substring(start, index).trim().toLowerCase();
+      }
+
+      String parseAttributeValue() {
+        int start = index;
+        while (!done()) {
+          if (s[index] == ";") break;
+          index++;
+        }
+        return s.substring(start, index).trim().toLowerCase();
+      }
+
+      while (!done()) {
+        String name = parseAttributeName();
+        String value = "";
+        if (!done() && s[index] == "=") {
+          index++; // Skip the = character.
+          value = parseAttributeValue();
+        }
+        if (name == "expires") {
+          expires = HttpDate._parseCookieDate(value);
+        } else if (name == "max-age") {
+          maxAge = int.parse(value);
+        } else if (name == "domain") {
+          domain = value;
+        } else if (name == "path") {
+          path = value;
+        } else if (name == "httponly") {
+          httpOnly = true;
+        } else if (name == "secure") {
+          secure = true;
+        }
+        if (!done()) index++; // Skip the ; character
+      }
+    }
+
+    _name = _validateName(parseName());
+    if (done() || _name.length == 0) {
+      throw new HttpException("Failed to parse header value [$s]");
+    }
+    index++; // Skip the = character.
+    _value = _validateValue(parseValue());
+    if (done()) return;
+    index++; // Skip the ; character.
+    parseAttributes();
+  }
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb..write(_name)..write("=")..write(_value);
+    if (expires != null) {
+      sb..write("; Expires=")..write(HttpDate.format(expires));
+    }
+    if (maxAge != null) {
+      sb..write("; Max-Age=")..write(maxAge);
+    }
+    if (domain != null) {
+      sb..write("; Domain=")..write(domain);
+    }
+    if (path != null) {
+      sb..write("; Path=")..write(path);
+    }
+    if (secure) sb.write("; Secure");
+    if (httpOnly) sb.write("; HttpOnly");
+    return sb.toString();
+  }
+
+  static String _validateName(String newName) {
+    const separators = const [
+      "(",
+      ")",
+      "<",
+      ">",
+      "@",
+      ",",
+      ";",
+      ":",
+      "\\",
+      '"',
+      "/",
+      "[",
+      "]",
+      "?",
+      "=",
+      "{",
+      "}"
+    ];
+    if (newName == null) throw new ArgumentError.notNull("name");
+    for (int i = 0; i < newName.length; i++) {
+      int codeUnit = newName.codeUnits[i];
+      if (codeUnit <= 32 ||
+          codeUnit >= 127 ||
+          separators.indexOf(newName[i]) >= 0) {
+        throw new FormatException(
+            "Invalid character in cookie name, code unit: '$codeUnit'",
+            newName,
+            i);
+      }
+    }
+    return newName;
+  }
+
+  static String _validateValue(String newValue) {
+    if (newValue == null) throw new ArgumentError.notNull("value");
+    // Per RFC 6265, consider surrounding "" as part of the value, but otherwise
+    // double quotes are not allowed.
+    int start = 0;
+    int end = newValue.length;
+    if (2 <= newValue.length &&
+        newValue.codeUnits[start] == 0x22 &&
+        newValue.codeUnits[end - 1] == 0x22) {
+      start++;
+      end--;
+    }
+
+    for (int i = start; i < end; i++) {
+      int codeUnit = newValue.codeUnits[i];
+      if (!(codeUnit == 0x21 ||
+          (codeUnit >= 0x23 && codeUnit <= 0x2B) ||
+          (codeUnit >= 0x2D && codeUnit <= 0x3A) ||
+          (codeUnit >= 0x3C && codeUnit <= 0x5B) ||
+          (codeUnit >= 0x5D && codeUnit <= 0x7E))) {
+        throw new FormatException(
+            "Invalid character in cookie value, code unit: '$codeUnit'",
+            newValue,
+            i);
+      }
+    }
+    return newValue;
+  }
+}
diff --git a/sdk_nnbd/lib/_http/http_impl.dart b/sdk_nnbd/lib/_http/http_impl.dart
new file mode 100644
index 0000000..cdf2412
--- /dev/null
+++ b/sdk_nnbd/lib/_http/http_impl.dart
@@ -0,0 +1,3237 @@
+// 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 dart._http;
+
+int _nextServiceId = 1;
+
+// TODO(ajohnsen): Use other way of getting a unique id.
+abstract class _ServiceObject {
+  int __serviceId = 0;
+  int get _serviceId {
+    if (__serviceId == 0) __serviceId = _nextServiceId++;
+    return __serviceId;
+  }
+
+  Map _toJSON(bool ref);
+
+  String get _servicePath => "$_serviceTypePath/$_serviceId";
+
+  String get _serviceTypePath;
+
+  String get _serviceTypeName;
+
+  String _serviceType(bool ref) {
+    if (ref) return "@$_serviceTypeName";
+    return _serviceTypeName;
+  }
+}
+
+class _CopyingBytesBuilder implements BytesBuilder {
+  // Start with 1024 bytes.
+  static const int _INIT_SIZE = 1024;
+
+  static final _emptyList = new Uint8List(0);
+
+  int _length = 0;
+  Uint8List _buffer;
+
+  _CopyingBytesBuilder([int initialCapacity = 0])
+      : _buffer = (initialCapacity <= 0)
+            ? _emptyList
+            : new Uint8List(_pow2roundup(initialCapacity));
+
+  void add(List<int> bytes) {
+    int bytesLength = bytes.length;
+    if (bytesLength == 0) return;
+    int required = _length + bytesLength;
+    if (_buffer.length < required) {
+      _grow(required);
+    }
+    assert(_buffer.length >= required);
+    if (bytes is Uint8List) {
+      _buffer.setRange(_length, required, bytes);
+    } else {
+      for (int i = 0; i < bytesLength; i++) {
+        _buffer[_length + i] = bytes[i];
+      }
+    }
+    _length = required;
+  }
+
+  void addByte(int byte) {
+    if (_buffer.length == _length) {
+      // The grow algorithm always at least doubles.
+      // If we added one to _length it would quadruple unnecessarily.
+      _grow(_length);
+    }
+    assert(_buffer.length > _length);
+    _buffer[_length] = byte;
+    _length++;
+  }
+
+  void _grow(int required) {
+    // We will create a list in the range of 2-4 times larger than
+    // required.
+    int newSize = required * 2;
+    if (newSize < _INIT_SIZE) {
+      newSize = _INIT_SIZE;
+    } else {
+      newSize = _pow2roundup(newSize);
+    }
+    var newBuffer = new Uint8List(newSize);
+    newBuffer.setRange(0, _buffer.length, _buffer);
+    _buffer = newBuffer;
+  }
+
+  Uint8List takeBytes() {
+    if (_length == 0) return _emptyList;
+    var buffer = new Uint8List.view(_buffer.buffer, 0, _length);
+    clear();
+    return buffer;
+  }
+
+  Uint8List toBytes() {
+    if (_length == 0) return _emptyList;
+    return new Uint8List.fromList(
+        new Uint8List.view(_buffer.buffer, 0, _length));
+  }
+
+  int get length => _length;
+
+  bool get isEmpty => _length == 0;
+
+  bool get isNotEmpty => _length != 0;
+
+  void clear() {
+    _length = 0;
+    _buffer = _emptyList;
+  }
+
+  static int _pow2roundup(int x) {
+    assert(x > 0);
+    --x;
+    x |= x >> 1;
+    x |= x >> 2;
+    x |= x >> 4;
+    x |= x >> 8;
+    x |= x >> 16;
+    return x + 1;
+  }
+}
+
+const int _OUTGOING_BUFFER_SIZE = 8 * 1024;
+
+typedef void _BytesConsumer(List<int> bytes);
+
+class _HttpIncoming extends Stream<Uint8List> {
+  final int _transferLength;
+  final Completer _dataCompleter = new Completer();
+  Stream<Uint8List> _stream;
+
+  bool fullBodyRead = false;
+
+  // Common properties.
+  final _HttpHeaders headers;
+  bool upgraded = false;
+
+  // ClientResponse properties.
+  int statusCode;
+  String reasonPhrase;
+
+  // Request properties.
+  String method;
+  Uri uri;
+
+  bool hasSubscriber = false;
+
+  // The transfer length if the length of the message body as it
+  // appears in the message (RFC 2616 section 4.4). This can be -1 if
+  // the length of the massage body is not known due to transfer
+  // codings.
+  int get transferLength => _transferLength;
+
+  _HttpIncoming(this.headers, this._transferLength, this._stream);
+
+  StreamSubscription<Uint8List> listen(void onData(Uint8List event),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    hasSubscriber = true;
+    return _stream.handleError((error) {
+      throw new HttpException(error.message, uri: uri);
+    }).listen(onData,
+        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+  }
+
+  // Is completed once all data have been received.
+  Future get dataDone => _dataCompleter.future;
+
+  void close(bool closing) {
+    fullBodyRead = true;
+    hasSubscriber = true;
+    _dataCompleter.complete(closing);
+  }
+}
+
+abstract class _HttpInboundMessageListInt extends Stream<List<int>> {
+  final _HttpIncoming _incoming;
+  List<Cookie> _cookies;
+
+  _HttpInboundMessageListInt(this._incoming);
+
+  List<Cookie> get cookies {
+    if (_cookies != null) return _cookies;
+    return _cookies = headers._parseCookies();
+  }
+
+  _HttpHeaders get headers => _incoming.headers;
+  String get protocolVersion => headers.protocolVersion;
+  int get contentLength => headers.contentLength;
+  bool get persistentConnection => headers.persistentConnection;
+}
+
+abstract class _HttpInboundMessage extends Stream<Uint8List> {
+  final _HttpIncoming _incoming;
+  List<Cookie> _cookies;
+
+  _HttpInboundMessage(this._incoming);
+
+  List<Cookie> get cookies {
+    if (_cookies != null) return _cookies;
+    return _cookies = headers._parseCookies();
+  }
+
+  _HttpHeaders get headers => _incoming.headers;
+  String get protocolVersion => headers.protocolVersion;
+  int get contentLength => headers.contentLength;
+  bool get persistentConnection => headers.persistentConnection;
+}
+
+class _HttpRequest extends _HttpInboundMessage implements HttpRequest {
+  final HttpResponse response;
+
+  final _HttpServer _httpServer;
+
+  final _HttpConnection _httpConnection;
+
+  _HttpSession _session;
+
+  Uri _requestedUri;
+
+  _HttpRequest(this.response, _HttpIncoming _incoming, this._httpServer,
+      this._httpConnection)
+      : super(_incoming) {
+    if (headers.protocolVersion == "1.1") {
+      response.headers
+        ..chunkedTransferEncoding = true
+        ..persistentConnection = headers.persistentConnection;
+    }
+
+    if (_httpServer._sessionManagerInstance != null) {
+      // Map to session if exists.
+      var sessionIds = cookies
+          .where((cookie) => cookie.name.toUpperCase() == _DART_SESSION_ID)
+          .map((cookie) => cookie.value);
+      for (var sessionId in sessionIds) {
+        _session = _httpServer._sessionManager.getSession(sessionId);
+        if (_session != null) {
+          _session._markSeen();
+          break;
+        }
+      }
+    }
+  }
+
+  StreamSubscription<Uint8List> listen(void onData(Uint8List event),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    return _incoming.listen(onData,
+        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+  }
+
+  Uri get uri => _incoming.uri;
+
+  Uri get requestedUri {
+    if (_requestedUri == null) {
+      var proto = headers['x-forwarded-proto'];
+      var scheme = proto != null
+          ? proto.first
+          : _httpConnection._socket is SecureSocket ? "https" : "http";
+      var hostList = headers['x-forwarded-host'];
+      String host;
+      if (hostList != null) {
+        host = hostList.first;
+      } else {
+        hostList = headers['host'];
+        if (hostList != null) {
+          host = hostList.first;
+        } else {
+          host = "${_httpServer.address.host}:${_httpServer.port}";
+        }
+      }
+      _requestedUri = Uri.parse("$scheme://$host$uri");
+    }
+    return _requestedUri;
+  }
+
+  String get method => _incoming.method;
+
+  HttpSession get session {
+    if (_session != null) {
+      if (_session._destroyed) {
+        // It's destroyed, clear it.
+        _session = null;
+        // Create new session object by calling recursive.
+        return session;
+      }
+      // It's already mapped, use it.
+      return _session;
+    }
+    // Create session, store it in connection, and return.
+    return _session = _httpServer._sessionManager.createSession();
+  }
+
+  HttpConnectionInfo get connectionInfo => _httpConnection.connectionInfo;
+
+  X509Certificate get certificate {
+    var socket = _httpConnection._socket;
+    if (socket is SecureSocket) return socket.peerCertificate;
+    return null;
+  }
+}
+
+class _HttpClientResponse extends _HttpInboundMessageListInt
+    implements HttpClientResponse {
+  List<RedirectInfo> get redirects => _httpRequest._responseRedirects;
+
+  // The HttpClient this response belongs to.
+  final _HttpClient _httpClient;
+
+  // The HttpClientRequest of this response.
+  final _HttpClientRequest _httpRequest;
+
+  // The compression state of this response.
+  final HttpClientResponseCompressionState compressionState;
+
+  _HttpClientResponse(
+      _HttpIncoming _incoming, this._httpRequest, this._httpClient)
+      : compressionState = _getCompressionState(_httpClient, _incoming.headers),
+        super(_incoming) {
+    // Set uri for potential exceptions.
+    _incoming.uri = _httpRequest.uri;
+  }
+
+  static HttpClientResponseCompressionState _getCompressionState(
+      _HttpClient httpClient, _HttpHeaders headers) {
+    if (headers.value(HttpHeaders.contentEncodingHeader) == "gzip") {
+      return httpClient.autoUncompress
+          ? HttpClientResponseCompressionState.decompressed
+          : HttpClientResponseCompressionState.compressed;
+    } else {
+      return HttpClientResponseCompressionState.notCompressed;
+    }
+  }
+
+  int get statusCode => _incoming.statusCode;
+  String get reasonPhrase => _incoming.reasonPhrase;
+
+  X509Certificate get certificate {
+    var socket = _httpRequest._httpClientConnection._socket;
+    if (socket is SecureSocket) return socket.peerCertificate;
+    return null;
+  }
+
+  List<Cookie> get cookies {
+    if (_cookies != null) return _cookies;
+    _cookies = new List<Cookie>();
+    List<String> values = headers[HttpHeaders.setCookieHeader];
+    if (values != null) {
+      values.forEach((value) {
+        _cookies.add(new Cookie.fromSetCookieValue(value));
+      });
+    }
+    return _cookies;
+  }
+
+  bool get isRedirect {
+    if (_httpRequest.method == "GET" || _httpRequest.method == "HEAD") {
+      return statusCode == HttpStatus.movedPermanently ||
+          statusCode == HttpStatus.found ||
+          statusCode == HttpStatus.seeOther ||
+          statusCode == HttpStatus.temporaryRedirect;
+    } else if (_httpRequest.method == "POST") {
+      return statusCode == HttpStatus.seeOther;
+    }
+    return false;
+  }
+
+  Future<HttpClientResponse> redirect(
+      [String method, Uri url, bool followLoops]) {
+    if (method == null) {
+      // Set method as defined by RFC 2616 section 10.3.4.
+      if (statusCode == HttpStatus.seeOther && _httpRequest.method == "POST") {
+        method = "GET";
+      } else {
+        method = _httpRequest.method;
+      }
+    }
+    if (url == null) {
+      String location = headers.value(HttpHeaders.locationHeader);
+      if (location == null) {
+        throw new StateError("Response has no Location header for redirect");
+      }
+      url = Uri.parse(location);
+    }
+    if (followLoops != true) {
+      for (var redirect in redirects) {
+        if (redirect.location == url) {
+          return new Future.error(
+              new RedirectException("Redirect loop detected", redirects));
+        }
+      }
+    }
+    return _httpClient
+        ._openUrlFromRequest(method, url, _httpRequest)
+        .then((request) {
+      request._responseRedirects
+        ..addAll(this.redirects)
+        ..add(new _RedirectInfo(statusCode, method, url));
+      return request.close();
+    });
+  }
+
+  StreamSubscription<Uint8List> listen(void onData(Uint8List event),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    if (_incoming.upgraded) {
+      // If upgraded, the connection is already 'removed' form the client.
+      // Since listening to upgraded data is 'bogus', simply close and
+      // return empty stream subscription.
+      _httpRequest._httpClientConnection.destroy();
+      return new Stream<Uint8List>.empty().listen(null, onDone: onDone);
+    }
+    Stream<Uint8List> stream = _incoming;
+    if (compressionState == HttpClientResponseCompressionState.decompressed) {
+      stream = stream
+          .cast<List<int>>()
+          .transform(gzip.decoder)
+          .transform(const _ToUint8List());
+    }
+    return stream.listen(onData,
+        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+  }
+
+  Future<Socket> detachSocket() {
+    _httpClient._connectionClosed(_httpRequest._httpClientConnection);
+    return _httpRequest._httpClientConnection.detachSocket();
+  }
+
+  HttpConnectionInfo get connectionInfo => _httpRequest.connectionInfo;
+
+  bool get _shouldAuthenticateProxy {
+    // Only try to authenticate if there is a challenge in the response.
+    List<String> challenge = headers[HttpHeaders.proxyAuthenticateHeader];
+    return statusCode == HttpStatus.proxyAuthenticationRequired &&
+        challenge != null &&
+        challenge.length == 1;
+  }
+
+  bool get _shouldAuthenticate {
+    // Only try to authenticate if there is a challenge in the response.
+    List<String> challenge = headers[HttpHeaders.wwwAuthenticateHeader];
+    return statusCode == HttpStatus.unauthorized &&
+        challenge != null &&
+        challenge.length == 1;
+  }
+
+  Future<HttpClientResponse> _authenticate(bool proxyAuth) {
+    Future<HttpClientResponse> retry() {
+      // Drain body and retry.
+      return drain().then((_) {
+        return _httpClient
+            ._openUrlFromRequest(
+                _httpRequest.method, _httpRequest.uri, _httpRequest)
+            .then((request) => request.close());
+      });
+    }
+
+    List<String> authChallenge() {
+      return proxyAuth
+          ? headers[HttpHeaders.proxyAuthenticateHeader]
+          : headers[HttpHeaders.wwwAuthenticateHeader];
+    }
+
+    _Credentials findCredentials(_AuthenticationScheme scheme) {
+      return proxyAuth
+          ? _httpClient._findProxyCredentials(_httpRequest._proxy, scheme)
+          : _httpClient._findCredentials(_httpRequest.uri, scheme);
+    }
+
+    void removeCredentials(_Credentials cr) {
+      if (proxyAuth) {
+        _httpClient._removeProxyCredentials(cr);
+      } else {
+        _httpClient._removeCredentials(cr);
+      }
+    }
+
+    Future requestAuthentication(_AuthenticationScheme scheme, String realm) {
+      if (proxyAuth) {
+        if (_httpClient._authenticateProxy == null) {
+          return new Future.value(false);
+        }
+        var proxy = _httpRequest._proxy;
+        return _httpClient._authenticateProxy(
+            proxy.host, proxy.port, scheme.toString(), realm);
+      } else {
+        if (_httpClient._authenticate == null) {
+          return new Future.value(false);
+        }
+        return _httpClient._authenticate(
+            _httpRequest.uri, scheme.toString(), realm);
+      }
+    }
+
+    List<String> challenge = authChallenge();
+    assert(challenge != null || challenge.length == 1);
+    _HeaderValue header =
+        _HeaderValue.parse(challenge[0], parameterSeparator: ",");
+    _AuthenticationScheme scheme =
+        new _AuthenticationScheme.fromString(header.value);
+    String realm = header.parameters["realm"];
+
+    // See if any matching credentials are available.
+    _Credentials cr = findCredentials(scheme);
+    if (cr != null) {
+      // For basic authentication don't retry already used credentials
+      // as they must have already been added to the request causing
+      // this authenticate response.
+      if (cr.scheme == _AuthenticationScheme.BASIC && !cr.used) {
+        // Credentials where found, prepare for retrying the request.
+        return retry();
+      }
+
+      // Digest authentication only supports the MD5 algorithm.
+      if (cr.scheme == _AuthenticationScheme.DIGEST &&
+          (header.parameters["algorithm"] == null ||
+              header.parameters["algorithm"].toLowerCase() == "md5")) {
+        if (cr.nonce == null || cr.nonce == header.parameters["nonce"]) {
+          // If the nonce is not set then this is the first authenticate
+          // response for these credentials. Set up authentication state.
+          if (cr.nonce == null) {
+            cr
+              ..nonce = header.parameters["nonce"]
+              ..algorithm = "MD5"
+              ..qop = header.parameters["qop"]
+              ..nonceCount = 0;
+          }
+          // Credentials where found, prepare for retrying the request.
+          return retry();
+        } else if (header.parameters["stale"] != null &&
+            header.parameters["stale"].toLowerCase() == "true") {
+          // If stale is true retry with new nonce.
+          cr.nonce = header.parameters["nonce"];
+          // Credentials where found, prepare for retrying the request.
+          return retry();
+        }
+      }
+    }
+
+    // Ask for more credentials if none found or the one found has
+    // already been used. If it has already been used it must now be
+    // invalid and is removed.
+    if (cr != null) {
+      removeCredentials(cr);
+      cr = null;
+    }
+    return requestAuthentication(scheme, realm).then((credsAvailable) {
+      if (credsAvailable) {
+        cr = _httpClient._findCredentials(_httpRequest.uri, scheme);
+        return retry();
+      } else {
+        // No credentials available, complete with original response.
+        return this;
+      }
+    });
+  }
+}
+
+class _ToUint8List extends Converter<List<int>, Uint8List> {
+  const _ToUint8List();
+
+  Uint8List convert(List<int> input) => Uint8List.fromList(input);
+
+  Sink<List<int>> startChunkedConversion(Sink<Uint8List> sink) {
+    return _Uint8ListConversionSink(sink);
+  }
+}
+
+class _Uint8ListConversionSink implements Sink<List<int>> {
+  const _Uint8ListConversionSink(this._target);
+
+  final Sink<Uint8List> _target;
+
+  void add(List<int> data) {
+    _target.add(Uint8List.fromList(data));
+  }
+
+  void close() {
+    _target.close();
+  }
+}
+
+class _StreamSinkImpl<T> implements StreamSink<T> {
+  final StreamConsumer<T> _target;
+  final Completer _doneCompleter = new Completer();
+  StreamController<T> _controllerInstance;
+  Completer _controllerCompleter;
+  bool _isClosed = false;
+  bool _isBound = false;
+  bool _hasError = false;
+
+  _StreamSinkImpl(this._target);
+
+  void add(T data) {
+    if (_isClosed) {
+      throw StateError("StreamSink is closed");
+    }
+    _controller.add(data);
+  }
+
+  void addError(error, [StackTrace stackTrace]) {
+    if (_isClosed) {
+      throw StateError("StreamSink is closed");
+    }
+    _controller.addError(error, stackTrace);
+  }
+
+  Future addStream(Stream<T> stream) {
+    if (_isBound) {
+      throw new StateError("StreamSink is already bound to a stream");
+    }
+    _isBound = true;
+    if (_hasError) return done;
+    // Wait for any sync operations to complete.
+    Future targetAddStream() {
+      return _target.addStream(stream).whenComplete(() {
+        _isBound = false;
+      });
+    }
+
+    if (_controllerInstance == null) return targetAddStream();
+    var future = _controllerCompleter.future;
+    _controllerInstance.close();
+    return future.then((_) => targetAddStream());
+  }
+
+  Future flush() {
+    if (_isBound) {
+      throw new StateError("StreamSink is bound to a stream");
+    }
+    if (_controllerInstance == null) return new Future.value(this);
+    // Adding an empty stream-controller will return a future that will complete
+    // when all data is done.
+    _isBound = true;
+    var future = _controllerCompleter.future;
+    _controllerInstance.close();
+    return future.whenComplete(() {
+      _isBound = false;
+    });
+  }
+
+  Future close() {
+    if (_isBound) {
+      throw new StateError("StreamSink is bound to a stream");
+    }
+    if (!_isClosed) {
+      _isClosed = true;
+      if (_controllerInstance != null) {
+        _controllerInstance.close();
+      } else {
+        _closeTarget();
+      }
+    }
+    return done;
+  }
+
+  void _closeTarget() {
+    _target.close().then(_completeDoneValue, onError: _completeDoneError);
+  }
+
+  Future get done => _doneCompleter.future;
+
+  void _completeDoneValue(value) {
+    if (!_doneCompleter.isCompleted) {
+      _doneCompleter.complete(value);
+    }
+  }
+
+  void _completeDoneError(error, StackTrace stackTrace) {
+    if (!_doneCompleter.isCompleted) {
+      _hasError = true;
+      _doneCompleter.completeError(error, stackTrace);
+    }
+  }
+
+  StreamController<T> get _controller {
+    if (_isBound) {
+      throw new StateError("StreamSink is bound to a stream");
+    }
+    if (_isClosed) {
+      throw new StateError("StreamSink is closed");
+    }
+    if (_controllerInstance == null) {
+      _controllerInstance = new StreamController<T>(sync: true);
+      _controllerCompleter = new Completer();
+      _target.addStream(_controller.stream).then((_) {
+        if (_isBound) {
+          // A new stream takes over - forward values to that stream.
+          _controllerCompleter.complete(this);
+          _controllerCompleter = null;
+          _controllerInstance = null;
+        } else {
+          // No new stream, .close was called. Close _target.
+          _closeTarget();
+        }
+      }, onError: (error, stackTrace) {
+        if (_isBound) {
+          // A new stream takes over - forward errors to that stream.
+          _controllerCompleter.completeError(error, stackTrace);
+          _controllerCompleter = null;
+          _controllerInstance = null;
+        } else {
+          // No new stream. No need to close target, as it has already
+          // failed.
+          _completeDoneError(error, stackTrace);
+        }
+      });
+    }
+    return _controllerInstance;
+  }
+}
+
+class _IOSinkImpl extends _StreamSinkImpl<List<int>> implements IOSink {
+  Encoding _encoding;
+  bool _encodingMutable = true;
+
+  _IOSinkImpl(StreamConsumer<List<int>> target, this._encoding) : super(target);
+
+  Encoding get encoding => _encoding;
+
+  void set encoding(Encoding value) {
+    if (!_encodingMutable) {
+      throw new StateError("IOSink encoding is not mutable");
+    }
+    _encoding = value;
+  }
+
+  void write(Object obj) {
+    String string = '$obj';
+    if (string.isEmpty) return;
+    add(_encoding.encode(string));
+  }
+
+  void writeAll(Iterable objects, [String separator = ""]) {
+    Iterator iterator = objects.iterator;
+    if (!iterator.moveNext()) return;
+    if (separator.isEmpty) {
+      do {
+        write(iterator.current);
+      } while (iterator.moveNext());
+    } else {
+      write(iterator.current);
+      while (iterator.moveNext()) {
+        write(separator);
+        write(iterator.current);
+      }
+    }
+  }
+
+  void writeln([Object object = ""]) {
+    write(object);
+    write("\n");
+  }
+
+  void writeCharCode(int charCode) {
+    write(new String.fromCharCode(charCode));
+  }
+}
+
+abstract class _HttpOutboundMessage<T> extends _IOSinkImpl {
+  // Used to mark when the body should be written. This is used for HEAD
+  // requests and in error handling.
+  bool _encodingSet = false;
+
+  bool _bufferOutput = true;
+
+  final Uri _uri;
+  final _HttpOutgoing _outgoing;
+
+  final _HttpHeaders headers;
+
+  _HttpOutboundMessage(Uri uri, String protocolVersion, _HttpOutgoing outgoing,
+      {_HttpHeaders initialHeaders})
+      : _uri = uri,
+        headers = new _HttpHeaders(protocolVersion,
+            defaultPortForScheme: uri.scheme == 'https'
+                ? HttpClient.defaultHttpsPort
+                : HttpClient.defaultHttpPort,
+            initialHeaders: initialHeaders),
+        _outgoing = outgoing,
+        super(outgoing, null) {
+    _outgoing.outbound = this;
+    _encodingMutable = false;
+  }
+
+  int get contentLength => headers.contentLength;
+  void set contentLength(int contentLength) {
+    headers.contentLength = contentLength;
+  }
+
+  bool get persistentConnection => headers.persistentConnection;
+  void set persistentConnection(bool p) {
+    headers.persistentConnection = p;
+  }
+
+  bool get bufferOutput => _bufferOutput;
+  void set bufferOutput(bool bufferOutput) {
+    if (_outgoing.headersWritten) throw new StateError("Header already sent");
+    _bufferOutput = bufferOutput;
+  }
+
+  Encoding get encoding {
+    if (_encodingSet && _outgoing.headersWritten) {
+      return _encoding;
+    }
+    var charset;
+    if (headers.contentType != null && headers.contentType.charset != null) {
+      charset = headers.contentType.charset;
+    } else {
+      charset = "iso-8859-1";
+    }
+    return Encoding.getByName(charset);
+  }
+
+  void add(List<int> data) {
+    if (data.length == 0) return;
+    super.add(data);
+  }
+
+  void write(Object obj) {
+    if (!_encodingSet) {
+      _encoding = encoding;
+      _encodingSet = true;
+    }
+    super.write(obj);
+  }
+
+  void _writeHeader();
+
+  bool get _isConnectionClosed => false;
+}
+
+class _HttpResponse extends _HttpOutboundMessage<HttpResponse>
+    implements HttpResponse {
+  int _statusCode = 200;
+  String _reasonPhrase;
+  List<Cookie> _cookies;
+  _HttpRequest _httpRequest;
+  Duration _deadline;
+  Timer _deadlineTimer;
+
+  _HttpResponse(Uri uri, String protocolVersion, _HttpOutgoing outgoing,
+      HttpHeaders defaultHeaders, String serverHeader)
+      : super(uri, protocolVersion, outgoing, initialHeaders: defaultHeaders) {
+    if (serverHeader != null) headers.set('server', serverHeader);
+  }
+
+  bool get _isConnectionClosed => _httpRequest._httpConnection._isClosing;
+
+  List<Cookie> get cookies {
+    if (_cookies == null) _cookies = new List<Cookie>();
+    return _cookies;
+  }
+
+  int get statusCode => _statusCode;
+  void set statusCode(int statusCode) {
+    if (_outgoing.headersWritten) throw new StateError("Header already sent");
+    _statusCode = statusCode;
+  }
+
+  String get reasonPhrase => _findReasonPhrase(statusCode);
+  void set reasonPhrase(String reasonPhrase) {
+    if (_outgoing.headersWritten) throw new StateError("Header already sent");
+    _reasonPhrase = reasonPhrase;
+  }
+
+  Future redirect(Uri location, {int status: HttpStatus.movedTemporarily}) {
+    if (_outgoing.headersWritten) throw new StateError("Header already sent");
+    statusCode = status;
+    headers.set("location", location.toString());
+    return close();
+  }
+
+  Future<Socket> detachSocket({bool writeHeaders: true}) {
+    if (_outgoing.headersWritten) throw new StateError("Headers already sent");
+    deadline = null; // Be sure to stop any deadline.
+    var future = _httpRequest._httpConnection.detachSocket();
+    if (writeHeaders) {
+      var headersFuture =
+          _outgoing.writeHeaders(drainRequest: false, setOutgoing: false);
+      assert(headersFuture == null);
+    } else {
+      // Imitate having written the headers.
+      _outgoing.headersWritten = true;
+    }
+    // Close connection so the socket is 'free'.
+    close();
+    done.catchError((_) {
+      // Catch any error on done, as they automatically will be
+      // propagated to the websocket.
+    });
+    return future;
+  }
+
+  HttpConnectionInfo get connectionInfo => _httpRequest.connectionInfo;
+
+  Duration get deadline => _deadline;
+
+  void set deadline(Duration d) {
+    if (_deadlineTimer != null) _deadlineTimer.cancel();
+    _deadline = d;
+
+    if (_deadline == null) return;
+    _deadlineTimer = new Timer(_deadline, () {
+      _httpRequest._httpConnection.destroy();
+    });
+  }
+
+  void _writeHeader() {
+    BytesBuilder buffer = new _CopyingBytesBuilder(_OUTGOING_BUFFER_SIZE);
+
+    // Write status line.
+    if (headers.protocolVersion == "1.1") {
+      buffer.add(_Const.HTTP11);
+    } else {
+      buffer.add(_Const.HTTP10);
+    }
+    buffer.addByte(_CharCode.SP);
+    buffer.add(statusCode.toString().codeUnits);
+    buffer.addByte(_CharCode.SP);
+    buffer.add(reasonPhrase.codeUnits);
+    buffer.addByte(_CharCode.CR);
+    buffer.addByte(_CharCode.LF);
+
+    var session = _httpRequest._session;
+    if (session != null && !session._destroyed) {
+      // Mark as not new.
+      session._isNew = false;
+      // Make sure we only send the current session id.
+      bool found = false;
+      for (int i = 0; i < cookies.length; i++) {
+        if (cookies[i].name.toUpperCase() == _DART_SESSION_ID) {
+          cookies[i]
+            ..value = session.id
+            ..httpOnly = true
+            ..path = "/";
+          found = true;
+        }
+      }
+      if (!found) {
+        var cookie = new Cookie(_DART_SESSION_ID, session.id);
+        cookies.add(cookie
+          ..httpOnly = true
+          ..path = "/");
+      }
+    }
+    // Add all the cookies set to the headers.
+    if (_cookies != null) {
+      _cookies.forEach((cookie) {
+        headers.add(HttpHeaders.setCookieHeader, cookie);
+      });
+    }
+
+    headers._finalize();
+
+    // Write headers.
+    headers._build(buffer);
+    buffer.addByte(_CharCode.CR);
+    buffer.addByte(_CharCode.LF);
+    Uint8List headerBytes = buffer.takeBytes();
+    _outgoing.setHeader(headerBytes, headerBytes.length);
+  }
+
+  String _findReasonPhrase(int statusCode) {
+    if (_reasonPhrase != null) {
+      return _reasonPhrase;
+    }
+
+    switch (statusCode) {
+      case HttpStatus.continue_:
+        return "Continue";
+      case HttpStatus.switchingProtocols:
+        return "Switching Protocols";
+      case HttpStatus.ok:
+        return "OK";
+      case HttpStatus.created:
+        return "Created";
+      case HttpStatus.accepted:
+        return "Accepted";
+      case HttpStatus.nonAuthoritativeInformation:
+        return "Non-Authoritative Information";
+      case HttpStatus.noContent:
+        return "No Content";
+      case HttpStatus.resetContent:
+        return "Reset Content";
+      case HttpStatus.partialContent:
+        return "Partial Content";
+      case HttpStatus.multipleChoices:
+        return "Multiple Choices";
+      case HttpStatus.movedPermanently:
+        return "Moved Permanently";
+      case HttpStatus.found:
+        return "Found";
+      case HttpStatus.seeOther:
+        return "See Other";
+      case HttpStatus.notModified:
+        return "Not Modified";
+      case HttpStatus.useProxy:
+        return "Use Proxy";
+      case HttpStatus.temporaryRedirect:
+        return "Temporary Redirect";
+      case HttpStatus.badRequest:
+        return "Bad Request";
+      case HttpStatus.unauthorized:
+        return "Unauthorized";
+      case HttpStatus.paymentRequired:
+        return "Payment Required";
+      case HttpStatus.forbidden:
+        return "Forbidden";
+      case HttpStatus.notFound:
+        return "Not Found";
+      case HttpStatus.methodNotAllowed:
+        return "Method Not Allowed";
+      case HttpStatus.notAcceptable:
+        return "Not Acceptable";
+      case HttpStatus.proxyAuthenticationRequired:
+        return "Proxy Authentication Required";
+      case HttpStatus.requestTimeout:
+        return "Request Time-out";
+      case HttpStatus.conflict:
+        return "Conflict";
+      case HttpStatus.gone:
+        return "Gone";
+      case HttpStatus.lengthRequired:
+        return "Length Required";
+      case HttpStatus.preconditionFailed:
+        return "Precondition Failed";
+      case HttpStatus.requestEntityTooLarge:
+        return "Request Entity Too Large";
+      case HttpStatus.requestUriTooLong:
+        return "Request-URI Too Long";
+      case HttpStatus.unsupportedMediaType:
+        return "Unsupported Media Type";
+      case HttpStatus.requestedRangeNotSatisfiable:
+        return "Requested range not satisfiable";
+      case HttpStatus.expectationFailed:
+        return "Expectation Failed";
+      case HttpStatus.internalServerError:
+        return "Internal Server Error";
+      case HttpStatus.notImplemented:
+        return "Not Implemented";
+      case HttpStatus.badGateway:
+        return "Bad Gateway";
+      case HttpStatus.serviceUnavailable:
+        return "Service Unavailable";
+      case HttpStatus.gatewayTimeout:
+        return "Gateway Time-out";
+      case HttpStatus.httpVersionNotSupported:
+        return "Http Version not supported";
+      default:
+        return "Status $statusCode";
+    }
+  }
+}
+
+class _HttpClientRequest extends _HttpOutboundMessage<HttpClientResponse>
+    implements HttpClientRequest {
+  final String method;
+  final Uri uri;
+  final List<Cookie> cookies = new List<Cookie>();
+
+  // The HttpClient this request belongs to.
+  final _HttpClient _httpClient;
+  final _HttpClientConnection _httpClientConnection;
+
+  final Completer<HttpClientResponse> _responseCompleter =
+      new Completer<HttpClientResponse>();
+
+  final _Proxy _proxy;
+
+  Future<HttpClientResponse> _response;
+
+  // TODO(ajohnsen): Get default value from client?
+  bool _followRedirects = true;
+
+  int _maxRedirects = 5;
+
+  List<RedirectInfo> _responseRedirects = [];
+
+  _HttpClientRequest(_HttpOutgoing outgoing, Uri uri, this.method, this._proxy,
+      this._httpClient, this._httpClientConnection)
+      : uri = uri,
+        super(uri, "1.1", outgoing) {
+    // GET and HEAD have 'content-length: 0' by default.
+    if (method == "GET" || method == "HEAD") {
+      contentLength = 0;
+    } else {
+      headers.chunkedTransferEncoding = true;
+    }
+  }
+
+  Future<HttpClientResponse> get done {
+    if (_response == null) {
+      _response =
+          Future.wait([_responseCompleter.future, super.done], eagerError: true)
+              .then((list) => list[0]);
+    }
+    return _response;
+  }
+
+  Future<HttpClientResponse> close() {
+    super.close();
+    return done;
+  }
+
+  int get maxRedirects => _maxRedirects;
+  void set maxRedirects(int maxRedirects) {
+    if (_outgoing.headersWritten) throw new StateError("Request already sent");
+    _maxRedirects = maxRedirects;
+  }
+
+  bool get followRedirects => _followRedirects;
+  void set followRedirects(bool followRedirects) {
+    if (_outgoing.headersWritten) throw new StateError("Request already sent");
+    _followRedirects = followRedirects;
+  }
+
+  HttpConnectionInfo get connectionInfo => _httpClientConnection.connectionInfo;
+
+  void _onIncoming(_HttpIncoming incoming) {
+    var response = new _HttpClientResponse(incoming, this, _httpClient);
+    Future<HttpClientResponse> future;
+    if (followRedirects && response.isRedirect) {
+      if (response.redirects.length < maxRedirects) {
+        // Redirect and drain response.
+        future = response
+            .drain()
+            .then<HttpClientResponse>((_) => response.redirect());
+      } else {
+        // End with exception, too many redirects.
+        future = response.drain().then<HttpClientResponse>((_) {
+          return new Future<HttpClientResponse>.error(new RedirectException(
+              "Redirect limit exceeded", response.redirects));
+        });
+      }
+    } else if (response._shouldAuthenticateProxy) {
+      future = response._authenticate(true);
+    } else if (response._shouldAuthenticate) {
+      future = response._authenticate(false);
+    } else {
+      future = new Future<HttpClientResponse>.value(response);
+    }
+    future.then((v) => _responseCompleter.complete(v),
+        onError: _responseCompleter.completeError);
+  }
+
+  void _onError(error, StackTrace stackTrace) {
+    _responseCompleter.completeError(error, stackTrace);
+  }
+
+  // Generate the request URI based on the method and proxy.
+  String _requestUri() {
+    // Generate the request URI starting from the path component.
+    String uriStartingFromPath() {
+      String result = uri.path;
+      if (result.isEmpty) result = "/";
+      if (uri.hasQuery) {
+        result = "${result}?${uri.query}";
+      }
+      return result;
+    }
+
+    if (_proxy.isDirect) {
+      return uriStartingFromPath();
+    } else {
+      if (method == "CONNECT") {
+        // For the connect method the request URI is the host:port of
+        // the requested destination of the tunnel (see RFC 2817
+        // section 5.2)
+        return "${uri.host}:${uri.port}";
+      } else {
+        if (_httpClientConnection._proxyTunnel) {
+          return uriStartingFromPath();
+        } else {
+          return uri.removeFragment().toString();
+        }
+      }
+    }
+  }
+
+  void _writeHeader() {
+    BytesBuilder buffer = new _CopyingBytesBuilder(_OUTGOING_BUFFER_SIZE);
+
+    // Write the request method.
+    buffer.add(method.codeUnits);
+    buffer.addByte(_CharCode.SP);
+    // Write the request URI.
+    buffer.add(_requestUri().codeUnits);
+    buffer.addByte(_CharCode.SP);
+    // Write HTTP/1.1.
+    buffer.add(_Const.HTTP11);
+    buffer.addByte(_CharCode.CR);
+    buffer.addByte(_CharCode.LF);
+
+    // Add the cookies to the headers.
+    if (!cookies.isEmpty) {
+      StringBuffer sb = new StringBuffer();
+      for (int i = 0; i < cookies.length; i++) {
+        if (i > 0) sb.write("; ");
+        sb..write(cookies[i].name)..write("=")..write(cookies[i].value);
+      }
+      headers.add(HttpHeaders.cookieHeader, sb.toString());
+    }
+
+    headers._finalize();
+
+    // Write headers.
+    headers._build(buffer);
+    buffer.addByte(_CharCode.CR);
+    buffer.addByte(_CharCode.LF);
+    Uint8List headerBytes = buffer.takeBytes();
+    _outgoing.setHeader(headerBytes, headerBytes.length);
+  }
+}
+
+// Used by _HttpOutgoing as a target of a chunked converter for gzip
+// compression.
+class _HttpGZipSink extends ByteConversionSink {
+  final _BytesConsumer _consume;
+  _HttpGZipSink(this._consume);
+
+  void add(List<int> chunk) {
+    _consume(chunk);
+  }
+
+  void addSlice(List<int> chunk, int start, int end, bool isLast) {
+    if (chunk is Uint8List) {
+      _consume(new Uint8List.view(chunk.buffer, start, end - start));
+    } else {
+      _consume(chunk.sublist(start, end - start));
+    }
+  }
+
+  void close() {}
+}
+
+// The _HttpOutgoing handles all of the following:
+//  - Buffering
+//  - GZip compression
+//  - Content-Length validation.
+//  - Errors.
+//
+// Most notable is the GZip compression, that uses a double-buffering system,
+// one before gzip (_gzipBuffer) and one after (_buffer).
+class _HttpOutgoing implements StreamConsumer<List<int>> {
+  static const List<int> _footerAndChunk0Length = const [
+    _CharCode.CR,
+    _CharCode.LF,
+    0x30,
+    _CharCode.CR,
+    _CharCode.LF,
+    _CharCode.CR,
+    _CharCode.LF
+  ];
+
+  static const List<int> _chunk0Length = const [
+    0x30,
+    _CharCode.CR,
+    _CharCode.LF,
+    _CharCode.CR,
+    _CharCode.LF
+  ];
+
+  final Completer<Socket> _doneCompleter = new Completer<Socket>();
+  final Socket socket;
+
+  bool ignoreBody = false;
+  bool headersWritten = false;
+
+  Uint8List _buffer;
+  int _length = 0;
+
+  Future _closeFuture;
+
+  bool chunked = false;
+  int _pendingChunkedFooter = 0;
+
+  int contentLength;
+  int _bytesWritten = 0;
+
+  bool _gzip = false;
+  ByteConversionSink _gzipSink;
+  // _gzipAdd is set iff the sink is being added to. It's used to specify where
+  // gzipped data should be taken (sometimes a controller, sometimes a socket).
+  _BytesConsumer _gzipAdd;
+  Uint8List _gzipBuffer;
+  int _gzipBufferLength = 0;
+
+  bool _socketError = false;
+
+  _HttpOutboundMessage outbound;
+
+  _HttpOutgoing(this.socket);
+
+  // Returns either a future or 'null', if it was able to write headers
+  // immediately.
+  Future writeHeaders({bool drainRequest: true, bool setOutgoing: true}) {
+    if (headersWritten) return null;
+    headersWritten = true;
+    Future drainFuture;
+    bool gzip = false;
+    if (outbound is _HttpResponse) {
+      // Server side.
+      _HttpResponse response = outbound;
+      if (response._httpRequest._httpServer.autoCompress &&
+          outbound.bufferOutput &&
+          outbound.headers.chunkedTransferEncoding) {
+        List acceptEncodings =
+            response._httpRequest.headers[HttpHeaders.acceptEncodingHeader];
+        List contentEncoding =
+            outbound.headers[HttpHeaders.contentEncodingHeader];
+        if (acceptEncodings != null &&
+            acceptEncodings
+                .expand((list) => list.split(","))
+                .any((encoding) => encoding.trim().toLowerCase() == "gzip") &&
+            contentEncoding == null) {
+          outbound.headers.set(HttpHeaders.contentEncodingHeader, "gzip");
+          gzip = true;
+        }
+      }
+      if (drainRequest && !response._httpRequest._incoming.hasSubscriber) {
+        drainFuture = response._httpRequest.drain().catchError((_) {});
+      }
+    } else {
+      drainRequest = false;
+    }
+    if (!ignoreBody) {
+      if (setOutgoing) {
+        int contentLength = outbound.headers.contentLength;
+        if (outbound.headers.chunkedTransferEncoding) {
+          chunked = true;
+          if (gzip) this.gzip = true;
+        } else if (contentLength >= 0) {
+          this.contentLength = contentLength;
+        }
+      }
+      if (drainFuture != null) {
+        return drainFuture.then((_) => outbound._writeHeader());
+      }
+    }
+    outbound._writeHeader();
+    return null;
+  }
+
+  Future addStream(Stream<List<int>> stream) {
+    if (_socketError) {
+      stream.listen(null).cancel();
+      return new Future.value(outbound);
+    }
+    if (ignoreBody) {
+      stream.drain().catchError((_) {});
+      var future = writeHeaders();
+      if (future != null) {
+        return future.then((_) => close());
+      }
+      return close();
+    }
+    StreamSubscription<List<int>> sub;
+    // Use new stream so we are able to pause (see below listen). The
+    // alternative is to use stream.extand, but that won't give us a way of
+    // pausing.
+    var controller = new StreamController<List<int>>(
+        onPause: () => sub.pause(), onResume: () => sub.resume(), sync: true);
+
+    void onData(List<int> data) {
+      if (_socketError) return;
+      if (data.length == 0) return;
+      if (chunked) {
+        if (_gzip) {
+          _gzipAdd = controller.add;
+          _addGZipChunk(data, _gzipSink.add);
+          _gzipAdd = null;
+          return;
+        }
+        _addChunk(_chunkHeader(data.length), controller.add);
+        _pendingChunkedFooter = 2;
+      } else {
+        if (contentLength != null) {
+          _bytesWritten += data.length;
+          if (_bytesWritten > contentLength) {
+            controller.addError(new HttpException(
+                "Content size exceeds specified contentLength. "
+                "$_bytesWritten bytes written while expected "
+                "$contentLength. "
+                "[${new String.fromCharCodes(data)}]"));
+            return;
+          }
+        }
+      }
+      _addChunk(data, controller.add);
+    }
+
+    sub = stream.listen(onData,
+        onError: controller.addError,
+        onDone: controller.close,
+        cancelOnError: true);
+    // Write headers now that we are listening to the stream.
+    if (!headersWritten) {
+      var future = writeHeaders();
+      if (future != null) {
+        // While incoming is being drained, the pauseFuture is non-null. Pause
+        // output until it's drained.
+        sub.pause(future);
+      }
+    }
+    return socket.addStream(controller.stream).then((_) {
+      return outbound;
+    }, onError: (error, stackTrace) {
+      // Be sure to close it in case of an error.
+      if (_gzip) _gzipSink.close();
+      _socketError = true;
+      _doneCompleter.completeError(error, stackTrace);
+      if (_ignoreError(error)) {
+        return outbound;
+      } else {
+        throw error;
+      }
+    });
+  }
+
+  Future close() {
+    // If we are already closed, return that future.
+    if (_closeFuture != null) return _closeFuture;
+    // If we earlier saw an error, return immediate. The notification to
+    // _Http*Connection is already done.
+    if (_socketError) return new Future.value(outbound);
+    if (outbound._isConnectionClosed) return new Future.value(outbound);
+    if (!headersWritten && !ignoreBody) {
+      if (outbound.headers.contentLength == -1) {
+        // If no body was written, ignoreBody is false (it's not a HEAD
+        // request) and the content-length is unspecified, set contentLength to
+        // 0.
+        outbound.headers.chunkedTransferEncoding = false;
+        outbound.headers.contentLength = 0;
+      } else if (outbound.headers.contentLength > 0) {
+        var error = new HttpException(
+            "No content even though contentLength was specified to be "
+            "greater than 0: ${outbound.headers.contentLength}.",
+            uri: outbound._uri);
+        _doneCompleter.completeError(error);
+        return _closeFuture = new Future.error(error);
+      }
+    }
+    // If contentLength was specified, validate it.
+    if (contentLength != null) {
+      if (_bytesWritten < contentLength) {
+        var error = new HttpException(
+            "Content size below specified contentLength. "
+            " $_bytesWritten bytes written but expected "
+            "$contentLength.",
+            uri: outbound._uri);
+        _doneCompleter.completeError(error);
+        return _closeFuture = new Future.error(error);
+      }
+    }
+
+    Future finalize() {
+      // In case of chunked encoding (and gzip), handle remaining gzip data and
+      // append the 'footer' for chunked encoding.
+      if (chunked) {
+        if (_gzip) {
+          _gzipAdd = socket.add;
+          if (_gzipBufferLength > 0) {
+            _gzipSink.add(
+                new Uint8List.view(_gzipBuffer.buffer, 0, _gzipBufferLength));
+          }
+          _gzipBuffer = null;
+          _gzipSink.close();
+          _gzipAdd = null;
+        }
+        _addChunk(_chunkHeader(0), socket.add);
+      }
+      // Add any remaining data in the buffer.
+      if (_length > 0) {
+        socket.add(new Uint8List.view(_buffer.buffer, 0, _length));
+      }
+      // Clear references, for better GC.
+      _buffer = null;
+      // And finally flush it. As we support keep-alive, never close it from
+      // here. Once the socket is flushed, we'll be able to reuse it (signaled
+      // by the 'done' future).
+      return socket.flush().then((_) {
+        _doneCompleter.complete(socket);
+        return outbound;
+      }, onError: (error, stackTrace) {
+        _doneCompleter.completeError(error, stackTrace);
+        if (_ignoreError(error)) {
+          return outbound;
+        } else {
+          throw error;
+        }
+      });
+    }
+
+    var future = writeHeaders();
+    if (future != null) {
+      return _closeFuture = future.whenComplete(finalize);
+    }
+    return _closeFuture = finalize();
+  }
+
+  Future<Socket> get done => _doneCompleter.future;
+
+  void setHeader(List<int> data, int length) {
+    assert(_length == 0);
+    _buffer = data;
+    _length = length;
+  }
+
+  void set gzip(bool value) {
+    _gzip = value;
+    if (_gzip) {
+      _gzipBuffer = new Uint8List(_OUTGOING_BUFFER_SIZE);
+      assert(_gzipSink == null);
+      _gzipSink = new ZLibEncoder(gzip: true)
+          .startChunkedConversion(new _HttpGZipSink((data) {
+        // We are closing down prematurely, due to an error. Discard.
+        if (_gzipAdd == null) return;
+        _addChunk(_chunkHeader(data.length), _gzipAdd);
+        _pendingChunkedFooter = 2;
+        _addChunk(data, _gzipAdd);
+      }));
+    }
+  }
+
+  bool _ignoreError(error) =>
+      (error is SocketException || error is TlsException) &&
+      outbound is HttpResponse;
+
+  void _addGZipChunk(List<int> chunk, void add(List<int> data)) {
+    if (!outbound.bufferOutput) {
+      add(chunk);
+      return;
+    }
+    if (chunk.length > _gzipBuffer.length - _gzipBufferLength) {
+      add(new Uint8List.view(_gzipBuffer.buffer, 0, _gzipBufferLength));
+      _gzipBuffer = new Uint8List(_OUTGOING_BUFFER_SIZE);
+      _gzipBufferLength = 0;
+    }
+    if (chunk.length > _OUTGOING_BUFFER_SIZE) {
+      add(chunk);
+    } else {
+      _gzipBuffer.setRange(
+          _gzipBufferLength, _gzipBufferLength + chunk.length, chunk);
+      _gzipBufferLength += chunk.length;
+    }
+  }
+
+  void _addChunk(List<int> chunk, void add(List<int> data)) {
+    if (!outbound.bufferOutput) {
+      if (_buffer != null) {
+        // If _buffer is not null, we have not written the header yet. Write
+        // it now.
+        add(new Uint8List.view(_buffer.buffer, 0, _length));
+        _buffer = null;
+        _length = 0;
+      }
+      add(chunk);
+      return;
+    }
+    if (chunk.length > _buffer.length - _length) {
+      add(new Uint8List.view(_buffer.buffer, 0, _length));
+      _buffer = new Uint8List(_OUTGOING_BUFFER_SIZE);
+      _length = 0;
+    }
+    if (chunk.length > _OUTGOING_BUFFER_SIZE) {
+      add(chunk);
+    } else {
+      _buffer.setRange(_length, _length + chunk.length, chunk);
+      _length += chunk.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
+    ];
+    if (length == 0) {
+      if (_pendingChunkedFooter == 2) return _footerAndChunk0Length;
+      return _chunk0Length;
+    }
+    int size = _pendingChunkedFooter;
+    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 (_pendingChunkedFooter == 2) {
+      footerAndHeader[0] = _CharCode.CR;
+      footerAndHeader[1] = _CharCode.LF;
+    }
+    int index = size;
+    while (index > _pendingChunkedFooter) {
+      footerAndHeader[--index] = hexDigits[length & 15];
+      length = length >> 4;
+    }
+    footerAndHeader[size + 0] = _CharCode.CR;
+    footerAndHeader[size + 1] = _CharCode.LF;
+    return footerAndHeader;
+  }
+}
+
+class _HttpClientConnection {
+  final String key;
+  final Socket _socket;
+  final bool _proxyTunnel;
+  final SecurityContext _context;
+  final _HttpParser _httpParser;
+  StreamSubscription _subscription;
+  final _HttpClient _httpClient;
+  bool _dispose = false;
+  Timer _idleTimer;
+  bool closed = false;
+  Uri _currentUri;
+
+  Completer<_HttpIncoming> _nextResponseCompleter;
+  Future<Socket> _streamFuture;
+
+  _HttpClientConnection(this.key, this._socket, this._httpClient,
+      [this._proxyTunnel = false, this._context])
+      : _httpParser = new _HttpParser.responseParser() {
+    _httpParser.listenToStream(_socket);
+
+    // Set up handlers on the parser here, so we are sure to get 'onDone' from
+    // the parser.
+    _subscription = _httpParser.listen((incoming) {
+      // Only handle one incoming response at the time. Keep the
+      // stream paused until the response have been processed.
+      _subscription.pause();
+      // We assume the response is not here, until we have send the request.
+      if (_nextResponseCompleter == null) {
+        throw new HttpException(
+            "Unexpected response (unsolicited response without request).",
+            uri: _currentUri);
+      }
+
+      // Check for status code '100 Continue'. In that case just
+      // consume that response as the final response will follow
+      // it. There is currently no API for the client to wait for
+      // the '100 Continue' response.
+      if (incoming.statusCode == 100) {
+        incoming.drain().then((_) {
+          _subscription.resume();
+        }).catchError((error, [StackTrace stackTrace]) {
+          _nextResponseCompleter.completeError(
+              new HttpException(error.message, uri: _currentUri), stackTrace);
+          _nextResponseCompleter = null;
+        });
+      } else {
+        _nextResponseCompleter.complete(incoming);
+        _nextResponseCompleter = null;
+      }
+    }, onError: (error, [StackTrace stackTrace]) {
+      if (_nextResponseCompleter != null) {
+        _nextResponseCompleter.completeError(
+            new HttpException(error.message, uri: _currentUri), stackTrace);
+        _nextResponseCompleter = null;
+      }
+    }, onDone: () {
+      if (_nextResponseCompleter != null) {
+        _nextResponseCompleter.completeError(new HttpException(
+            "Connection closed before response was received",
+            uri: _currentUri));
+        _nextResponseCompleter = null;
+      }
+      close();
+    });
+  }
+
+  _HttpClientRequest send(Uri uri, int port, String method, _Proxy proxy) {
+    if (closed) {
+      throw new HttpException("Socket closed before request was sent",
+          uri: uri);
+    }
+    _currentUri = uri;
+    // Start with pausing the parser.
+    _subscription.pause();
+    _ProxyCredentials proxyCreds; // Credentials used to authorize proxy.
+    _SiteCredentials creds; // Credentials used to authorize this request.
+    var outgoing = new _HttpOutgoing(_socket);
+    // Create new request object, wrapping the outgoing connection.
+    var request =
+        new _HttpClientRequest(outgoing, uri, method, proxy, _httpClient, this);
+    // For the Host header an IPv6 address must be enclosed in []'s.
+    var host = uri.host;
+    if (host.contains(':')) host = "[$host]";
+    request.headers
+      ..host = host
+      ..port = port
+      .._add(HttpHeaders.acceptEncodingHeader, "gzip");
+    if (_httpClient.userAgent != null) {
+      request.headers._add('user-agent', _httpClient.userAgent);
+    }
+    if (proxy.isAuthenticated) {
+      // If the proxy configuration contains user information use that
+      // for proxy basic authorization.
+      String auth = _CryptoUtils.bytesToBase64(
+          utf8.encode("${proxy.username}:${proxy.password}"));
+      request.headers.set(HttpHeaders.proxyAuthorizationHeader, "Basic $auth");
+    } else if (!proxy.isDirect && _httpClient._proxyCredentials.length > 0) {
+      proxyCreds = _httpClient._findProxyCredentials(proxy);
+      if (proxyCreds != null) {
+        proxyCreds.authorize(request);
+      }
+    }
+    if (uri.userInfo != null && !uri.userInfo.isEmpty) {
+      // If the URL contains user information use that for basic
+      // authorization.
+      String auth = _CryptoUtils.bytesToBase64(utf8.encode(uri.userInfo));
+      request.headers.set(HttpHeaders.authorizationHeader, "Basic $auth");
+    } else {
+      // Look for credentials.
+      creds = _httpClient._findCredentials(uri);
+      if (creds != null) {
+        creds.authorize(request);
+      }
+    }
+    // Start sending the request (lazy, delayed until the user provides
+    // data).
+    _httpParser.isHead = method == "HEAD";
+    _streamFuture = outgoing.done.then<Socket>((Socket s) {
+      // Request sent, set up response completer.
+      _nextResponseCompleter = new Completer<_HttpIncoming>();
+
+      // Listen for response.
+      _nextResponseCompleter.future.then((incoming) {
+        _currentUri = null;
+        incoming.dataDone.then((closing) {
+          if (incoming.upgraded) {
+            _httpClient._connectionClosed(this);
+            startTimer();
+            return;
+          }
+          if (closed) return;
+          if (!closing &&
+              !_dispose &&
+              incoming.headers.persistentConnection &&
+              request.persistentConnection) {
+            // Return connection, now we are done.
+            _httpClient._returnConnection(this);
+            _subscription.resume();
+          } else {
+            destroy();
+          }
+        });
+        // For digest authentication if proxy check if the proxy
+        // requests the client to start using a new nonce for proxy
+        // authentication.
+        if (proxyCreds != null &&
+            proxyCreds.scheme == _AuthenticationScheme.DIGEST) {
+          var authInfo = incoming.headers["proxy-authentication-info"];
+          if (authInfo != null && authInfo.length == 1) {
+            var header =
+                _HeaderValue.parse(authInfo[0], parameterSeparator: ',');
+            var nextnonce = header.parameters["nextnonce"];
+            if (nextnonce != null) proxyCreds.nonce = nextnonce;
+          }
+        }
+        // For digest authentication check if the server requests the
+        // client to start using a new nonce.
+        if (creds != null && creds.scheme == _AuthenticationScheme.DIGEST) {
+          var authInfo = incoming.headers["authentication-info"];
+          if (authInfo != null && authInfo.length == 1) {
+            var header =
+                _HeaderValue.parse(authInfo[0], parameterSeparator: ',');
+            var nextnonce = header.parameters["nextnonce"];
+            if (nextnonce != null) creds.nonce = nextnonce;
+          }
+        }
+        request._onIncoming(incoming);
+      })
+          // If we see a state error, we failed to get the 'first'
+          // element.
+          .catchError((error) {
+        throw new HttpException("Connection closed before data was received",
+            uri: uri);
+      }, test: (error) => error is StateError).catchError((error, stackTrace) {
+        // We are done with the socket.
+        destroy();
+        request._onError(error, stackTrace);
+      });
+
+      // Resume the parser now we have a handler.
+      _subscription.resume();
+      return s;
+    }, onError: (e) {
+      destroy();
+    });
+    return request;
+  }
+
+  Future<Socket> detachSocket() {
+    return _streamFuture.then(
+        (_) => new _DetachedSocket(_socket, _httpParser.detachIncoming()));
+  }
+
+  void destroy() {
+    closed = true;
+    _httpClient._connectionClosed(this);
+    _socket.destroy();
+  }
+
+  void close() {
+    closed = true;
+    _httpClient._connectionClosed(this);
+    _streamFuture
+        .timeout(_httpClient.idleTimeout)
+        .then((_) => _socket.destroy());
+  }
+
+  Future<_HttpClientConnection> createProxyTunnel(String host, int port,
+      _Proxy proxy, bool callback(X509Certificate certificate)) {
+    _HttpClientRequest request =
+        send(new Uri(host: host, port: port), port, "CONNECT", proxy);
+    if (proxy.isAuthenticated) {
+      // If the proxy configuration contains user information use that
+      // for proxy basic authorization.
+      String auth = _CryptoUtils.bytesToBase64(
+          utf8.encode("${proxy.username}:${proxy.password}"));
+      request.headers.set(HttpHeaders.proxyAuthorizationHeader, "Basic $auth");
+    }
+    return request.close().then((response) {
+      if (response.statusCode != HttpStatus.ok) {
+        throw new HttpException(
+            "Proxy failed to establish tunnel "
+            "(${response.statusCode} ${response.reasonPhrase})",
+            uri: request.uri);
+      }
+      var socket = (response as _HttpClientResponse)
+          ._httpRequest
+          ._httpClientConnection
+          ._socket;
+      return SecureSocket.secure(socket,
+          host: host, context: _context, onBadCertificate: callback);
+    }).then((secureSocket) {
+      String key = _HttpClientConnection.makeKey(true, host, port);
+      return new _HttpClientConnection(
+          key, secureSocket, request._httpClient, true);
+    });
+  }
+
+  HttpConnectionInfo get connectionInfo => _HttpConnectionInfo.create(_socket);
+
+  static makeKey(bool isSecure, String host, int port) {
+    return isSecure ? "ssh:$host:$port" : "$host:$port";
+  }
+
+  void stopTimer() {
+    if (_idleTimer != null) {
+      _idleTimer.cancel();
+      _idleTimer = null;
+    }
+  }
+
+  void startTimer() {
+    assert(_idleTimer == null);
+    _idleTimer = new Timer(_httpClient.idleTimeout, () {
+      _idleTimer = null;
+      close();
+    });
+  }
+}
+
+class _ConnectionInfo {
+  final _HttpClientConnection connection;
+  final _Proxy proxy;
+
+  _ConnectionInfo(this.connection, this.proxy);
+}
+
+class _ConnectionTarget {
+  // Unique key for this connection target.
+  final String key;
+  final String host;
+  final int port;
+  final bool isSecure;
+  final SecurityContext context;
+  final Set<_HttpClientConnection> _idle = new HashSet();
+  final Set<_HttpClientConnection> _active = new HashSet();
+  final Set<ConnectionTask> _socketTasks = new HashSet();
+  final Queue _pending = new ListQueue();
+  int _connecting = 0;
+
+  _ConnectionTarget(
+      this.key, this.host, this.port, this.isSecure, this.context);
+
+  bool get isEmpty => _idle.isEmpty && _active.isEmpty && _connecting == 0;
+
+  bool get hasIdle => _idle.isNotEmpty;
+
+  bool get hasActive => _active.isNotEmpty || _connecting > 0;
+
+  _HttpClientConnection takeIdle() {
+    assert(hasIdle);
+    _HttpClientConnection connection = _idle.first;
+    _idle.remove(connection);
+    connection.stopTimer();
+    _active.add(connection);
+    return connection;
+  }
+
+  _checkPending() {
+    if (_pending.isNotEmpty) {
+      _pending.removeFirst()();
+    }
+  }
+
+  void addNewActive(_HttpClientConnection connection) {
+    _active.add(connection);
+  }
+
+  void returnConnection(_HttpClientConnection connection) {
+    assert(_active.contains(connection));
+    _active.remove(connection);
+    _idle.add(connection);
+    connection.startTimer();
+    _checkPending();
+  }
+
+  void connectionClosed(_HttpClientConnection connection) {
+    assert(!_active.contains(connection) || !_idle.contains(connection));
+    _active.remove(connection);
+    _idle.remove(connection);
+    _checkPending();
+  }
+
+  void close(bool force) {
+    // Always cancel pending socket connections.
+    for (var t in _socketTasks.toList()) {
+      // Make sure the socket is destroyed if the ConnectionTask is cancelled.
+      t.socket.then((s) {
+        s.destroy();
+      }, onError: (e) {});
+      t.cancel();
+    }
+    if (force) {
+      for (var c in _idle.toList()) {
+        c.destroy();
+      }
+      for (var c in _active.toList()) {
+        c.destroy();
+      }
+    } else {
+      for (var c in _idle.toList()) {
+        c.close();
+      }
+    }
+  }
+
+  Future<_ConnectionInfo> connect(
+      String uriHost, int uriPort, _Proxy proxy, _HttpClient client) {
+    if (hasIdle) {
+      var connection = takeIdle();
+      client._connectionsChanged();
+      return new Future.value(new _ConnectionInfo(connection, proxy));
+    }
+    if (client.maxConnectionsPerHost != null &&
+        _active.length + _connecting >= client.maxConnectionsPerHost) {
+      var completer = new Completer<_ConnectionInfo>();
+      _pending.add(() {
+        completer.complete(connect(uriHost, uriPort, proxy, client));
+      });
+      return completer.future;
+    }
+    var currentBadCertificateCallback = client._badCertificateCallback;
+
+    bool callback(X509Certificate certificate) {
+      if (currentBadCertificateCallback == null) return false;
+      return currentBadCertificateCallback(certificate, uriHost, uriPort);
+    }
+
+    Future<ConnectionTask> connectionTask = (isSecure && proxy.isDirect
+        ? SecureSocket.startConnect(host, port,
+            context: context, onBadCertificate: callback)
+        : Socket.startConnect(host, port));
+    _connecting++;
+    return connectionTask.then((ConnectionTask task) {
+      _socketTasks.add(task);
+      Future socketFuture = task.socket;
+      final Duration connectionTimeout = client.connectionTimeout;
+      if (connectionTimeout != null) {
+        socketFuture = socketFuture.timeout(connectionTimeout, onTimeout: () {
+          _socketTasks.remove(task);
+          task.cancel();
+          return null;
+        });
+      }
+      return socketFuture.then((socket) {
+        // When there is a timeout, there is a race in which the connectionTask
+        // Future won't be completed with an error before the socketFuture here
+        // is completed with 'null' by the onTimeout callback above. In this
+        // case, propagate a SocketException as specified by the
+        // HttpClient.connectionTimeout docs.
+        if (socket == null) {
+          assert(connectionTimeout != null);
+          throw new SocketException(
+              "HTTP connection timed out after ${connectionTimeout}, "
+              "host: ${host}, port: ${port}");
+        }
+        _connecting--;
+        socket.setOption(SocketOption.tcpNoDelay, true);
+        var connection =
+            new _HttpClientConnection(key, socket, client, false, context);
+        if (isSecure && !proxy.isDirect) {
+          connection._dispose = true;
+          return connection
+              .createProxyTunnel(uriHost, uriPort, proxy, callback)
+              .then((tunnel) {
+            client
+                ._getConnectionTarget(uriHost, uriPort, true)
+                .addNewActive(tunnel);
+            _socketTasks.remove(task);
+            return new _ConnectionInfo(tunnel, proxy);
+          });
+        } else {
+          addNewActive(connection);
+          _socketTasks.remove(task);
+          return new _ConnectionInfo(connection, proxy);
+        }
+      }, onError: (error) {
+        _connecting--;
+        _socketTasks.remove(task);
+        _checkPending();
+        throw error;
+      });
+    });
+  }
+}
+
+typedef bool BadCertificateCallback(X509Certificate cr, String host, int port);
+
+class _HttpClient implements HttpClient {
+  bool _closing = false;
+  bool _closingForcefully = false;
+  final Map<String, _ConnectionTarget> _connectionTargets =
+      new HashMap<String, _ConnectionTarget>();
+  final List<_Credentials> _credentials = [];
+  final List<_ProxyCredentials> _proxyCredentials = [];
+  final SecurityContext _context;
+  Function _authenticate;
+  Function _authenticateProxy;
+  Function _findProxy = HttpClient.findProxyFromEnvironment;
+  Duration _idleTimeout = const Duration(seconds: 15);
+  BadCertificateCallback _badCertificateCallback;
+
+  Duration get idleTimeout => _idleTimeout;
+
+  Duration connectionTimeout;
+
+  int maxConnectionsPerHost;
+
+  bool autoUncompress = true;
+
+  String userAgent = _getHttpVersion();
+
+  _HttpClient(this._context);
+
+  void set idleTimeout(Duration timeout) {
+    _idleTimeout = timeout;
+    for (var c in _connectionTargets.values) {
+      for (var idle in c._idle) {
+        // Reset timer. This is fine, as it's not happening often.
+        idle.stopTimer();
+        idle.startTimer();
+      }
+    }
+  }
+
+  set badCertificateCallback(
+      bool callback(X509Certificate cert, String host, int port)) {
+    _badCertificateCallback = callback;
+  }
+
+  Future<HttpClientRequest> open(
+      String method, String host, int port, String path) {
+    const int hashMark = 0x23;
+    const int questionMark = 0x3f;
+    int fragmentStart = path.length;
+    int queryStart = path.length;
+    for (int i = path.length - 1; i >= 0; i--) {
+      var char = path.codeUnitAt(i);
+      if (char == hashMark) {
+        fragmentStart = i;
+        queryStart = i;
+      } else if (char == questionMark) {
+        queryStart = i;
+      }
+    }
+    String query = null;
+    if (queryStart < fragmentStart) {
+      query = path.substring(queryStart + 1, fragmentStart);
+      path = path.substring(0, queryStart);
+    }
+    Uri uri = new Uri(
+        scheme: "http", host: host, port: port, path: path, query: query);
+    return _openUrl(method, uri);
+  }
+
+  Future<HttpClientRequest> openUrl(String method, Uri url) =>
+      _openUrl(method, url);
+
+  Future<HttpClientRequest> get(String host, int port, String path) =>
+      open("get", host, port, path);
+
+  Future<HttpClientRequest> getUrl(Uri url) => _openUrl("get", url);
+
+  Future<HttpClientRequest> post(String host, int port, String path) =>
+      open("post", host, port, path);
+
+  Future<HttpClientRequest> postUrl(Uri url) => _openUrl("post", url);
+
+  Future<HttpClientRequest> put(String host, int port, String path) =>
+      open("put", host, port, path);
+
+  Future<HttpClientRequest> putUrl(Uri url) => _openUrl("put", url);
+
+  Future<HttpClientRequest> delete(String host, int port, String path) =>
+      open("delete", host, port, path);
+
+  Future<HttpClientRequest> deleteUrl(Uri url) => _openUrl("delete", url);
+
+  Future<HttpClientRequest> head(String host, int port, String path) =>
+      open("head", host, port, path);
+
+  Future<HttpClientRequest> headUrl(Uri url) => _openUrl("head", url);
+
+  Future<HttpClientRequest> patch(String host, int port, String path) =>
+      open("patch", host, port, path);
+
+  Future<HttpClientRequest> patchUrl(Uri url) => _openUrl("patch", url);
+
+  void close({bool force: false}) {
+    _closing = true;
+    _closingForcefully = force;
+    _closeConnections(_closingForcefully);
+    assert(!_connectionTargets.values.any((s) => s.hasIdle));
+    assert(
+        !force || !_connectionTargets.values.any((s) => s._active.isNotEmpty));
+  }
+
+  set authenticate(Future<bool> f(Uri url, String scheme, String realm)) {
+    _authenticate = f;
+  }
+
+  void addCredentials(Uri url, String realm, HttpClientCredentials cr) {
+    _credentials.add(new _SiteCredentials(url, realm, cr));
+  }
+
+  set authenticateProxy(
+      Future<bool> f(String host, int port, String scheme, String realm)) {
+    _authenticateProxy = f;
+  }
+
+  void addProxyCredentials(
+      String host, int port, String realm, HttpClientCredentials cr) {
+    _proxyCredentials.add(new _ProxyCredentials(host, port, realm, cr));
+  }
+
+  set findProxy(String f(Uri uri)) => _findProxy = f;
+
+  Future<_HttpClientRequest> _openUrl(String method, Uri uri) {
+    if (_closing) {
+      throw new StateError("Client is closed");
+    }
+
+    // Ignore any fragments on the request URI.
+    uri = uri.removeFragment();
+
+    if (method == null) {
+      throw new ArgumentError(method);
+    }
+    if (method != "CONNECT") {
+      if (uri.host.isEmpty) {
+        throw new ArgumentError("No host specified in URI $uri");
+      } else if (uri.scheme != "http" && uri.scheme != "https") {
+        throw new ArgumentError(
+            "Unsupported scheme '${uri.scheme}' in URI $uri");
+      }
+    }
+
+    bool isSecure = (uri.scheme == "https");
+    int port = uri.port;
+    if (port == 0) {
+      port =
+          isSecure ? HttpClient.defaultHttpsPort : HttpClient.defaultHttpPort;
+    }
+    // Check to see if a proxy server should be used for this connection.
+    var proxyConf = const _ProxyConfiguration.direct();
+    if (_findProxy != null) {
+      // TODO(sgjesse): Keep a map of these as normally only a few
+      // configuration strings will be used.
+      try {
+        proxyConf = new _ProxyConfiguration(_findProxy(uri));
+      } catch (error, stackTrace) {
+        return new Future.error(error, stackTrace);
+      }
+    }
+    return _getConnection(uri.host, port, proxyConf, isSecure)
+        .then((_ConnectionInfo info) {
+      _HttpClientRequest send(_ConnectionInfo info) {
+        return info.connection
+            .send(uri, port, method.toUpperCase(), info.proxy);
+      }
+
+      // If the connection was closed before the request was sent, create
+      // and use another connection.
+      if (info.connection.closed) {
+        return _getConnection(uri.host, port, proxyConf, isSecure).then(send);
+      }
+      return send(info);
+    });
+  }
+
+  Future<_HttpClientRequest> _openUrlFromRequest(
+      String method, Uri uri, _HttpClientRequest previous) {
+    // If the new URI is relative (to either '/' or some sub-path),
+    // construct a full URI from the previous one.
+    Uri resolved = previous.uri.resolveUri(uri);
+    return _openUrl(method, resolved).then((_HttpClientRequest request) {
+      request
+        // Only follow redirects if initial request did.
+        ..followRedirects = previous.followRedirects
+        // Allow same number of redirects.
+        ..maxRedirects = previous.maxRedirects;
+      // Copy headers.
+      for (var header in previous.headers._headers.keys) {
+        if (request.headers[header] == null) {
+          request.headers.set(header, previous.headers[header]);
+        }
+      }
+      return request
+        ..headers.chunkedTransferEncoding = false
+        ..contentLength = 0;
+    });
+  }
+
+  // Return a live connection to the idle pool.
+  void _returnConnection(_HttpClientConnection connection) {
+    _connectionTargets[connection.key].returnConnection(connection);
+    _connectionsChanged();
+  }
+
+  // Remove a closed connection from the active set.
+  void _connectionClosed(_HttpClientConnection connection) {
+    connection.stopTimer();
+    var connectionTarget = _connectionTargets[connection.key];
+    if (connectionTarget != null) {
+      connectionTarget.connectionClosed(connection);
+      if (connectionTarget.isEmpty) {
+        _connectionTargets.remove(connection.key);
+      }
+      _connectionsChanged();
+    }
+  }
+
+  void _connectionsChanged() {
+    if (_closing) {
+      _closeConnections(_closingForcefully);
+    }
+  }
+
+  void _closeConnections(bool force) {
+    for (var connectionTarget in _connectionTargets.values.toList()) {
+      connectionTarget.close(force);
+    }
+  }
+
+  _ConnectionTarget _getConnectionTarget(String host, int port, bool isSecure) {
+    String key = _HttpClientConnection.makeKey(isSecure, host, port);
+    return _connectionTargets.putIfAbsent(key, () {
+      return new _ConnectionTarget(key, host, port, isSecure, _context);
+    });
+  }
+
+  // Get a new _HttpClientConnection, from the matching _ConnectionTarget.
+  Future<_ConnectionInfo> _getConnection(String uriHost, int uriPort,
+      _ProxyConfiguration proxyConf, bool isSecure) {
+    Iterator<_Proxy> proxies = proxyConf.proxies.iterator;
+
+    Future<_ConnectionInfo> connect(error) {
+      if (!proxies.moveNext()) return new Future.error(error);
+      _Proxy proxy = proxies.current;
+      String host = proxy.isDirect ? uriHost : proxy.host;
+      int port = proxy.isDirect ? uriPort : proxy.port;
+      return _getConnectionTarget(host, port, isSecure)
+          .connect(uriHost, uriPort, proxy, this)
+          // On error, continue with next proxy.
+          .catchError(connect);
+    }
+
+    return connect(new HttpException("No proxies given"));
+  }
+
+  _SiteCredentials _findCredentials(Uri url, [_AuthenticationScheme scheme]) {
+    // Look for credentials.
+    _SiteCredentials cr =
+        _credentials.fold(null, (_SiteCredentials prev, value) {
+      var siteCredentials = value as _SiteCredentials;
+      if (siteCredentials.applies(url, scheme)) {
+        if (prev == null) return value;
+        return siteCredentials.uri.path.length > prev.uri.path.length
+            ? siteCredentials
+            : prev;
+      } else {
+        return prev;
+      }
+    });
+    return cr;
+  }
+
+  _ProxyCredentials _findProxyCredentials(_Proxy proxy,
+      [_AuthenticationScheme scheme]) {
+    // Look for credentials.
+    var it = _proxyCredentials.iterator;
+    while (it.moveNext()) {
+      if (it.current.applies(proxy, scheme)) {
+        return it.current;
+      }
+    }
+    return null;
+  }
+
+  void _removeCredentials(_Credentials cr) {
+    int index = _credentials.indexOf(cr);
+    if (index != -1) {
+      _credentials.removeAt(index);
+    }
+  }
+
+  void _removeProxyCredentials(_Credentials cr) {
+    int index = _proxyCredentials.indexOf(cr);
+    if (index != -1) {
+      _proxyCredentials.removeAt(index);
+    }
+  }
+
+  static String _findProxyFromEnvironment(
+      Uri url, Map<String, String> environment) {
+    checkNoProxy(String option) {
+      if (option == null) return null;
+      Iterator<String> names = option.split(",").map((s) => s.trim()).iterator;
+      while (names.moveNext()) {
+        var name = names.current;
+        if ((name.startsWith("[") &&
+                name.endsWith("]") &&
+                "[${url.host}]" == name) ||
+            (name.isNotEmpty && url.host.endsWith(name))) {
+          return "DIRECT";
+        }
+      }
+      return null;
+    }
+
+    checkProxy(String option) {
+      if (option == null) return null;
+      option = option.trim();
+      if (option.isEmpty) return null;
+      int pos = option.indexOf("://");
+      if (pos >= 0) {
+        option = option.substring(pos + 3);
+      }
+      pos = option.indexOf("/");
+      if (pos >= 0) {
+        option = option.substring(0, pos);
+      }
+      // Add default port if no port configured.
+      if (option.indexOf("[") == 0) {
+        var pos = option.lastIndexOf(":");
+        if (option.indexOf("]") > pos) option = "$option:1080";
+      } else {
+        if (option.indexOf(":") == -1) option = "$option:1080";
+      }
+      return "PROXY $option";
+    }
+
+    // Default to using the process current environment.
+    if (environment == null) environment = _platformEnvironmentCache;
+
+    String proxyCfg;
+
+    String noProxy = environment["no_proxy"];
+    if (noProxy == null) noProxy = environment["NO_PROXY"];
+    if ((proxyCfg = checkNoProxy(noProxy)) != null) {
+      return proxyCfg;
+    }
+
+    if (url.scheme == "http") {
+      String proxy = environment["http_proxy"];
+      if (proxy == null) proxy = environment["HTTP_PROXY"];
+      if ((proxyCfg = checkProxy(proxy)) != null) {
+        return proxyCfg;
+      }
+    } else if (url.scheme == "https") {
+      String proxy = environment["https_proxy"];
+      if (proxy == null) proxy = environment["HTTPS_PROXY"];
+      if ((proxyCfg = checkProxy(proxy)) != null) {
+        return proxyCfg;
+      }
+    }
+    return "DIRECT";
+  }
+
+  static Map<String, String> _platformEnvironmentCache = Platform.environment;
+}
+
+class _HttpConnection extends LinkedListEntry<_HttpConnection>
+    with _ServiceObject {
+  static const _ACTIVE = 0;
+  static const _IDLE = 1;
+  static const _CLOSING = 2;
+  static const _DETACHED = 3;
+
+  // Use HashMap, as we don't need to keep order.
+  static Map<int, _HttpConnection> _connections =
+      new HashMap<int, _HttpConnection>();
+
+  final /*_ServerSocket*/ _socket;
+  final _HttpServer _httpServer;
+  final _HttpParser _httpParser;
+  int _state = _IDLE;
+  StreamSubscription _subscription;
+  bool _idleMark = false;
+  Future _streamFuture;
+
+  _HttpConnection(this._socket, this._httpServer)
+      : _httpParser = new _HttpParser.requestParser() {
+    _connections[_serviceId] = this;
+    _httpParser.listenToStream(_socket);
+    _subscription = _httpParser.listen((incoming) {
+      _httpServer._markActive(this);
+      // If the incoming was closed, close the connection.
+      incoming.dataDone.then((closing) {
+        if (closing) destroy();
+      });
+      // Only handle one incoming request at the time. Keep the
+      // stream paused until the request has been send.
+      _subscription.pause();
+      _state = _ACTIVE;
+      var outgoing = new _HttpOutgoing(_socket);
+      var response = new _HttpResponse(
+          incoming.uri,
+          incoming.headers.protocolVersion,
+          outgoing,
+          _httpServer.defaultResponseHeaders,
+          _httpServer.serverHeader);
+      var request = new _HttpRequest(response, incoming, _httpServer, this);
+      _streamFuture = outgoing.done.then((_) {
+        response.deadline = null;
+        if (_state == _DETACHED) return;
+        if (response.persistentConnection &&
+            request.persistentConnection &&
+            incoming.fullBodyRead &&
+            !_httpParser.upgrade &&
+            !_httpServer.closed) {
+          _state = _IDLE;
+          _idleMark = false;
+          _httpServer._markIdle(this);
+          // Resume the subscription for incoming requests as the
+          // request is now processed.
+          _subscription.resume();
+        } else {
+          // Close socket, keep-alive not used or body sent before
+          // received data was handled.
+          destroy();
+        }
+      }, onError: (_) {
+        destroy();
+      });
+      outgoing.ignoreBody = request.method == "HEAD";
+      response._httpRequest = request;
+      _httpServer._handleRequest(request);
+    }, onDone: () {
+      destroy();
+    }, onError: (error) {
+      // Ignore failed requests that was closed before headers was received.
+      destroy();
+    });
+  }
+
+  void markIdle() {
+    _idleMark = true;
+  }
+
+  bool get isMarkedIdle => _idleMark;
+
+  void destroy() {
+    if (_state == _CLOSING || _state == _DETACHED) return;
+    _state = _CLOSING;
+    _socket.destroy();
+    _httpServer._connectionClosed(this);
+    _connections.remove(_serviceId);
+  }
+
+  Future<Socket> detachSocket() {
+    _state = _DETACHED;
+    // Remove connection from server.
+    _httpServer._connectionClosed(this);
+
+    _HttpDetachedIncoming detachedIncoming = _httpParser.detachIncoming();
+
+    return _streamFuture.then((_) {
+      _connections.remove(_serviceId);
+      return new _DetachedSocket(_socket, detachedIncoming);
+    });
+  }
+
+  HttpConnectionInfo get connectionInfo => _HttpConnectionInfo.create(_socket);
+
+  bool get _isActive => _state == _ACTIVE;
+  bool get _isIdle => _state == _IDLE;
+  bool get _isClosing => _state == _CLOSING;
+  bool get _isDetached => _state == _DETACHED;
+
+  String get _serviceTypePath => 'io/http/serverconnections';
+  String get _serviceTypeName => 'HttpServerConnection';
+
+  Map _toJSON(bool ref) {
+    var name = "${_socket.address.host}:${_socket.port} <-> "
+        "${_socket.remoteAddress.host}:${_socket.remotePort}";
+    var r = <String, dynamic>{
+      'id': _servicePath,
+      'type': _serviceType(ref),
+      'name': name,
+      'user_name': name,
+    };
+    if (ref) {
+      return r;
+    }
+    r['server'] = _httpServer._toJSON(true);
+    try {
+      r['socket'] = _socket._toJSON(true);
+    } catch (_) {
+      r['socket'] = {
+        'id': _servicePath,
+        'type': '@Socket',
+        'name': 'UserSocket',
+        'user_name': 'UserSocket',
+      };
+    }
+    switch (_state) {
+      case _ACTIVE:
+        r['state'] = "Active";
+        break;
+      case _IDLE:
+        r['state'] = "Idle";
+        break;
+      case _CLOSING:
+        r['state'] = "Closing";
+        break;
+      case _DETACHED:
+        r['state'] = "Detached";
+        break;
+      default:
+        r['state'] = 'Unknown';
+        break;
+    }
+    return r;
+  }
+}
+
+// HTTP server waiting for socket connections.
+class _HttpServer extends Stream<HttpRequest>
+    with _ServiceObject
+    implements HttpServer {
+  // Use default Map so we keep order.
+  static Map<int, _HttpServer> _servers = new Map<int, _HttpServer>();
+
+  String serverHeader;
+  final HttpHeaders defaultResponseHeaders = _initDefaultResponseHeaders();
+  bool autoCompress = false;
+
+  Duration _idleTimeout;
+  Timer _idleTimer;
+
+  static Future<HttpServer> bind(
+      address, int port, int backlog, bool v6Only, bool shared) {
+    return ServerSocket.bind(address, port,
+            backlog: backlog, v6Only: v6Only, shared: shared)
+        .then<HttpServer>((socket) {
+      return new _HttpServer._(socket, true);
+    });
+  }
+
+  static Future<HttpServer> bindSecure(
+      address,
+      int port,
+      SecurityContext context,
+      int backlog,
+      bool v6Only,
+      bool requestClientCertificate,
+      bool shared) {
+    return SecureServerSocket.bind(address, port, context,
+            backlog: backlog,
+            v6Only: v6Only,
+            requestClientCertificate: requestClientCertificate,
+            shared: shared)
+        .then<HttpServer>((socket) {
+      return new _HttpServer._(socket, true);
+    });
+  }
+
+  _HttpServer._(this._serverSocket, this._closeServer) {
+    _controller =
+        new StreamController<HttpRequest>(sync: true, onCancel: close);
+    idleTimeout = const Duration(seconds: 120);
+    _servers[_serviceId] = this;
+  }
+
+  _HttpServer.listenOn(this._serverSocket) : _closeServer = false {
+    _controller =
+        new StreamController<HttpRequest>(sync: true, onCancel: close);
+    idleTimeout = const Duration(seconds: 120);
+    _servers[_serviceId] = this;
+  }
+
+  static HttpHeaders _initDefaultResponseHeaders() {
+    var defaultResponseHeaders = new _HttpHeaders('1.1');
+    defaultResponseHeaders.contentType = ContentType.text;
+    defaultResponseHeaders.set('X-Frame-Options', 'SAMEORIGIN');
+    defaultResponseHeaders.set('X-Content-Type-Options', 'nosniff');
+    defaultResponseHeaders.set('X-XSS-Protection', '1; mode=block');
+    return defaultResponseHeaders;
+  }
+
+  Duration get idleTimeout => _idleTimeout;
+
+  void set idleTimeout(Duration duration) {
+    if (_idleTimer != null) {
+      _idleTimer.cancel();
+      _idleTimer = null;
+    }
+    _idleTimeout = duration;
+    if (_idleTimeout != null) {
+      _idleTimer = new Timer.periodic(_idleTimeout, (_) {
+        for (var idle in _idleConnections.toList()) {
+          if (idle.isMarkedIdle) {
+            idle.destroy();
+          } else {
+            idle.markIdle();
+          }
+        }
+      });
+    }
+  }
+
+  StreamSubscription<HttpRequest> listen(void onData(HttpRequest event),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    _serverSocket.listen((Socket socket) {
+      socket.setOption(SocketOption.tcpNoDelay, true);
+      // Accept the client connection.
+      _HttpConnection connection = new _HttpConnection(socket, this);
+      _idleConnections.add(connection);
+    }, onError: (error, stackTrace) {
+      // Ignore HandshakeExceptions as they are bound to a single request,
+      // and are not fatal for the server.
+      if (error is! HandshakeException) {
+        _controller.addError(error, stackTrace);
+      }
+    }, onDone: _controller.close);
+    return _controller.stream.listen(onData,
+        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+  }
+
+  Future close({bool force: false}) {
+    closed = true;
+    Future result;
+    if (_serverSocket != null && _closeServer) {
+      result = _serverSocket.close();
+    } else {
+      result = new Future.value();
+    }
+    idleTimeout = null;
+    if (force) {
+      for (var c in _activeConnections.toList()) {
+        c.destroy();
+      }
+      assert(_activeConnections.isEmpty);
+    }
+    for (var c in _idleConnections.toList()) {
+      c.destroy();
+    }
+    _maybePerformCleanup();
+    return result;
+  }
+
+  void _maybePerformCleanup() {
+    if (closed &&
+        _idleConnections.isEmpty &&
+        _activeConnections.isEmpty &&
+        _sessionManagerInstance != null) {
+      _sessionManagerInstance.close();
+      _sessionManagerInstance = null;
+      _servers.remove(_serviceId);
+    }
+  }
+
+  int get port {
+    if (closed) throw new HttpException("HttpServer is not bound to a socket");
+    return _serverSocket.port;
+  }
+
+  InternetAddress get address {
+    if (closed) throw new HttpException("HttpServer is not bound to a socket");
+    return _serverSocket.address;
+  }
+
+  set sessionTimeout(int timeout) {
+    _sessionManager.sessionTimeout = timeout;
+  }
+
+  void _handleRequest(_HttpRequest request) {
+    if (!closed) {
+      _controller.add(request);
+    } else {
+      request._httpConnection.destroy();
+    }
+  }
+
+  void _connectionClosed(_HttpConnection connection) {
+    // Remove itself from either idle or active connections.
+    connection.unlink();
+    _maybePerformCleanup();
+  }
+
+  void _markIdle(_HttpConnection connection) {
+    _activeConnections.remove(connection);
+    _idleConnections.add(connection);
+  }
+
+  void _markActive(_HttpConnection connection) {
+    _idleConnections.remove(connection);
+    _activeConnections.add(connection);
+  }
+
+  _HttpSessionManager get _sessionManager {
+    // Lazy init.
+    if (_sessionManagerInstance == null) {
+      _sessionManagerInstance = new _HttpSessionManager();
+    }
+    return _sessionManagerInstance;
+  }
+
+  HttpConnectionsInfo connectionsInfo() {
+    HttpConnectionsInfo result = new HttpConnectionsInfo();
+    result.total = _activeConnections.length + _idleConnections.length;
+    _activeConnections.forEach((_HttpConnection conn) {
+      if (conn._isActive) {
+        result.active++;
+      } else {
+        assert(conn._isClosing);
+        result.closing++;
+      }
+    });
+    _idleConnections.forEach((_HttpConnection conn) {
+      result.idle++;
+      assert(conn._isIdle);
+    });
+    return result;
+  }
+
+  String get _serviceTypePath => 'io/http/servers';
+  String get _serviceTypeName => 'HttpServer';
+
+  Map<String, dynamic> _toJSON(bool ref) {
+    var r = <String, dynamic>{
+      'id': _servicePath,
+      'type': _serviceType(ref),
+      'name': '${address.host}:$port',
+      'user_name': '${address.host}:$port',
+    };
+    if (ref) {
+      return r;
+    }
+    try {
+      r['socket'] = _serverSocket._toJSON(true);
+    } catch (_) {
+      r['socket'] = {
+        'id': _servicePath,
+        'type': '@Socket',
+        'name': 'UserSocket',
+        'user_name': 'UserSocket',
+      };
+    }
+    r['port'] = port;
+    r['address'] = address.host;
+    r['active'] = _activeConnections.map((c) => c._toJSON(true)).toList();
+    r['idle'] = _idleConnections.map((c) => c._toJSON(true)).toList();
+    r['closed'] = closed;
+    return r;
+  }
+
+  _HttpSessionManager _sessionManagerInstance;
+
+  // Indicated if the http server has been closed.
+  bool closed = false;
+
+  // The server listen socket. Untyped as it can be both ServerSocket and
+  // SecureServerSocket.
+  final dynamic /*ServerSocket|SecureServerSocket*/ _serverSocket;
+  final bool _closeServer;
+
+  // Set of currently connected clients.
+  final LinkedList<_HttpConnection> _activeConnections =
+      new LinkedList<_HttpConnection>();
+  final LinkedList<_HttpConnection> _idleConnections =
+      new LinkedList<_HttpConnection>();
+  StreamController<HttpRequest> _controller;
+}
+
+class _ProxyConfiguration {
+  static const String PROXY_PREFIX = "PROXY ";
+  static const String DIRECT_PREFIX = "DIRECT";
+
+  _ProxyConfiguration(String configuration) : proxies = new List<_Proxy>() {
+    if (configuration == null) {
+      throw new HttpException("Invalid proxy configuration $configuration");
+    }
+    List<String> list = configuration.split(";");
+    list.forEach((String proxy) {
+      proxy = proxy.trim();
+      if (!proxy.isEmpty) {
+        if (proxy.startsWith(PROXY_PREFIX)) {
+          String username;
+          String password;
+          // Skip the "PROXY " prefix.
+          proxy = proxy.substring(PROXY_PREFIX.length).trim();
+          // Look for proxy authentication.
+          int at = proxy.indexOf("@");
+          if (at != -1) {
+            String userinfo = proxy.substring(0, at).trim();
+            proxy = proxy.substring(at + 1).trim();
+            int colon = userinfo.indexOf(":");
+            if (colon == -1 || colon == 0 || colon == proxy.length - 1) {
+              throw new HttpException(
+                  "Invalid proxy configuration $configuration");
+            }
+            username = userinfo.substring(0, colon).trim();
+            password = userinfo.substring(colon + 1).trim();
+          }
+          // Look for proxy host and port.
+          int colon = proxy.lastIndexOf(":");
+          if (colon == -1 || colon == 0 || colon == proxy.length - 1) {
+            throw new HttpException(
+                "Invalid proxy configuration $configuration");
+          }
+          String host = proxy.substring(0, colon).trim();
+          if (host.startsWith("[") && host.endsWith("]")) {
+            host = host.substring(1, host.length - 1);
+          }
+          String portString = proxy.substring(colon + 1).trim();
+          int port;
+          try {
+            port = int.parse(portString);
+          } on FormatException catch (e) {
+            throw new HttpException(
+                "Invalid proxy configuration $configuration, "
+                "invalid port '$portString'");
+          }
+          proxies.add(new _Proxy(host, port, username, password));
+        } else if (proxy.trim() == DIRECT_PREFIX) {
+          proxies.add(new _Proxy.direct());
+        } else {
+          throw new HttpException("Invalid proxy configuration $configuration");
+        }
+      }
+    });
+  }
+
+  const _ProxyConfiguration.direct() : proxies = const [const _Proxy.direct()];
+
+  final List<_Proxy> proxies;
+}
+
+class _Proxy {
+  final String host;
+  final int port;
+  final String username;
+  final String password;
+  final bool isDirect;
+
+  const _Proxy(this.host, this.port, this.username, this.password)
+      : isDirect = false;
+  const _Proxy.direct()
+      : host = null,
+        port = null,
+        username = null,
+        password = null,
+        isDirect = true;
+
+  bool get isAuthenticated => username != null;
+}
+
+class _HttpConnectionInfo implements HttpConnectionInfo {
+  InternetAddress remoteAddress;
+  int remotePort;
+  int localPort;
+
+  static _HttpConnectionInfo create(Socket socket) {
+    if (socket == null) return null;
+    try {
+      _HttpConnectionInfo info = new _HttpConnectionInfo();
+      return info
+        ..remoteAddress = socket.remoteAddress
+        ..remotePort = socket.remotePort
+        ..localPort = socket.port;
+    } catch (e) {}
+    return null;
+  }
+}
+
+class _DetachedSocket extends Stream<Uint8List> implements Socket {
+  final Stream<Uint8List> _incoming;
+  final Socket _socket;
+
+  _DetachedSocket(this._socket, this._incoming);
+
+  StreamSubscription<Uint8List> listen(void onData(Uint8List event),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    return _incoming.listen(onData,
+        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+  }
+
+  Encoding get encoding => _socket.encoding;
+
+  void set encoding(Encoding value) {
+    _socket.encoding = value;
+  }
+
+  void write(Object obj) {
+    _socket.write(obj);
+  }
+
+  void writeln([Object obj = ""]) {
+    _socket.writeln(obj);
+  }
+
+  void writeCharCode(int charCode) {
+    _socket.writeCharCode(charCode);
+  }
+
+  void writeAll(Iterable objects, [String separator = ""]) {
+    _socket.writeAll(objects, separator);
+  }
+
+  void add(List<int> bytes) {
+    _socket.add(bytes);
+  }
+
+  void addError(error, [StackTrace stackTrace]) =>
+      _socket.addError(error, stackTrace);
+
+  Future addStream(Stream<List<int>> stream) {
+    return _socket.addStream(stream);
+  }
+
+  void destroy() {
+    _socket.destroy();
+  }
+
+  Future flush() => _socket.flush();
+
+  Future close() => _socket.close();
+
+  Future get done => _socket.done;
+
+  int get port => _socket.port;
+
+  InternetAddress get address => _socket.address;
+
+  InternetAddress get remoteAddress => _socket.remoteAddress;
+
+  int get remotePort => _socket.remotePort;
+
+  bool setOption(SocketOption option, bool enabled) {
+    return _socket.setOption(option, enabled);
+  }
+
+  Uint8List getRawOption(RawSocketOption option) {
+    return _socket.getRawOption(option);
+  }
+
+  void setRawOption(RawSocketOption option) {
+    _socket.setRawOption(option);
+  }
+
+  Map _toJSON(bool ref) {
+    return (_socket as dynamic)._toJSON(ref);
+  }
+}
+
+class _AuthenticationScheme {
+  final int _scheme;
+
+  static const UNKNOWN = const _AuthenticationScheme(-1);
+  static const BASIC = const _AuthenticationScheme(0);
+  static const DIGEST = const _AuthenticationScheme(1);
+
+  const _AuthenticationScheme(this._scheme);
+
+  factory _AuthenticationScheme.fromString(String scheme) {
+    if (scheme.toLowerCase() == "basic") return BASIC;
+    if (scheme.toLowerCase() == "digest") return DIGEST;
+    return UNKNOWN;
+  }
+
+  String toString() {
+    if (this == BASIC) return "Basic";
+    if (this == DIGEST) return "Digest";
+    return "Unknown";
+  }
+}
+
+abstract class _Credentials {
+  _HttpClientCredentials credentials;
+  String realm;
+  bool used = false;
+
+  // Digest specific fields.
+  String ha1;
+  String nonce;
+  String algorithm;
+  String qop;
+  int nonceCount;
+
+  _Credentials(this.credentials, this.realm) {
+    if (credentials.scheme == _AuthenticationScheme.DIGEST) {
+      // Calculate the H(A1) value once. There is no mentioning of
+      // username/password encoding in RFC 2617. However there is an
+      // open draft for adding an additional accept-charset parameter to
+      // the WWW-Authenticate and Proxy-Authenticate headers, see
+      // http://tools.ietf.org/html/draft-reschke-basicauth-enc-06. For
+      // now always use UTF-8 encoding.
+      _HttpClientDigestCredentials creds = credentials;
+      var hasher = new _MD5()
+        ..add(utf8.encode(creds.username))
+        ..add([_CharCode.COLON])
+        ..add(realm.codeUnits)
+        ..add([_CharCode.COLON])
+        ..add(utf8.encode(creds.password));
+      ha1 = _CryptoUtils.bytesToHex(hasher.close());
+    }
+  }
+
+  _AuthenticationScheme get scheme => credentials.scheme;
+
+  void authorize(HttpClientRequest request);
+}
+
+class _SiteCredentials extends _Credentials {
+  Uri uri;
+
+  _SiteCredentials(this.uri, realm, _HttpClientCredentials creds)
+      : super(creds, realm);
+
+  bool applies(Uri uri, _AuthenticationScheme scheme) {
+    if (scheme != null && credentials.scheme != scheme) return false;
+    if (uri.host != this.uri.host) return false;
+    int thisPort =
+        this.uri.port == 0 ? HttpClient.defaultHttpPort : this.uri.port;
+    int otherPort = uri.port == 0 ? HttpClient.defaultHttpPort : uri.port;
+    if (otherPort != thisPort) return false;
+    return uri.path.startsWith(this.uri.path);
+  }
+
+  void authorize(HttpClientRequest request) {
+    // Digest credentials cannot be used without a nonce from the
+    // server.
+    if (credentials.scheme == _AuthenticationScheme.DIGEST && nonce == null) {
+      return;
+    }
+    credentials.authorize(this, request);
+    used = true;
+  }
+}
+
+class _ProxyCredentials extends _Credentials {
+  String host;
+  int port;
+
+  _ProxyCredentials(this.host, this.port, realm, _HttpClientCredentials creds)
+      : super(creds, realm);
+
+  bool applies(_Proxy proxy, _AuthenticationScheme scheme) {
+    if (scheme != null && credentials.scheme != scheme) return false;
+    return proxy.host == host && proxy.port == port;
+  }
+
+  void authorize(HttpClientRequest request) {
+    // Digest credentials cannot be used without a nonce from the
+    // server.
+    if (credentials.scheme == _AuthenticationScheme.DIGEST && nonce == null) {
+      return;
+    }
+    credentials.authorizeProxy(this, request);
+  }
+}
+
+abstract class _HttpClientCredentials implements HttpClientCredentials {
+  _AuthenticationScheme get scheme;
+  void authorize(_Credentials credentials, HttpClientRequest request);
+  void authorizeProxy(_ProxyCredentials credentials, HttpClientRequest request);
+}
+
+class _HttpClientBasicCredentials extends _HttpClientCredentials
+    implements HttpClientBasicCredentials {
+  String username;
+  String password;
+
+  _HttpClientBasicCredentials(this.username, this.password);
+
+  _AuthenticationScheme get scheme => _AuthenticationScheme.BASIC;
+
+  String authorization() {
+    // There is no mentioning of username/password encoding in RFC
+    // 2617. However there is an open draft for adding an additional
+    // accept-charset parameter to the WWW-Authenticate and
+    // Proxy-Authenticate headers, see
+    // http://tools.ietf.org/html/draft-reschke-basicauth-enc-06. For
+    // now always use UTF-8 encoding.
+    String auth =
+        _CryptoUtils.bytesToBase64(utf8.encode("$username:$password"));
+    return "Basic $auth";
+  }
+
+  void authorize(_Credentials _, HttpClientRequest request) {
+    request.headers.set(HttpHeaders.authorizationHeader, authorization());
+  }
+
+  void authorizeProxy(_ProxyCredentials _, HttpClientRequest request) {
+    request.headers.set(HttpHeaders.proxyAuthorizationHeader, authorization());
+  }
+}
+
+class _HttpClientDigestCredentials extends _HttpClientCredentials
+    implements HttpClientDigestCredentials {
+  String username;
+  String password;
+
+  _HttpClientDigestCredentials(this.username, this.password);
+
+  _AuthenticationScheme get scheme => _AuthenticationScheme.DIGEST;
+
+  String authorization(_Credentials credentials, _HttpClientRequest request) {
+    String requestUri = request._requestUri();
+    _MD5 hasher = new _MD5()
+      ..add(request.method.codeUnits)
+      ..add([_CharCode.COLON])
+      ..add(requestUri.codeUnits);
+    var ha2 = _CryptoUtils.bytesToHex(hasher.close());
+
+    String qop;
+    String cnonce;
+    String nc;
+    var x;
+    hasher = new _MD5()..add(credentials.ha1.codeUnits)..add([_CharCode.COLON]);
+    if (credentials.qop == "auth") {
+      qop = credentials.qop;
+      cnonce = _CryptoUtils.bytesToHex(_CryptoUtils.getRandomBytes(4));
+      ++credentials.nonceCount;
+      nc = credentials.nonceCount.toRadixString(16);
+      nc = "00000000".substring(0, 8 - nc.length + 1) + nc;
+      hasher
+        ..add(credentials.nonce.codeUnits)
+        ..add([_CharCode.COLON])
+        ..add(nc.codeUnits)
+        ..add([_CharCode.COLON])
+        ..add(cnonce.codeUnits)
+        ..add([_CharCode.COLON])
+        ..add(credentials.qop.codeUnits)
+        ..add([_CharCode.COLON])
+        ..add(ha2.codeUnits);
+    } else {
+      hasher
+        ..add(credentials.nonce.codeUnits)
+        ..add([_CharCode.COLON])
+        ..add(ha2.codeUnits);
+    }
+    var response = _CryptoUtils.bytesToHex(hasher.close());
+
+    StringBuffer buffer = new StringBuffer()
+      ..write('Digest ')
+      ..write('username="$username"')
+      ..write(', realm="${credentials.realm}"')
+      ..write(', nonce="${credentials.nonce}"')
+      ..write(', uri="$requestUri"')
+      ..write(', algorithm="${credentials.algorithm}"');
+    if (qop == "auth") {
+      buffer
+        ..write(', qop="$qop"')
+        ..write(', cnonce="$cnonce"')
+        ..write(', nc="$nc"');
+    }
+    buffer.write(', response="$response"');
+    return buffer.toString();
+  }
+
+  void authorize(_Credentials credentials, HttpClientRequest request) {
+    request.headers.set(
+        HttpHeaders.authorizationHeader, authorization(credentials, request));
+  }
+
+  void authorizeProxy(
+      _ProxyCredentials credentials, HttpClientRequest request) {
+    request.headers.set(HttpHeaders.proxyAuthorizationHeader,
+        authorization(credentials, request));
+  }
+}
+
+class _RedirectInfo implements RedirectInfo {
+  final int statusCode;
+  final String method;
+  final Uri location;
+  const _RedirectInfo(this.statusCode, this.method, this.location);
+}
+
+String _getHttpVersion() {
+  var version = Platform.version;
+  // Only include major and minor version numbers.
+  int index = version.indexOf('.', version.indexOf('.') + 1);
+  version = version.substring(0, index);
+  return 'Dart/$version (dart:io)';
+}
diff --git a/sdk_nnbd/lib/_http/http_parser.dart b/sdk_nnbd/lib/_http/http_parser.dart
new file mode 100644
index 0000000..bd85b2b
--- /dev/null
+++ b/sdk_nnbd/lib/_http/http_parser.dart
@@ -0,0 +1,1062 @@
+// 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 dart._http;
+
+// Global constants.
+class _Const {
+  // Bytes for "HTTP".
+  static const HTTP = const [72, 84, 84, 80];
+  // Bytes for "HTTP/1.".
+  static const HTTP1DOT = const [72, 84, 84, 80, 47, 49, 46];
+  // Bytes for "HTTP/1.0".
+  static const HTTP10 = const [72, 84, 84, 80, 47, 49, 46, 48];
+  // Bytes for "HTTP/1.1".
+  static const HTTP11 = const [72, 84, 84, 80, 47, 49, 46, 49];
+
+  static const bool T = true;
+  static const bool F = false;
+  // Loopup-map for the following characters: '()<>@,;:\\"/[]?={} \t'.
+  static const SEPARATOR_MAP = const [
+    F, F, F, F, F, F, F, F, F, T, F, F, F, F, F, F, F, F, F, F, F, F, F, F, //
+    F, F, F, F, F, F, F, F, T, F, T, F, F, F, F, F, T, T, F, F, T, F, F, T, //
+    F, F, F, F, F, F, F, F, F, F, T, T, T, T, T, T, T, F, F, F, F, F, F, F, //
+    F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, T, T, T, F, F, //
+    F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, //
+    F, F, F, T, F, T, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, //
+    F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, //
+    F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, //
+    F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, //
+    F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, //
+    F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F
+  ];
+}
+
+// Frequently used character codes.
+class _CharCode {
+  static const int HT = 9;
+  static const int LF = 10;
+  static const int CR = 13;
+  static const int SP = 32;
+  static const int AMPERSAND = 38;
+  static const int COMMA = 44;
+  static const int DASH = 45;
+  static const int SLASH = 47;
+  static const int ZERO = 48;
+  static const int ONE = 49;
+  static const int COLON = 58;
+  static const int SEMI_COLON = 59;
+  static const int EQUAL = 61;
+}
+
+// States of the HTTP parser state machine.
+class _State {
+  static const int START = 0;
+  static const int METHOD_OR_RESPONSE_HTTP_VERSION = 1;
+  static const int RESPONSE_HTTP_VERSION = 2;
+  static const int REQUEST_LINE_METHOD = 3;
+  static const int REQUEST_LINE_URI = 4;
+  static const int REQUEST_LINE_HTTP_VERSION = 5;
+  static const int REQUEST_LINE_ENDING = 6;
+  static const int RESPONSE_LINE_STATUS_CODE = 7;
+  static const int RESPONSE_LINE_REASON_PHRASE = 8;
+  static const int RESPONSE_LINE_ENDING = 9;
+  static const int HEADER_START = 10;
+  static const int HEADER_FIELD = 11;
+  static const int HEADER_VALUE_START = 12;
+  static const int HEADER_VALUE = 13;
+  static const int HEADER_VALUE_FOLDING_OR_ENDING = 14;
+  static const int HEADER_VALUE_FOLD_OR_END = 15;
+  static const int HEADER_ENDING = 16;
+
+  static const int CHUNK_SIZE_STARTING_CR = 17;
+  static const int CHUNK_SIZE_STARTING_LF = 18;
+  static const int CHUNK_SIZE = 19;
+  static const int CHUNK_SIZE_EXTENSION = 20;
+  static const int CHUNK_SIZE_ENDING = 21;
+  static const int CHUNKED_BODY_DONE_CR = 22;
+  static const int CHUNKED_BODY_DONE_LF = 23;
+  static const int BODY = 24;
+  static const int CLOSED = 25;
+  static const int UPGRADED = 26;
+  static const int FAILURE = 27;
+
+  static const int FIRST_BODY_STATE = CHUNK_SIZE_STARTING_CR;
+}
+
+// HTTP version of the request or response being parsed.
+class _HttpVersion {
+  static const int UNDETERMINED = 0;
+  static const int HTTP10 = 1;
+  static const int HTTP11 = 2;
+}
+
+// States of the HTTP parser state machine.
+class _MessageType {
+  static const int UNDETERMINED = 0;
+  static const int REQUEST = 1;
+  static const int RESPONSE = 0;
+}
+
+/**
+ * The _HttpDetachedStreamSubscription takes a subscription and some extra data,
+ * and makes it possible to "inject" the data in from of other data events
+ * from the subscription.
+ *
+ * It does so by overriding pause/resume, so that once the
+ * _HttpDetachedStreamSubscription is resumed, it'll deliver the data before
+ * resuming the underlaying subscription.
+ */
+class _HttpDetachedStreamSubscription implements StreamSubscription<Uint8List> {
+  StreamSubscription<Uint8List> _subscription;
+  Uint8List _injectData;
+  bool _isCanceled = false;
+  int _pauseCount = 1;
+  Function _userOnData;
+  bool _scheduled = false;
+
+  _HttpDetachedStreamSubscription(
+      this._subscription, this._injectData, this._userOnData);
+
+  bool get isPaused => _subscription.isPaused;
+
+  Future<T> asFuture<T>([T futureValue]) =>
+      _subscription.asFuture<T>(futureValue);
+
+  Future cancel() {
+    _isCanceled = true;
+    _injectData = null;
+    return _subscription.cancel();
+  }
+
+  void onData(void handleData(Uint8List data)) {
+    _userOnData = handleData;
+    _subscription.onData(handleData);
+  }
+
+  void onDone(void handleDone()) {
+    _subscription.onDone(handleDone);
+  }
+
+  void onError(Function handleError) {
+    _subscription.onError(handleError);
+  }
+
+  void pause([Future resumeSignal]) {
+    if (_injectData == null) {
+      _subscription.pause(resumeSignal);
+    } else {
+      _pauseCount++;
+      if (resumeSignal != null) {
+        resumeSignal.whenComplete(resume);
+      }
+    }
+  }
+
+  void resume() {
+    if (_injectData == null) {
+      _subscription.resume();
+    } else {
+      _pauseCount--;
+      _maybeScheduleData();
+    }
+  }
+
+  void _maybeScheduleData() {
+    if (_scheduled) return;
+    if (_pauseCount != 0) return;
+    _scheduled = true;
+    scheduleMicrotask(() {
+      _scheduled = false;
+      if (_pauseCount > 0 || _isCanceled) return;
+      var data = _injectData;
+      _injectData = null;
+      // To ensure that 'subscription.isPaused' is false, we resume the
+      // subscription here. This is fine as potential events are delayed.
+      _subscription.resume();
+      if (_userOnData != null) {
+        _userOnData(data);
+      }
+    });
+  }
+}
+
+class _HttpDetachedIncoming extends Stream<Uint8List> {
+  final StreamSubscription<Uint8List> subscription;
+  final Uint8List bufferedData;
+
+  _HttpDetachedIncoming(this.subscription, this.bufferedData);
+
+  StreamSubscription<Uint8List> listen(void onData(Uint8List event),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    if (subscription != null) {
+      subscription
+        ..onData(onData)
+        ..onError(onError)
+        ..onDone(onDone);
+      if (bufferedData == null) {
+        return subscription..resume();
+      }
+      return new _HttpDetachedStreamSubscription(
+          subscription, bufferedData, onData)
+        ..resume();
+    } else {
+      // TODO(26379): add test for this branch.
+      return new Stream<Uint8List>.fromIterable([bufferedData]).listen(onData,
+          onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+    }
+  }
+}
+
+/**
+ * HTTP parser which parses the data stream given to [consume].
+ *
+ * If an HTTP parser error occurs, the parser will signal an error to either
+ * the current _HttpIncoming or the _parser itself.
+ *
+ * The connection upgrades (e.g. switching from HTTP/1.1 to the
+ * WebSocket protocol) is handled in a special way. If connection
+ * upgrade is specified in the headers, then on the callback to
+ * [:responseStart:] the [:upgrade:] property on the [:HttpParser:]
+ * object will be [:true:] indicating that from now on the protocol is
+ * not HTTP anymore and no more callbacks will happen, that is
+ * [:dataReceived:] and [:dataEnd:] are not called in this case as
+ * there is no more HTTP data. After the upgrade the method
+ * [:readUnparsedData:] can be used to read any remaining bytes in the
+ * HTTP parser which are part of the protocol the connection is
+ * upgrading to. These bytes cannot be processed by the HTTP parser
+ * and should be handled according to whatever protocol is being
+ * upgraded to.
+ */
+class _HttpParser extends Stream<_HttpIncoming> {
+  // State.
+  bool _parserCalled = false;
+
+  // The data that is currently being parsed.
+  Uint8List _buffer;
+  int _index;
+
+  final bool _requestParser;
+  int _state;
+  int _httpVersionIndex;
+  int _messageType;
+  int _statusCode = 0;
+  int _statusCodeLength = 0;
+  final List<int> _method = [];
+  final List<int> _uri_or_reason_phrase = [];
+  final List<int> _headerField = [];
+  final List<int> _headerValue = [];
+
+  int _httpVersion;
+  int _transferLength = -1;
+  bool _persistentConnection;
+  bool _connectionUpgrade;
+  bool _chunked;
+
+  bool _noMessageBody = false;
+  int _remainingContent = -1;
+
+  _HttpHeaders _headers;
+
+  // The current incoming connection.
+  _HttpIncoming _incoming;
+  StreamSubscription<Uint8List> _socketSubscription;
+  bool _paused = true;
+  bool _bodyPaused = false;
+  StreamController<_HttpIncoming> _controller;
+  StreamController<Uint8List> _bodyController;
+
+  factory _HttpParser.requestParser() {
+    return new _HttpParser._(true);
+  }
+
+  factory _HttpParser.responseParser() {
+    return new _HttpParser._(false);
+  }
+
+  _HttpParser._(this._requestParser) {
+    _controller = new StreamController<_HttpIncoming>(
+        sync: true,
+        onListen: () {
+          _paused = false;
+        },
+        onPause: () {
+          _paused = true;
+          _pauseStateChanged();
+        },
+        onResume: () {
+          _paused = false;
+          _pauseStateChanged();
+        },
+        onCancel: () {
+          if (_socketSubscription != null) {
+            _socketSubscription.cancel();
+          }
+        });
+    _reset();
+  }
+
+  StreamSubscription<_HttpIncoming> listen(void onData(_HttpIncoming event),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    return _controller.stream.listen(onData,
+        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+  }
+
+  void listenToStream(Stream<Uint8List> stream) {
+    // Listen to the stream and handle data accordingly. When a
+    // _HttpIncoming is created, _dataPause, _dataResume, _dataDone is
+    // given to provide a way of controlling the parser.
+    // TODO(ajohnsen): Remove _dataPause, _dataResume and _dataDone and clean up
+    // how the _HttpIncoming signals the parser.
+    _socketSubscription =
+        stream.listen(_onData, onError: _controller.addError, onDone: _onDone);
+  }
+
+  void _parse() {
+    try {
+      _doParse();
+    } catch (e, s) {
+      _state = _State.FAILURE;
+      _reportError(e, s);
+    }
+  }
+
+  // Process end of headers. Returns true if the parser should stop
+  // parsing and return. This will be in case of either an upgrade
+  // request or a request or response with an empty body.
+  bool _headersEnd() {
+    _headers._mutable = false;
+
+    _transferLength = _headers.contentLength;
+    // Ignore the Content-Length header if Transfer-Encoding
+    // is chunked (RFC 2616 section 4.4)
+    if (_chunked) _transferLength = -1;
+
+    // If a request message has neither Content-Length nor
+    // Transfer-Encoding the message must not have a body (RFC
+    // 2616 section 4.3).
+    if (_messageType == _MessageType.REQUEST &&
+        _transferLength < 0 &&
+        _chunked == false) {
+      _transferLength = 0;
+    }
+    if (_connectionUpgrade) {
+      _state = _State.UPGRADED;
+      _transferLength = 0;
+    }
+    _createIncoming(_transferLength);
+    if (_requestParser) {
+      _incoming.method = new String.fromCharCodes(_method);
+      _incoming.uri =
+          Uri.parse(new String.fromCharCodes(_uri_or_reason_phrase));
+    } else {
+      _incoming.statusCode = _statusCode;
+      _incoming.reasonPhrase = new String.fromCharCodes(_uri_or_reason_phrase);
+    }
+    _method.clear();
+    _uri_or_reason_phrase.clear();
+    if (_connectionUpgrade) {
+      _incoming.upgraded = true;
+      _parserCalled = false;
+      var tmp = _incoming;
+      _closeIncoming();
+      _controller.add(tmp);
+      return true;
+    }
+    if (_transferLength == 0 ||
+        (_messageType == _MessageType.RESPONSE && _noMessageBody)) {
+      _reset();
+      var tmp = _incoming;
+      _closeIncoming();
+      _controller.add(tmp);
+      return false;
+    } else if (_chunked) {
+      _state = _State.CHUNK_SIZE;
+      _remainingContent = 0;
+    } else if (_transferLength > 0) {
+      _remainingContent = _transferLength;
+      _state = _State.BODY;
+    } else {
+      // Neither chunked nor content length. End of body
+      // indicated by close.
+      _state = _State.BODY;
+    }
+    _parserCalled = false;
+    _controller.add(_incoming);
+    return true;
+  }
+
+  // From RFC 2616.
+  // generic-message = start-line
+  //                   *(message-header CRLF)
+  //                   CRLF
+  //                   [ message-body ]
+  // start-line      = Request-Line | Status-Line
+  // Request-Line    = Method SP Request-URI SP HTTP-Version CRLF
+  // Status-Line     = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
+  // message-header  = field-name ":" [ field-value ]
+  void _doParse() {
+    assert(!_parserCalled);
+    _parserCalled = true;
+    if (_state == _State.CLOSED) {
+      throw new HttpException("Data on closed connection");
+    }
+    if (_state == _State.FAILURE) {
+      throw new HttpException("Data on failed connection");
+    }
+    while (_buffer != null &&
+        _index < _buffer.length &&
+        _state != _State.FAILURE &&
+        _state != _State.UPGRADED) {
+      // Depending on _incoming, we either break on _bodyPaused or _paused.
+      if ((_incoming != null && _bodyPaused) ||
+          (_incoming == null && _paused)) {
+        _parserCalled = false;
+        return;
+      }
+      int byte = _buffer[_index++];
+      switch (_state) {
+        case _State.START:
+          if (byte == _Const.HTTP[0]) {
+            // Start parsing method or HTTP version.
+            _httpVersionIndex = 1;
+            _state = _State.METHOD_OR_RESPONSE_HTTP_VERSION;
+          } else {
+            // Start parsing method.
+            if (!_isTokenChar(byte)) {
+              throw new HttpException("Invalid request method");
+            }
+            _method.add(byte);
+            if (!_requestParser) {
+              throw new HttpException("Invalid response line");
+            }
+            _state = _State.REQUEST_LINE_METHOD;
+          }
+          break;
+
+        case _State.METHOD_OR_RESPONSE_HTTP_VERSION:
+          if (_httpVersionIndex < _Const.HTTP.length &&
+              byte == _Const.HTTP[_httpVersionIndex]) {
+            // Continue parsing HTTP version.
+            _httpVersionIndex++;
+          } else if (_httpVersionIndex == _Const.HTTP.length &&
+              byte == _CharCode.SLASH) {
+            // HTTP/ parsed. As method is a token this cannot be a
+            // method anymore.
+            _httpVersionIndex++;
+            if (_requestParser) {
+              throw new HttpException("Invalid request line");
+            }
+            _state = _State.RESPONSE_HTTP_VERSION;
+          } else {
+            // Did not parse HTTP version. Expect method instead.
+            for (int i = 0; i < _httpVersionIndex; i++) {
+              _method.add(_Const.HTTP[i]);
+            }
+            if (byte == _CharCode.SP) {
+              _state = _State.REQUEST_LINE_URI;
+            } else {
+              _method.add(byte);
+              _httpVersion = _HttpVersion.UNDETERMINED;
+              if (!_requestParser) {
+                throw new HttpException("Invalid response line");
+              }
+              _state = _State.REQUEST_LINE_METHOD;
+            }
+          }
+          break;
+
+        case _State.RESPONSE_HTTP_VERSION:
+          if (_httpVersionIndex < _Const.HTTP1DOT.length) {
+            // Continue parsing HTTP version.
+            _expect(byte, _Const.HTTP1DOT[_httpVersionIndex]);
+            _httpVersionIndex++;
+          } else if (_httpVersionIndex == _Const.HTTP1DOT.length &&
+              byte == _CharCode.ONE) {
+            // HTTP/1.1 parsed.
+            _httpVersion = _HttpVersion.HTTP11;
+            _persistentConnection = true;
+            _httpVersionIndex++;
+          } else if (_httpVersionIndex == _Const.HTTP1DOT.length &&
+              byte == _CharCode.ZERO) {
+            // HTTP/1.0 parsed.
+            _httpVersion = _HttpVersion.HTTP10;
+            _persistentConnection = false;
+            _httpVersionIndex++;
+          } else if (_httpVersionIndex == _Const.HTTP1DOT.length + 1) {
+            _expect(byte, _CharCode.SP);
+            // HTTP version parsed.
+            _state = _State.RESPONSE_LINE_STATUS_CODE;
+          } else {
+            throw new HttpException("Invalid response line");
+          }
+          break;
+
+        case _State.REQUEST_LINE_METHOD:
+          if (byte == _CharCode.SP) {
+            _state = _State.REQUEST_LINE_URI;
+          } else {
+            if (_Const.SEPARATOR_MAP[byte] ||
+                byte == _CharCode.CR ||
+                byte == _CharCode.LF) {
+              throw new HttpException("Invalid request method");
+            }
+            _method.add(byte);
+          }
+          break;
+
+        case _State.REQUEST_LINE_URI:
+          if (byte == _CharCode.SP) {
+            if (_uri_or_reason_phrase.length == 0) {
+              throw new HttpException("Invalid request URI");
+            }
+            _state = _State.REQUEST_LINE_HTTP_VERSION;
+            _httpVersionIndex = 0;
+          } else {
+            if (byte == _CharCode.CR || byte == _CharCode.LF) {
+              throw new HttpException("Invalid request URI");
+            }
+            _uri_or_reason_phrase.add(byte);
+          }
+          break;
+
+        case _State.REQUEST_LINE_HTTP_VERSION:
+          if (_httpVersionIndex < _Const.HTTP1DOT.length) {
+            _expect(byte, _Const.HTTP11[_httpVersionIndex]);
+            _httpVersionIndex++;
+          } else if (_httpVersionIndex == _Const.HTTP1DOT.length) {
+            if (byte == _CharCode.ONE) {
+              // HTTP/1.1 parsed.
+              _httpVersion = _HttpVersion.HTTP11;
+              _persistentConnection = true;
+              _httpVersionIndex++;
+            } else if (byte == _CharCode.ZERO) {
+              // HTTP/1.0 parsed.
+              _httpVersion = _HttpVersion.HTTP10;
+              _persistentConnection = false;
+              _httpVersionIndex++;
+            } else {
+              throw new HttpException("Invalid response line");
+            }
+          } else {
+            if (byte == _CharCode.CR) {
+              _state = _State.REQUEST_LINE_ENDING;
+            } else {
+              _expect(byte, _CharCode.LF);
+              _messageType = _MessageType.REQUEST;
+              _state = _State.HEADER_START;
+            }
+          }
+          break;
+
+        case _State.REQUEST_LINE_ENDING:
+          _expect(byte, _CharCode.LF);
+          _messageType = _MessageType.REQUEST;
+          _state = _State.HEADER_START;
+          break;
+
+        case _State.RESPONSE_LINE_STATUS_CODE:
+          if (byte == _CharCode.SP) {
+            _state = _State.RESPONSE_LINE_REASON_PHRASE;
+          } else if (byte == _CharCode.CR) {
+            // Some HTTP servers does not follow the spec. and send
+            // \r\n right after the status code.
+            _state = _State.RESPONSE_LINE_ENDING;
+          } else {
+            _statusCodeLength++;
+            if ((byte < 0x30 && 0x39 < byte) || _statusCodeLength > 3) {
+              throw new HttpException("Invalid response status code");
+            } else {
+              _statusCode = _statusCode * 10 + byte - 0x30;
+            }
+          }
+          break;
+
+        case _State.RESPONSE_LINE_REASON_PHRASE:
+          if (byte == _CharCode.CR) {
+            _state = _State.RESPONSE_LINE_ENDING;
+          } else {
+            if (byte == _CharCode.CR || byte == _CharCode.LF) {
+              throw new HttpException("Invalid response reason phrase");
+            }
+            _uri_or_reason_phrase.add(byte);
+          }
+          break;
+
+        case _State.RESPONSE_LINE_ENDING:
+          _expect(byte, _CharCode.LF);
+          _messageType == _MessageType.RESPONSE;
+          if (_statusCode < 100 || _statusCode > 599) {
+            throw new HttpException("Invalid response status code");
+          } else {
+            // Check whether this response will never have a body.
+            if (_statusCode <= 199 ||
+                _statusCode == 204 ||
+                _statusCode == 304) {
+              _noMessageBody = true;
+            }
+          }
+          _state = _State.HEADER_START;
+          break;
+
+        case _State.HEADER_START:
+          _headers = new _HttpHeaders(version);
+          if (byte == _CharCode.CR) {
+            _state = _State.HEADER_ENDING;
+          } else if (byte == _CharCode.LF) {
+            _state = _State.HEADER_ENDING;
+            _index--; // Make the new state see the LF again.
+          } else {
+            // Start of new header field.
+            _headerField.add(_toLowerCaseByte(byte));
+            _state = _State.HEADER_FIELD;
+          }
+          break;
+
+        case _State.HEADER_FIELD:
+          if (byte == _CharCode.COLON) {
+            _state = _State.HEADER_VALUE_START;
+          } else {
+            if (!_isTokenChar(byte)) {
+              throw new HttpException("Invalid header field name");
+            }
+            _headerField.add(_toLowerCaseByte(byte));
+          }
+          break;
+
+        case _State.HEADER_VALUE_START:
+          if (byte == _CharCode.CR) {
+            _state = _State.HEADER_VALUE_FOLDING_OR_ENDING;
+          } else if (byte == _CharCode.LF) {
+            _state = _State.HEADER_VALUE_FOLD_OR_END;
+          } else if (byte != _CharCode.SP && byte != _CharCode.HT) {
+            // Start of new header value.
+            _headerValue.add(byte);
+            _state = _State.HEADER_VALUE;
+          }
+          break;
+
+        case _State.HEADER_VALUE:
+          if (byte == _CharCode.CR) {
+            _state = _State.HEADER_VALUE_FOLDING_OR_ENDING;
+          } else if (byte == _CharCode.LF) {
+            _state = _State.HEADER_VALUE_FOLD_OR_END;
+          } else {
+            _headerValue.add(byte);
+          }
+          break;
+
+        case _State.HEADER_VALUE_FOLDING_OR_ENDING:
+          _expect(byte, _CharCode.LF);
+          _state = _State.HEADER_VALUE_FOLD_OR_END;
+          break;
+
+        case _State.HEADER_VALUE_FOLD_OR_END:
+          if (byte == _CharCode.SP || byte == _CharCode.HT) {
+            _state = _State.HEADER_VALUE_START;
+          } else {
+            String headerField = new String.fromCharCodes(_headerField);
+            String headerValue = new String.fromCharCodes(_headerValue);
+            if (headerField == "transfer-encoding" &&
+                _caseInsensitiveCompare("chunked".codeUnits, _headerValue)) {
+              _chunked = true;
+            }
+            if (headerField == "connection") {
+              List<String> tokens = _tokenizeFieldValue(headerValue);
+              final bool isResponse = _messageType == _MessageType.RESPONSE;
+              final bool isUpgradeCode =
+                  (_statusCode == HttpStatus.upgradeRequired) ||
+                      (_statusCode == HttpStatus.switchingProtocols);
+              for (int i = 0; i < tokens.length; i++) {
+                final bool isUpgrade = _caseInsensitiveCompare(
+                    "upgrade".codeUnits, tokens[i].codeUnits);
+                if ((isUpgrade && !isResponse) ||
+                    (isUpgrade && isResponse && isUpgradeCode)) {
+                  _connectionUpgrade = true;
+                }
+                _headers._add(headerField, tokens[i]);
+              }
+            } else {
+              _headers._add(headerField, headerValue);
+            }
+            _headerField.clear();
+            _headerValue.clear();
+
+            if (byte == _CharCode.CR) {
+              _state = _State.HEADER_ENDING;
+            } else if (byte == _CharCode.LF) {
+              _state = _State.HEADER_ENDING;
+              _index--; // Make the new state see the LF again.
+            } else {
+              // Start of new header field.
+              _headerField.add(_toLowerCaseByte(byte));
+              _state = _State.HEADER_FIELD;
+            }
+          }
+          break;
+
+        case _State.HEADER_ENDING:
+          _expect(byte, _CharCode.LF);
+          if (_headersEnd()) {
+            return;
+          } else {
+            break;
+          }
+          return;
+
+        case _State.CHUNK_SIZE_STARTING_CR:
+          _expect(byte, _CharCode.CR);
+          _state = _State.CHUNK_SIZE_STARTING_LF;
+          break;
+
+        case _State.CHUNK_SIZE_STARTING_LF:
+          _expect(byte, _CharCode.LF);
+          _state = _State.CHUNK_SIZE;
+          break;
+
+        case _State.CHUNK_SIZE:
+          if (byte == _CharCode.CR) {
+            _state = _State.CHUNK_SIZE_ENDING;
+          } else if (byte == _CharCode.SEMI_COLON) {
+            _state = _State.CHUNK_SIZE_EXTENSION;
+          } else {
+            int value = _expectHexDigit(byte);
+            _remainingContent = _remainingContent * 16 + value;
+          }
+          break;
+
+        case _State.CHUNK_SIZE_EXTENSION:
+          if (byte == _CharCode.CR) {
+            _state = _State.CHUNK_SIZE_ENDING;
+          }
+          break;
+
+        case _State.CHUNK_SIZE_ENDING:
+          _expect(byte, _CharCode.LF);
+          if (_remainingContent > 0) {
+            _state = _State.BODY;
+          } else {
+            _state = _State.CHUNKED_BODY_DONE_CR;
+          }
+          break;
+
+        case _State.CHUNKED_BODY_DONE_CR:
+          _expect(byte, _CharCode.CR);
+          _state = _State.CHUNKED_BODY_DONE_LF;
+          break;
+
+        case _State.CHUNKED_BODY_DONE_LF:
+          _expect(byte, _CharCode.LF);
+          _reset();
+          _closeIncoming();
+          break;
+
+        case _State.BODY:
+          // The body is not handled one byte at a time but in blocks.
+          _index--;
+          int dataAvailable = _buffer.length - _index;
+          if (_remainingContent >= 0 && dataAvailable > _remainingContent) {
+            dataAvailable = _remainingContent;
+          }
+          // Always present the data as a view. This way we can handle all
+          // cases like this, and the user will not experience different data
+          // typed (which could lead to polymorphic user code).
+          Uint8List data = new Uint8List.view(
+              _buffer.buffer, _buffer.offsetInBytes + _index, dataAvailable);
+          _bodyController.add(data);
+          if (_remainingContent != -1) {
+            _remainingContent -= data.length;
+          }
+          _index += data.length;
+          if (_remainingContent == 0) {
+            if (!_chunked) {
+              _reset();
+              _closeIncoming();
+            } else {
+              _state = _State.CHUNK_SIZE_STARTING_CR;
+            }
+          }
+          break;
+
+        case _State.FAILURE:
+          // Should be unreachable.
+          assert(false);
+          break;
+
+        default:
+          // Should be unreachable.
+          assert(false);
+          break;
+      }
+    }
+
+    _parserCalled = false;
+    if (_buffer != null && _index == _buffer.length) {
+      // If all data is parsed release the buffer and resume receiving
+      // data.
+      _releaseBuffer();
+      if (_state != _State.UPGRADED && _state != _State.FAILURE) {
+        _socketSubscription.resume();
+      }
+    }
+  }
+
+  void _onData(Uint8List buffer) {
+    _socketSubscription.pause();
+    assert(_buffer == null);
+    _buffer = buffer;
+    _index = 0;
+    _parse();
+  }
+
+  void _onDone() {
+    // onDone cancels the subscription.
+    _socketSubscription = null;
+    if (_state == _State.CLOSED || _state == _State.FAILURE) return;
+
+    if (_incoming != null) {
+      if (_state != _State.UPGRADED &&
+          !(_state == _State.START && !_requestParser) &&
+          !(_state == _State.BODY && !_chunked && _transferLength == -1)) {
+        _bodyController.addError(
+            new HttpException("Connection closed while receiving data"));
+      }
+      _closeIncoming(true);
+      _controller.close();
+      return;
+    }
+    // If the connection is idle the HTTP stream is closed.
+    if (_state == _State.START) {
+      if (!_requestParser) {
+        _reportError(new HttpException(
+            "Connection closed before full header was received"));
+      }
+      _controller.close();
+      return;
+    }
+
+    if (_state == _State.UPGRADED) {
+      _controller.close();
+      return;
+    }
+
+    if (_state < _State.FIRST_BODY_STATE) {
+      _state = _State.FAILURE;
+      // Report the error through the error callback if any. Otherwise
+      // throw the error.
+      _reportError(new HttpException(
+          "Connection closed before full header was received"));
+      _controller.close();
+      return;
+    }
+
+    if (!_chunked && _transferLength == -1) {
+      _state = _State.CLOSED;
+    } else {
+      _state = _State.FAILURE;
+      // Report the error through the error callback if any. Otherwise
+      // throw the error.
+      _reportError(
+          new HttpException("Connection closed before full body was received"));
+    }
+    _controller.close();
+  }
+
+  String get version {
+    switch (_httpVersion) {
+      case _HttpVersion.HTTP10:
+        return "1.0";
+      case _HttpVersion.HTTP11:
+        return "1.1";
+    }
+    return null;
+  }
+
+  int get messageType => _messageType;
+  int get transferLength => _transferLength;
+  bool get upgrade => _connectionUpgrade && _state == _State.UPGRADED;
+  bool get persistentConnection => _persistentConnection;
+
+  void set isHead(bool value) {
+    if (value) _noMessageBody = true;
+  }
+
+  _HttpDetachedIncoming detachIncoming() {
+    // Simulate detached by marking as upgraded.
+    _state = _State.UPGRADED;
+    return new _HttpDetachedIncoming(_socketSubscription, readUnparsedData());
+  }
+
+  Uint8List readUnparsedData() {
+    if (_buffer == null) return null;
+    if (_index == _buffer.length) return null;
+    var result = _buffer.sublist(_index);
+    _releaseBuffer();
+    return result;
+  }
+
+  void _reset() {
+    if (_state == _State.UPGRADED) return;
+    _state = _State.START;
+    _messageType = _MessageType.UNDETERMINED;
+    _headerField.clear();
+    _headerValue.clear();
+    _method.clear();
+    _uri_or_reason_phrase.clear();
+
+    _statusCode = 0;
+    _statusCodeLength = 0;
+
+    _httpVersion = _HttpVersion.UNDETERMINED;
+    _transferLength = -1;
+    _persistentConnection = false;
+    _connectionUpgrade = false;
+    _chunked = false;
+
+    _noMessageBody = false;
+    _remainingContent = -1;
+
+    _headers = null;
+  }
+
+  void _releaseBuffer() {
+    _buffer = null;
+    _index = null;
+  }
+
+  static bool _isTokenChar(int byte) {
+    return byte > 31 && byte < 128 && !_Const.SEPARATOR_MAP[byte];
+  }
+
+  static bool _isValueChar(int byte) {
+    return (byte > 31 && byte < 128) ||
+        (byte == _CharCode.SP) ||
+        (byte == _CharCode.HT);
+  }
+
+  static List<String> _tokenizeFieldValue(String headerValue) {
+    List<String> tokens = new List<String>();
+    int start = 0;
+    int index = 0;
+    while (index < headerValue.length) {
+      if (headerValue[index] == ",") {
+        tokens.add(headerValue.substring(start, index));
+        start = index + 1;
+      } else if (headerValue[index] == " " || headerValue[index] == "\t") {
+        start++;
+      }
+      index++;
+    }
+    tokens.add(headerValue.substring(start, index));
+    return tokens;
+  }
+
+  static int _toLowerCaseByte(int x) {
+    // Optimized version:
+    //  -  0x41 is 'A'
+    //  -  0x7f is ASCII mask
+    //  -  26 is the number of alpha characters.
+    //  -  0x20 is the delta between lower and upper chars.
+    return (((x - 0x41) & 0x7f) < 26) ? (x | 0x20) : x;
+  }
+
+  // expected should already be lowercase.
+  bool _caseInsensitiveCompare(List<int> expected, List<int> value) {
+    if (expected.length != value.length) return false;
+    for (int i = 0; i < expected.length; i++) {
+      if (expected[i] != _toLowerCaseByte(value[i])) return false;
+    }
+    return true;
+  }
+
+  int _expect(int val1, int val2) {
+    if (val1 != val2) {
+      throw new HttpException("Failed to parse HTTP");
+    }
+  }
+
+  int _expectHexDigit(int byte) {
+    if (0x30 <= byte && byte <= 0x39) {
+      return byte - 0x30; // 0 - 9
+    } else if (0x41 <= byte && byte <= 0x46) {
+      return byte - 0x41 + 10; // A - F
+    } else if (0x61 <= byte && byte <= 0x66) {
+      return byte - 0x61 + 10; // a - f
+    } else {
+      throw new HttpException("Failed to parse HTTP");
+    }
+  }
+
+  void _createIncoming(int transferLength) {
+    assert(_incoming == null);
+    assert(_bodyController == null);
+    assert(!_bodyPaused);
+    var incoming;
+    _bodyController = new StreamController<Uint8List>(
+        sync: true,
+        onListen: () {
+          if (incoming != _incoming) return;
+          assert(_bodyPaused);
+          _bodyPaused = false;
+          _pauseStateChanged();
+        },
+        onPause: () {
+          if (incoming != _incoming) return;
+          assert(!_bodyPaused);
+          _bodyPaused = true;
+          _pauseStateChanged();
+        },
+        onResume: () {
+          if (incoming != _incoming) return;
+          assert(_bodyPaused);
+          _bodyPaused = false;
+          _pauseStateChanged();
+        },
+        onCancel: () {
+          if (incoming != _incoming) return;
+          if (_socketSubscription != null) {
+            _socketSubscription.cancel();
+          }
+          _closeIncoming(true);
+          _controller.close();
+        });
+    incoming = _incoming =
+        new _HttpIncoming(_headers, transferLength, _bodyController.stream);
+    _bodyPaused = true;
+    _pauseStateChanged();
+  }
+
+  void _closeIncoming([bool closing = false]) {
+    // Ignore multiple close (can happen in re-entrance).
+    if (_incoming == null) return;
+    var tmp = _incoming;
+    tmp.close(closing);
+    _incoming = null;
+    if (_bodyController != null) {
+      _bodyController.close();
+      _bodyController = null;
+    }
+    _bodyPaused = false;
+    _pauseStateChanged();
+  }
+
+  void _pauseStateChanged() {
+    if (_incoming != null) {
+      if (!_bodyPaused && !_parserCalled) {
+        _parse();
+      }
+    } else {
+      if (!_paused && !_parserCalled) {
+        _parse();
+      }
+    }
+  }
+
+  void _reportError(error, [stackTrace]) {
+    if (_socketSubscription != null) _socketSubscription.cancel();
+    _state = _State.FAILURE;
+    _controller.addError(error, stackTrace);
+    _controller.close();
+  }
+}
diff --git a/sdk_nnbd/lib/_http/http_session.dart b/sdk_nnbd/lib/_http/http_session.dart
new file mode 100644
index 0000000..3907609
--- /dev/null
+++ b/sdk_nnbd/lib/_http/http_session.dart
@@ -0,0 +1,205 @@
+// 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 dart._http;
+
+const String _DART_SESSION_ID = "DARTSESSID";
+
+// A _HttpSession is a node in a double-linked list, with _next and _prev being
+// the previous and next pointers.
+class _HttpSession implements HttpSession {
+  // Destroyed marked. Used by the http connection to see if a session is valid.
+  bool _destroyed = false;
+  bool _isNew = true;
+  DateTime _lastSeen;
+  Function _timeoutCallback;
+  _HttpSessionManager _sessionManager;
+  // Pointers in timeout queue.
+  _HttpSession _prev;
+  _HttpSession _next;
+  final String id;
+
+  final Map _data = new HashMap();
+
+  _HttpSession(this._sessionManager, this.id) : _lastSeen = new DateTime.now();
+
+  void destroy() {
+    _destroyed = true;
+    _sessionManager._removeFromTimeoutQueue(this);
+    _sessionManager._sessions.remove(id);
+  }
+
+  // Mark the session as seen. This will reset the timeout and move the node to
+  // the end of the timeout queue.
+  void _markSeen() {
+    _lastSeen = new DateTime.now();
+    _sessionManager._bumpToEnd(this);
+  }
+
+  DateTime get lastSeen => _lastSeen;
+
+  bool get isNew => _isNew;
+
+  void set onTimeout(void callback()) {
+    _timeoutCallback = callback;
+  }
+
+  // Map implementation:
+  bool containsValue(value) => _data.containsValue(value);
+  bool containsKey(key) => _data.containsKey(key);
+  operator [](key) => _data[key];
+  void operator []=(key, value) {
+    _data[key] = value;
+  }
+
+  putIfAbsent(key, ifAbsent) => _data.putIfAbsent(key, ifAbsent);
+  addAll(Map other) => _data.addAll(other);
+  remove(key) => _data.remove(key);
+  void clear() {
+    _data.clear();
+  }
+
+  void forEach(void f(key, value)) {
+    _data.forEach(f);
+  }
+
+  Iterable<MapEntry> get entries => _data.entries;
+
+  void addEntries(Iterable<MapEntry> entries) {
+    _data.addEntries(entries);
+  }
+
+  Map<K, V> map<K, V>(MapEntry<K, V> transform(key, value)) =>
+      _data.map(transform);
+
+  void removeWhere(bool test(key, value)) {
+    _data.removeWhere(test);
+  }
+
+  Map<K, V> cast<K, V>() => _data.cast<K, V>();
+  update(key, update(value), {ifAbsent()}) =>
+      _data.update(key, update, ifAbsent: ifAbsent);
+
+  void updateAll(update(key, value)) {
+    _data.updateAll(update);
+  }
+
+  Iterable get keys => _data.keys;
+  Iterable get values => _data.values;
+  int get length => _data.length;
+  bool get isEmpty => _data.isEmpty;
+  bool get isNotEmpty => _data.isNotEmpty;
+
+  String toString() => 'HttpSession id:$id $_data';
+}
+
+// Private class used to manage all the active sessions. The sessions are stored
+// in two ways:
+//
+//  * In a map, mapping from ID to HttpSession.
+//  * In a linked list, used as a timeout queue.
+class _HttpSessionManager {
+  Map<String, _HttpSession> _sessions;
+  int _sessionTimeout = 20 * 60; // 20 mins.
+  _HttpSession _head;
+  _HttpSession _tail;
+  Timer _timer;
+
+  _HttpSessionManager() : _sessions = {};
+
+  String createSessionId() {
+    const int _KEY_LENGTH = 16; // 128 bits.
+    var data = _CryptoUtils.getRandomBytes(_KEY_LENGTH);
+    return _CryptoUtils.bytesToHex(data);
+  }
+
+  _HttpSession getSession(String id) => _sessions[id];
+
+  _HttpSession createSession() {
+    var id = createSessionId();
+    // TODO(ajohnsen): Consider adding a limit and throwing an exception.
+    // Should be very unlikely however.
+    while (_sessions.containsKey(id)) {
+      id = createSessionId();
+    }
+    var session = _sessions[id] = new _HttpSession(this, id);
+    _addToTimeoutQueue(session);
+    return session;
+  }
+
+  void set sessionTimeout(int timeout) {
+    _sessionTimeout = timeout;
+    _stopTimer();
+    _startTimer();
+  }
+
+  void close() {
+    _stopTimer();
+  }
+
+  void _bumpToEnd(_HttpSession session) {
+    _removeFromTimeoutQueue(session);
+    _addToTimeoutQueue(session);
+  }
+
+  void _addToTimeoutQueue(_HttpSession session) {
+    if (_head == null) {
+      assert(_tail == null);
+      _tail = _head = session;
+      _startTimer();
+    } else {
+      assert(_timer != null);
+      assert(_tail != null);
+      // Add to end.
+      _tail._next = session;
+      session._prev = _tail;
+      _tail = session;
+    }
+  }
+
+  void _removeFromTimeoutQueue(_HttpSession session) {
+    if (session._next != null) {
+      session._next._prev = session._prev;
+    }
+    if (session._prev != null) {
+      session._prev._next = session._next;
+    }
+    if (_head == session) {
+      // We removed the head element, start new timer.
+      _head = session._next;
+      _stopTimer();
+      _startTimer();
+    }
+    if (_tail == session) {
+      _tail = session._prev;
+    }
+    session._next = session._prev = null;
+  }
+
+  void _timerTimeout() {
+    _stopTimer(); // Clear timer.
+    assert(_head != null);
+    var session = _head;
+    session.destroy(); // Will remove the session from timeout queue and map.
+    if (session._timeoutCallback != null) {
+      session._timeoutCallback();
+    }
+  }
+
+  void _startTimer() {
+    assert(_timer == null);
+    if (_head != null) {
+      int seconds = new DateTime.now().difference(_head.lastSeen).inSeconds;
+      _timer = new Timer(
+          new Duration(seconds: _sessionTimeout - seconds), _timerTimeout);
+    }
+  }
+
+  void _stopTimer() {
+    if (_timer != null) {
+      _timer.cancel();
+      _timer = null;
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/_http/http_sources.gni b/sdk_nnbd/lib/_http/http_sources.gni
new file mode 100644
index 0000000..1ce36b4
--- /dev/null
+++ b/sdk_nnbd/lib/_http/http_sources.gni
@@ -0,0 +1,18 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+http_sdk_sources = [
+  "http.dart",
+
+  # The above file needs to be first if additional parts are added to the lib.
+  "crypto.dart",
+  "http_date.dart",
+  "http_headers.dart",
+  "http_impl.dart",
+  "http_parser.dart",
+  "http_session.dart",
+  "overrides.dart",
+  "websocket.dart",
+  "websocket_impl.dart",
+]
diff --git a/sdk_nnbd/lib/_http/overrides.dart b/sdk_nnbd/lib/_http/overrides.dart
new file mode 100644
index 0000000..7f9e689
--- /dev/null
+++ b/sdk_nnbd/lib/_http/overrides.dart
@@ -0,0 +1,118 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart._http;
+
+final _httpOverridesToken = new Object();
+
+const _asyncRunZoned = runZoned;
+
+/// This class facilitates overriding [HttpClient] with a mock implementation.
+/// It should be extended by another class in client code with overrides
+/// that construct a mock implementation. The implementation in this base class
+/// defaults to the actual [HttpClient] implementation. For example:
+///
+/// ```
+/// class MyHttpClient implements HttpClient {
+///   ...
+///   // An implementation of the HttpClient interface
+///   ...
+/// }
+///
+/// main() {
+///   HttpOverrides.runZoned(() {
+///     ...
+///     // Operations will use MyHttpClient instead of the real HttpClient
+///     // implementation whenever HttpClient is used.
+///     ...
+///   }, createHttpClient: (SecurityContext c) => new MyHttpClient(c));
+/// }
+/// ```
+abstract class HttpOverrides {
+  static HttpOverrides _global;
+
+  static HttpOverrides get current {
+    return Zone.current[_httpOverridesToken] ?? _global;
+  }
+
+  /// The [HttpOverrides] to use in the root [Zone].
+  ///
+  /// These are the [HttpOverrides] that will be used in the root Zone, and in
+  /// Zone's that do not set [HttpOverrides] and whose ancestors up to the root
+  /// Zone do not set [HttpOverrides].
+  static set global(HttpOverrides overrides) {
+    _global = overrides;
+  }
+
+  /// Runs [body] in a fresh [Zone] using the provided overrides.
+  static R runZoned<R>(R body(),
+      {HttpClient Function(SecurityContext) createHttpClient,
+      String Function(Uri uri, Map<String, String> environment)
+          findProxyFromEnvironment,
+      ZoneSpecification zoneSpecification,
+      Function onError}) {
+    HttpOverrides overrides =
+        new _HttpOverridesScope(createHttpClient, findProxyFromEnvironment);
+    return _asyncRunZoned<R>(body,
+        zoneValues: {_httpOverridesToken: overrides},
+        zoneSpecification: zoneSpecification,
+        onError: onError);
+  }
+
+  /// Runs [body] in a fresh [Zone] using the overrides found in [overrides].
+  ///
+  /// Note that [overrides] should be an instance of a class that extends
+  /// [HttpOverrides].
+  static R runWithHttpOverrides<R>(R body(), HttpOverrides overrides,
+      {ZoneSpecification zoneSpecification, Function onError}) {
+    return _asyncRunZoned<R>(body,
+        zoneValues: {_httpOverridesToken: overrides},
+        zoneSpecification: zoneSpecification,
+        onError: onError);
+  }
+
+  /// Returns a new [HttpClient] using the given [context].
+  ///
+  /// When this override is installed, this function overrides the behavior of
+  /// `new HttpClient`.
+  HttpClient createHttpClient(SecurityContext context) {
+    return new _HttpClient(context);
+  }
+
+  /// Resolves the proxy server to be used for HTTP connections.
+  ///
+  /// When this override is installed, this function overrides the behavior of
+  /// `HttpClient.findProxyFromEnvironment`.
+  String findProxyFromEnvironment(Uri url, Map<String, String> environment) {
+    return _HttpClient._findProxyFromEnvironment(url, environment);
+  }
+}
+
+class _HttpOverridesScope extends HttpOverrides {
+  final HttpOverrides _previous = HttpOverrides.current;
+
+  final HttpClient Function(SecurityContext) _createHttpClient;
+  final String Function(Uri uri, Map<String, String> environment)
+      _findProxyFromEnvironment;
+
+  _HttpOverridesScope(this._createHttpClient, this._findProxyFromEnvironment);
+
+  @override
+  HttpClient createHttpClient(SecurityContext context) {
+    if (_createHttpClient != null) return _createHttpClient(context);
+    if (_previous != null) return _previous.createHttpClient(context);
+    return super.createHttpClient(context);
+  }
+
+  @override
+  String findProxyFromEnvironment(Uri url, Map<String, String> environment) {
+    if (_findProxyFromEnvironment != null) {
+      return _findProxyFromEnvironment(url, environment);
+    }
+    if (_previous != null) {
+      return _previous.findProxyFromEnvironment(url, environment);
+    }
+    return super.findProxyFromEnvironment(url, environment);
+  }
+}
diff --git a/sdk_nnbd/lib/_http/websocket.dart b/sdk_nnbd/lib/_http/websocket.dart
new file mode 100644
index 0000000..5a949af
--- /dev/null
+++ b/sdk_nnbd/lib/_http/websocket.dart
@@ -0,0 +1,497 @@
+// 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 dart._http;
+
+/**
+ * WebSocket status codes used when closing a WebSocket connection.
+ */
+abstract class WebSocketStatus {
+  static const int normalClosure = 1000;
+  static const int goingAway = 1001;
+  static const int protocolError = 1002;
+  static const int unsupportedData = 1003;
+  static const int reserved1004 = 1004;
+  static const int noStatusReceived = 1005;
+  static const int abnormalClosure = 1006;
+  static const int invalidFramePayloadData = 1007;
+  static const int policyViolation = 1008;
+  static const int messageTooBig = 1009;
+  static const int missingMandatoryExtension = 1010;
+  static const int internalServerError = 1011;
+  static const int reserved1015 = 1015;
+
+  @Deprecated("Use normalClosure instead")
+  static const int NORMAL_CLOSURE = normalClosure;
+  @Deprecated("Use goingAway instead")
+  static const int GOING_AWAY = goingAway;
+  @Deprecated("Use protocolError instead")
+  static const int PROTOCOL_ERROR = protocolError;
+  @Deprecated("Use unsupportedData instead")
+  static const int UNSUPPORTED_DATA = unsupportedData;
+  @Deprecated("Use reserved1004 instead")
+  static const int RESERVED_1004 = reserved1004;
+  @Deprecated("Use noStatusReceived instead")
+  static const int NO_STATUS_RECEIVED = noStatusReceived;
+  @Deprecated("Use abnormalClosure instead")
+  static const int ABNORMAL_CLOSURE = abnormalClosure;
+  @Deprecated("Use invalidFramePayloadData instead")
+  static const int INVALID_FRAME_PAYLOAD_DATA = invalidFramePayloadData;
+  @Deprecated("Use policyViolation instead")
+  static const int POLICY_VIOLATION = policyViolation;
+  @Deprecated("Use messageTooBig instead")
+  static const int MESSAGE_TOO_BIG = messageTooBig;
+  @Deprecated("Use missingMandatoryExtension instead")
+  static const int MISSING_MANDATORY_EXTENSION = missingMandatoryExtension;
+  @Deprecated("Use internalServerError instead")
+  static const int INTERNAL_SERVER_ERROR = internalServerError;
+  @Deprecated("Use reserved1015 instead")
+  static const int RESERVED_1015 = reserved1015;
+}
+
+/// Options controlling compression in a [WebSocket].
+///
+/// A [CompressionOptions] instance can be passed to [WebSocket.connect], or
+/// used in other similar places where [WebSocket] compression is configured.
+///
+/// In most cases the default [compressionDefault] is sufficient, but in some
+/// situations, it might be desirable to use different compression parameters,
+/// for example to preserve memory on small devices.
+class CompressionOptions {
+  /// Default [WebSocket] compression configuration.
+  ///
+  /// Enables compression with default window sizes and no reuse. This is the
+  /// default options used by [WebSocket.connect] if no [CompressionOptions] is
+  /// supplied.
+  ///
+  /// * `clientNoContextTakeover`: false
+  /// * `serverNoContextTakeover`: false
+  /// * `clientMaxWindowBits`: null (default maximal window size of 15 bits)
+  /// * `serverMaxWindowBits`: null (default maximal window size of 15 bits)
+  static const CompressionOptions compressionDefault =
+      const CompressionOptions();
+  @Deprecated("Use compressionDefault instead")
+  static const CompressionOptions DEFAULT = compressionDefault;
+
+  /// No-compression configuration.
+  ///
+  /// Disables compression when used as compression configuration for a
+  /// [WebSocket].
+  static const CompressionOptions compressionOff =
+      const CompressionOptions(enabled: false);
+  @Deprecated("Use compressionOff instead")
+  static const CompressionOptions OFF = compressionOff;
+
+  /// Whether the client will reuse its compression instances.
+  final bool clientNoContextTakeover;
+
+  /// Whether the server will reuse its compression instances.
+  final bool serverNoContextTakeover;
+
+  /// The maximal window size bit count requested by the client.
+  ///
+  /// The windows size for the compression is always a power of two, so the
+  /// number of bits precisely determines the window size.
+  ///
+  /// If set to `null`, the client has no preference, and the compression can
+  /// use up to its default maximum window size of 15 bits depending on the
+  /// server's preference.
+  final int clientMaxWindowBits;
+
+  /// The maximal window size bit count requested by the server.
+  ///
+  /// The windows size for the compression is always a power of two, so the
+  /// number of bits precisely determines the window size.
+  ///
+  /// If set to `null`, the server has no preference, and the compression can
+  /// use up to its default maximum window size of 15 bits depending on the
+  /// client's preference.
+  final int serverMaxWindowBits;
+
+  /// Whether WebSocket compression is enabled.
+  ///
+  /// If not enabled, the remaining fields have no effect, and the
+  /// [compressionOff] instance can, and should, be reused instead of creating a
+  /// new instance with compression disabled.
+  final bool enabled;
+
+  const CompressionOptions(
+      {this.clientNoContextTakeover = false,
+      this.serverNoContextTakeover = false,
+      this.clientMaxWindowBits,
+      this.serverMaxWindowBits,
+      this.enabled = true});
+
+  /// Parses list of requested server headers to return server compression
+  /// response headers.
+  ///
+  /// Uses [serverMaxWindowBits] value if set, otherwise will attempt to use
+  /// value from headers. Defaults to [WebSocket.DEFAULT_WINDOW_BITS]. Returns a
+  /// [_CompressionMaxWindowBits] object which contains the response headers and
+  /// negotiated max window bits.
+  _CompressionMaxWindowBits _createServerResponseHeader(HeaderValue requested) {
+    var info = new _CompressionMaxWindowBits();
+
+    int mwb;
+    String part;
+    if (requested?.parameters != null) {
+      part = requested.parameters[_serverMaxWindowBits];
+    }
+    if (part != null) {
+      if (part.length >= 2 && part.startsWith('0')) {
+        throw new ArgumentError("Illegal 0 padding on value.");
+      } else {
+        mwb = serverMaxWindowBits == null
+            ? int.parse(part,
+                onError: (source) => _WebSocketImpl.DEFAULT_WINDOW_BITS)
+            : serverMaxWindowBits;
+        info.headerValue = "; server_max_window_bits=${mwb}";
+        info.maxWindowBits = mwb;
+      }
+    } else {
+      info.headerValue = "";
+      info.maxWindowBits = _WebSocketImpl.DEFAULT_WINDOW_BITS;
+    }
+    return info;
+  }
+
+  /// Returns default values for client compression request headers.
+  String _createClientRequestHeader(HeaderValue requested, int size) {
+    var info = "";
+
+    // If responding to a valid request, specify size
+    if (requested != null) {
+      info = "; client_max_window_bits=$size";
+    } else {
+      // Client request. Specify default
+      if (clientMaxWindowBits == null) {
+        info = "; client_max_window_bits";
+      } else {
+        info = "; client_max_window_bits=$clientMaxWindowBits";
+      }
+      if (serverMaxWindowBits != null) {
+        info += "; server_max_window_bits=$serverMaxWindowBits";
+      }
+    }
+
+    return info;
+  }
+
+  /// Create a Compression Header.
+  ///
+  /// If [requested] is null or contains client request headers, returns Client
+  /// compression request headers with default settings for
+  /// `client_max_window_bits` header value.  If [requested] contains server
+  /// response headers this method returns a Server compression response header
+  /// negotiating the max window bits for both client and server as requested
+  /// `server_max_window_bits` value.  This method returns a
+  /// [_CompressionMaxWindowBits] object with the response headers and
+  /// negotiated `maxWindowBits` value.
+  _CompressionMaxWindowBits _createHeader([HeaderValue requested]) {
+    var info = new _CompressionMaxWindowBits("", 0);
+    if (!enabled) {
+      return info;
+    }
+
+    info.headerValue = _WebSocketImpl.PER_MESSAGE_DEFLATE;
+
+    if (clientNoContextTakeover &&
+        (requested == null ||
+            (requested != null &&
+                requested.parameters.containsKey(_clientNoContextTakeover)))) {
+      info.headerValue += "; client_no_context_takeover";
+    }
+
+    if (serverNoContextTakeover &&
+        (requested == null ||
+            (requested != null &&
+                requested.parameters.containsKey(_serverNoContextTakeover)))) {
+      info.headerValue += "; server_no_context_takeover";
+    }
+
+    var headerList = _createServerResponseHeader(requested);
+    info.headerValue += headerList.headerValue;
+    info.maxWindowBits = headerList.maxWindowBits;
+
+    info.headerValue +=
+        _createClientRequestHeader(requested, info.maxWindowBits);
+
+    return info;
+  }
+}
+
+/**
+ * The [WebSocketTransformer] provides the ability to upgrade a
+ * [HttpRequest] to a [WebSocket] connection. It supports both
+ * upgrading a single [HttpRequest] and upgrading a stream of
+ * [HttpRequest]s.
+ *
+ * To upgrade a single [HttpRequest] use the static [upgrade] method.
+ *
+ *     HttpServer server;
+ *     server.listen((request) {
+ *       if (...) {
+ *         WebSocketTransformer.upgrade(request).then((websocket) {
+ *           ...
+ *         });
+ *       } else {
+ *         // Do normal HTTP request processing.
+ *       }
+ *     });
+ *
+ * To transform a stream of [HttpRequest] events as it implements a
+ * stream transformer that transforms a stream of HttpRequest into a
+ * stream of WebSockets by upgrading each HttpRequest from the HTTP or
+ * HTTPS server, to the WebSocket protocol.
+ *
+ *     server.transform(new WebSocketTransformer()).listen((webSocket) => ...);
+ *
+ * This transformer strives to implement WebSockets as specified by RFC6455.
+ */
+abstract class WebSocketTransformer
+    implements StreamTransformer<HttpRequest, WebSocket> {
+  /**
+   * Create a new [WebSocketTransformer].
+   *
+   * If [protocolSelector] is provided, [protocolSelector] will be called to
+   * select what protocol to use, if any were provided by the client.
+   * [protocolSelector] is should return either a [String] or a [Future]
+   * completing with a [String]. The [String] must exist in the list of
+   * protocols.
+   *
+   * If [compression] is provided, the [WebSocket] created will be configured
+   * to negotiate with the specified [CompressionOptions]. If none is specified
+   * then the [WebSocket] will be created with the default [CompressionOptions].
+   */
+  factory WebSocketTransformer(
+      {/*String|Future<String>*/ protocolSelector(List<String> protocols),
+      CompressionOptions compression: CompressionOptions.compressionDefault}) {
+    return new _WebSocketTransformerImpl(protocolSelector, compression);
+  }
+
+  /**
+   * Upgrades a [HttpRequest] to a [WebSocket] connection. If the
+   * request is not a valid WebSocket upgrade request an HTTP response
+   * with status code 500 will be returned. Otherwise the returned
+   * future will complete with the [WebSocket] when the upgrade process
+   * is complete.
+   *
+   * If [protocolSelector] is provided, [protocolSelector] will be called to
+   * select what protocol to use, if any were provided by the client.
+   * [protocolSelector] is should return either a [String] or a [Future]
+   * completing with a [String]. The [String] must exist in the list of
+   * protocols.
+   *
+   * If [compression] is provided, the [WebSocket] created will be configured
+   * to negotiate with the specified [CompressionOptions]. If none is specified
+   * then the [WebSocket] will be created with the default [CompressionOptions].
+   */
+  static Future<WebSocket> upgrade(HttpRequest request,
+      {protocolSelector(List<String> protocols),
+      CompressionOptions compression: CompressionOptions.compressionDefault}) {
+    return _WebSocketTransformerImpl._upgrade(
+        request, protocolSelector, compression);
+  }
+
+  /**
+   * Checks whether the request is a valid WebSocket upgrade request.
+   */
+  static bool isUpgradeRequest(HttpRequest request) {
+    return _WebSocketTransformerImpl._isUpgradeRequest(request);
+  }
+}
+
+/**
+ * A two-way HTTP communication object for client or server applications.
+ *
+ * The stream exposes the messages received. A text message will be of type
+ * `String` and a binary message will be of type `List<int>`.
+ */
+abstract class WebSocket
+    implements
+        Stream<dynamic /*String|List<int>*/ >,
+        StreamSink<dynamic /*String|List<int>*/ > {
+  /**
+   * Possible states of the connection.
+   */
+  static const int connecting = 0;
+  static const int open = 1;
+  static const int closing = 2;
+  static const int closed = 3;
+
+  @Deprecated("Use connecting instead")
+  static const int CONNECTING = connecting;
+  @Deprecated("Use open instead")
+  static const int OPEN = open;
+  @Deprecated("Use closing instead")
+  static const int CLOSING = closing;
+  @Deprecated("Use closed instead")
+  static const int CLOSED = closed;
+
+  /**
+   * Set and get the interval for sending ping signals. If a ping message is not
+   * answered by a pong message from the peer, the `WebSocket` is assumed
+   * disconnected and the connection is closed with a
+   * [WebSocketStatus.GOING_AWAY] close code. When a ping signal is sent, the
+   * pong message must be received within [pingInterval].
+   *
+   * There are never two outstanding pings at any given time, and the next ping
+   * timer starts when the pong is received.
+   *
+   * Set the [pingInterval] to `null` to disable sending ping messages.
+   *
+   * The default value is `null`.
+   */
+  Duration pingInterval;
+
+  /**
+   * Create a new WebSocket connection. The URL supplied in [url]
+   * must use the scheme `ws` or `wss`.
+   *
+   * The [protocols] argument is specifying the subprotocols the
+   * client is willing to speak.
+   *
+   * The [headers] argument is specifying additional HTTP headers for
+   * setting up the connection. This would typically be the `Origin`
+   * header and potentially cookies. The keys of the map are the header
+   * fields and the values are either String or List<String>.
+   *
+   * If [headers] is provided, there are a number of headers
+   * which are controlled by the WebSocket connection process. These
+   * headers are:
+   *
+   *   - `connection`
+   *   - `sec-websocket-key`
+   *   - `sec-websocket-protocol`
+   *   - `sec-websocket-version`
+   *   - `upgrade`
+   *
+   * If any of these are passed in the `headers` map they will be ignored.
+   *
+   * If the `url` contains user information this will be passed as basic
+   * authentication when setting up the connection.
+   */
+  static Future<WebSocket> connect(String url,
+          {Iterable<String> protocols,
+          Map<String, dynamic> headers,
+          CompressionOptions compression:
+              CompressionOptions.compressionDefault}) =>
+      _WebSocketImpl.connect(url, protocols, headers, compression: compression);
+
+  @Deprecated('This constructor will be removed in Dart 2.0. Use `implements`'
+      ' instead of `extends` if implementing this abstract class.')
+  WebSocket();
+
+  /**
+   * Creates a WebSocket from an already-upgraded socket.
+   *
+   * The initial WebSocket handshake must have occurred prior to this call. A
+   * WebSocket client can automatically perform the handshake using
+   * [WebSocket.connect], while a server can do so using
+   * [WebSocketTransformer.upgrade]. To manually upgrade an [HttpRequest],
+   * [HttpResponse.detachSocket] may be called.
+   *
+   * [protocol] should be the protocol negotiated by this handshake, if any.
+   *
+   * [serverSide] must be passed explicitly. If it's `false`, the WebSocket will
+   * act as the client and mask the messages it sends. If it's `true`, it will
+   * act as the server and will not mask its messages.
+   *
+   * If [compression] is provided, the [WebSocket] created will be configured
+   * to negotiate with the specified [CompressionOptions]. If none is specified
+   * then the [WebSocket] will be created with the default [CompressionOptions].
+   */
+  factory WebSocket.fromUpgradedSocket(Socket socket,
+      {String protocol,
+      bool serverSide,
+      CompressionOptions compression: CompressionOptions.compressionDefault}) {
+    if (serverSide == null) {
+      throw new ArgumentError("The serverSide argument must be passed "
+          "explicitly to WebSocket.fromUpgradedSocket.");
+    }
+    return new _WebSocketImpl._fromSocket(
+        socket, protocol, compression, serverSide);
+  }
+
+  /**
+   * Returns the current state of the connection.
+   */
+  int get readyState;
+
+  /**
+   * The extensions property is initially the empty string. After the
+   * WebSocket connection is established this string reflects the
+   * extensions used by the server.
+   */
+  String get extensions;
+
+  /**
+   * The protocol property is initially the empty string. After the
+   * WebSocket connection is established the value is the subprotocol
+   * selected by the server. If no subprotocol is negotiated the
+   * value will remain [:null:].
+   */
+  String get protocol;
+
+  /**
+   * The close code set when the WebSocket connection is closed. If
+   * there is no close code available this property will be [:null:]
+   */
+  int get closeCode;
+
+  /**
+   * The close reason set when the WebSocket connection is closed. If
+   * there is no close reason available this property will be [:null:]
+   */
+  String get closeReason;
+
+  /**
+   * Closes the WebSocket connection. Set the optional [code] and [reason]
+   * arguments to send close information to the remote peer. If they are
+   * omitted, the peer will see [WebSocketStatus.NO_STATUS_RECEIVED] code
+   * with no reason.
+   */
+  Future close([int code, String reason]);
+
+  /**
+   * Sends data on the WebSocket connection. The data in [data] must
+   * be either a `String`, or a `List<int>` holding bytes.
+   */
+  void add(/*String|List<int>*/ data);
+
+  /**
+   * Sends data from a stream on WebSocket connection. Each data event from
+   * [stream] will be send as a single WebSocket frame. The data from [stream]
+   * must be either `String`s, or `List<int>`s holding bytes.
+   */
+  Future addStream(Stream stream);
+
+  /**
+   * Sends a text message with the text represented by [bytes].
+   *
+   * The [bytes] should be valid UTF-8 encoded Unicode characters. If they are
+   * not, the receiving end will close the connection.
+   */
+  void addUtf8Text(List<int> bytes);
+
+  /**
+   * Gets the user agent used for WebSocket connections.
+   */
+  static String get userAgent => _WebSocketImpl.userAgent;
+
+  /**
+   * Sets the user agent to use for WebSocket connections.
+   */
+  static set userAgent(String userAgent) {
+    _WebSocketImpl.userAgent = userAgent;
+  }
+}
+
+class WebSocketException implements IOException {
+  final String message;
+
+  const WebSocketException([this.message = ""]);
+
+  String toString() => "WebSocketException: $message";
+}
diff --git a/sdk_nnbd/lib/_http/websocket_impl.dart b/sdk_nnbd/lib/_http/websocket_impl.dart
new file mode 100644
index 0000000..8750ccc
--- /dev/null
+++ b/sdk_nnbd/lib/_http/websocket_impl.dart
@@ -0,0 +1,1317 @@
+// 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 dart._http;
+
+const String _webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+const String _clientNoContextTakeover = "client_no_context_takeover";
+const String _serverNoContextTakeover = "server_no_context_takeover";
+const String _clientMaxWindowBits = "client_max_window_bits";
+const String _serverMaxWindowBits = "server_max_window_bits";
+
+// Matches _WebSocketOpcode.
+class _WebSocketMessageType {
+  static const int NONE = 0;
+  static const int TEXT = 1;
+  static const int BINARY = 2;
+}
+
+class _WebSocketOpcode {
+  static const int CONTINUATION = 0;
+  static const int TEXT = 1;
+  static const int BINARY = 2;
+  static const int RESERVED_3 = 3;
+  static const int RESERVED_4 = 4;
+  static const int RESERVED_5 = 5;
+  static const int RESERVED_6 = 6;
+  static const int RESERVED_7 = 7;
+  static const int CLOSE = 8;
+  static const int PING = 9;
+  static const int PONG = 10;
+  static const int RESERVED_B = 11;
+  static const int RESERVED_C = 12;
+  static const int RESERVED_D = 13;
+  static const int RESERVED_E = 14;
+  static const int RESERVED_F = 15;
+}
+
+class _EncodedString {
+  final List<int> bytes;
+  _EncodedString(this.bytes);
+}
+
+/**
+ *  Stores the header and integer value derived from negotiation of
+ *  client_max_window_bits and server_max_window_bits. headerValue will be
+ *  set in the Websocket response headers.
+ */
+class _CompressionMaxWindowBits {
+  String headerValue;
+  int maxWindowBits;
+  _CompressionMaxWindowBits([this.headerValue, this.maxWindowBits]);
+  String toString() => headerValue;
+}
+
+/**
+ * The web socket protocol transformer handles the protocol byte stream
+ * which is supplied through the `handleData`. As the protocol is processed,
+ * it'll output frame data as either a List<int> or String.
+ *
+ * Important information about usage: Be sure you use cancelOnError, so the
+ * socket will be closed when the processor encounter an error. Not using it
+ * will lead to undefined behaviour.
+ */
+class _WebSocketProtocolTransformer extends StreamTransformerBase<List<int>,
+        dynamic /*List<int>|_WebSocketPing|_WebSocketPong*/ >
+    implements EventSink<List<int>> {
+  static const int START = 0;
+  static const int LEN_FIRST = 1;
+  static const int LEN_REST = 2;
+  static const int MASK = 3;
+  static const int PAYLOAD = 4;
+  static const int CLOSED = 5;
+  static const int FAILURE = 6;
+  static const int FIN = 0x80;
+  static const int RSV1 = 0x40;
+  static const int RSV2 = 0x20;
+  static const int RSV3 = 0x10;
+  static const int OPCODE = 0xF;
+
+  int _state = START;
+  bool _fin = false;
+  bool _compressed = false;
+  int _opcode = -1;
+  int _len = -1;
+  bool _masked = false;
+  int _remainingLenBytes = -1;
+  int _remainingMaskingKeyBytes = 4;
+  int _remainingPayloadBytes = -1;
+  int _unmaskingIndex = 0;
+  int _currentMessageType = _WebSocketMessageType.NONE;
+  int closeCode = WebSocketStatus.NO_STATUS_RECEIVED;
+  String closeReason = "";
+
+  EventSink<dynamic /*List<int>|_WebSocketPing|_WebSocketPong*/ > _eventSink;
+
+  final bool _serverSide;
+  final List _maskingBytes = new List(4);
+  final BytesBuilder _payload = new BytesBuilder(copy: false);
+
+  _WebSocketPerMessageDeflate _deflate;
+  _WebSocketProtocolTransformer([this._serverSide = false, this._deflate]);
+
+  Stream<dynamic /*List<int>|_WebSocketPing|_WebSocketPong*/ > bind(
+      Stream<List<int>> stream) {
+    return new Stream.eventTransformed(stream, (EventSink eventSink) {
+      if (_eventSink != null) {
+        throw new StateError("WebSocket transformer already used.");
+      }
+      _eventSink = eventSink;
+      return this;
+    });
+  }
+
+  void addError(Object error, [StackTrace stackTrace]) {
+    _eventSink.addError(error, stackTrace);
+  }
+
+  void close() {
+    _eventSink.close();
+  }
+
+  /**
+   * Process data received from the underlying communication channel.
+   */
+  void add(List<int> bytes) {
+    var buffer = bytes is Uint8List ? bytes : new Uint8List.fromList(bytes);
+    int index = 0;
+    int lastIndex = buffer.length;
+    if (_state == CLOSED) {
+      throw new WebSocketException("Data on closed connection");
+    }
+    if (_state == FAILURE) {
+      throw new WebSocketException("Data on failed connection");
+    }
+    while ((index < lastIndex) && _state != CLOSED && _state != FAILURE) {
+      int byte = buffer[index];
+      if (_state <= LEN_REST) {
+        if (_state == START) {
+          _fin = (byte & FIN) != 0;
+
+          if ((byte & (RSV2 | RSV3)) != 0) {
+            // The RSV2, RSV3 bits must both be zero.
+            throw new WebSocketException("Protocol error");
+          }
+
+          _opcode = (byte & OPCODE);
+
+          if (_opcode != _WebSocketOpcode.CONTINUATION) {
+            if ((byte & RSV1) != 0) {
+              _compressed = true;
+            } else {
+              _compressed = false;
+            }
+          }
+
+          if (_opcode <= _WebSocketOpcode.BINARY) {
+            if (_opcode == _WebSocketOpcode.CONTINUATION) {
+              if (_currentMessageType == _WebSocketMessageType.NONE) {
+                throw new WebSocketException("Protocol error");
+              }
+            } else {
+              assert(_opcode == _WebSocketOpcode.TEXT ||
+                  _opcode == _WebSocketOpcode.BINARY);
+              if (_currentMessageType != _WebSocketMessageType.NONE) {
+                throw new WebSocketException("Protocol error");
+              }
+              _currentMessageType = _opcode;
+            }
+          } else if (_opcode >= _WebSocketOpcode.CLOSE &&
+              _opcode <= _WebSocketOpcode.PONG) {
+            // Control frames cannot be fragmented.
+            if (!_fin) throw new WebSocketException("Protocol error");
+          } else {
+            throw new WebSocketException("Protocol error");
+          }
+          _state = LEN_FIRST;
+        } else if (_state == LEN_FIRST) {
+          _masked = (byte & 0x80) != 0;
+          _len = byte & 0x7F;
+          if (_isControlFrame() && _len > 125) {
+            throw new WebSocketException("Protocol error");
+          }
+          if (_len == 126) {
+            _len = 0;
+            _remainingLenBytes = 2;
+            _state = LEN_REST;
+          } else if (_len == 127) {
+            _len = 0;
+            _remainingLenBytes = 8;
+            _state = LEN_REST;
+          } else {
+            assert(_len < 126);
+            _lengthDone();
+          }
+        } else {
+          assert(_state == LEN_REST);
+          _len = _len << 8 | byte;
+          _remainingLenBytes--;
+          if (_remainingLenBytes == 0) {
+            _lengthDone();
+          }
+        }
+      } else {
+        if (_state == MASK) {
+          _maskingBytes[4 - _remainingMaskingKeyBytes--] = byte;
+          if (_remainingMaskingKeyBytes == 0) {
+            _maskDone();
+          }
+        } else {
+          assert(_state == PAYLOAD);
+          // The payload is not handled one byte at a time but in blocks.
+          int payloadLength = min(lastIndex - index, _remainingPayloadBytes);
+          _remainingPayloadBytes -= payloadLength;
+          // Unmask payload if masked.
+          if (_masked) {
+            _unmask(index, payloadLength, buffer);
+          }
+          // Control frame and data frame share _payloads.
+          _payload.add(new Uint8List.view(buffer.buffer, index, payloadLength));
+          index += payloadLength;
+          if (_isControlFrame()) {
+            if (_remainingPayloadBytes == 0) _controlFrameEnd();
+          } else {
+            if (_currentMessageType != _WebSocketMessageType.TEXT &&
+                _currentMessageType != _WebSocketMessageType.BINARY) {
+              throw new WebSocketException("Protocol error");
+            }
+            if (_remainingPayloadBytes == 0) _messageFrameEnd();
+          }
+
+          // Hack - as we always do index++ below.
+          index--;
+        }
+      }
+
+      // Move to the next byte.
+      index++;
+    }
+  }
+
+  void _unmask(int index, int length, Uint8List buffer) {
+    const int BLOCK_SIZE = 16;
+    // Skip Int32x4-version if message is small.
+    if (length >= BLOCK_SIZE) {
+      // Start by aligning to 16 bytes.
+      final int startOffset = BLOCK_SIZE - (index & 15);
+      final int end = index + startOffset;
+      for (int i = index; i < end; i++) {
+        buffer[i] ^= _maskingBytes[_unmaskingIndex++ & 3];
+      }
+      index += startOffset;
+      length -= startOffset;
+      final int blockCount = length ~/ BLOCK_SIZE;
+      if (blockCount > 0) {
+        // Create mask block.
+        int mask = 0;
+        for (int i = 3; i >= 0; i--) {
+          mask = (mask << 8) | _maskingBytes[(_unmaskingIndex + i) & 3];
+        }
+        Int32x4 blockMask = new Int32x4(mask, mask, mask, mask);
+        Int32x4List blockBuffer =
+            new Int32x4List.view(buffer.buffer, index, blockCount);
+        for (int i = 0; i < blockBuffer.length; i++) {
+          blockBuffer[i] ^= blockMask;
+        }
+        final int bytes = blockCount * BLOCK_SIZE;
+        index += bytes;
+        length -= bytes;
+      }
+    }
+    // Handle end.
+    final int end = index + length;
+    for (int i = index; i < end; i++) {
+      buffer[i] ^= _maskingBytes[_unmaskingIndex++ & 3];
+    }
+  }
+
+  void _lengthDone() {
+    if (_masked) {
+      if (!_serverSide) {
+        throw new WebSocketException("Received masked frame from server");
+      }
+      _state = MASK;
+    } else {
+      if (_serverSide) {
+        throw new WebSocketException("Received unmasked frame from client");
+      }
+      _remainingPayloadBytes = _len;
+      _startPayload();
+    }
+  }
+
+  void _maskDone() {
+    _remainingPayloadBytes = _len;
+    _startPayload();
+  }
+
+  void _startPayload() {
+    // If there is no actual payload perform perform callbacks without
+    // going through the PAYLOAD state.
+    if (_remainingPayloadBytes == 0) {
+      if (_isControlFrame()) {
+        switch (_opcode) {
+          case _WebSocketOpcode.CLOSE:
+            _state = CLOSED;
+            _eventSink.close();
+            break;
+          case _WebSocketOpcode.PING:
+            _eventSink.add(new _WebSocketPing());
+            break;
+          case _WebSocketOpcode.PONG:
+            _eventSink.add(new _WebSocketPong());
+            break;
+        }
+        _prepareForNextFrame();
+      } else {
+        _messageFrameEnd();
+      }
+    } else {
+      _state = PAYLOAD;
+    }
+  }
+
+  void _messageFrameEnd() {
+    if (_fin) {
+      var bytes = _payload.takeBytes();
+      if (_deflate != null && _compressed) {
+        bytes = _deflate.processIncomingMessage(bytes);
+      }
+
+      switch (_currentMessageType) {
+        case _WebSocketMessageType.TEXT:
+          _eventSink.add(utf8.decode(bytes));
+          break;
+        case _WebSocketMessageType.BINARY:
+          _eventSink.add(bytes);
+          break;
+      }
+      _currentMessageType = _WebSocketMessageType.NONE;
+    }
+    _prepareForNextFrame();
+  }
+
+  void _controlFrameEnd() {
+    switch (_opcode) {
+      case _WebSocketOpcode.CLOSE:
+        closeCode = WebSocketStatus.NO_STATUS_RECEIVED;
+        var payload = _payload.takeBytes();
+        if (payload.length > 0) {
+          if (payload.length == 1) {
+            throw new WebSocketException("Protocol error");
+          }
+          closeCode = payload[0] << 8 | payload[1];
+          if (closeCode == WebSocketStatus.NO_STATUS_RECEIVED) {
+            throw new WebSocketException("Protocol error");
+          }
+          if (payload.length > 2) {
+            closeReason = utf8.decode(payload.sublist(2));
+          }
+        }
+        _state = CLOSED;
+        _eventSink.close();
+        break;
+
+      case _WebSocketOpcode.PING:
+        _eventSink.add(new _WebSocketPing(_payload.takeBytes()));
+        break;
+
+      case _WebSocketOpcode.PONG:
+        _eventSink.add(new _WebSocketPong(_payload.takeBytes()));
+        break;
+    }
+    _prepareForNextFrame();
+  }
+
+  bool _isControlFrame() {
+    return _opcode == _WebSocketOpcode.CLOSE ||
+        _opcode == _WebSocketOpcode.PING ||
+        _opcode == _WebSocketOpcode.PONG;
+  }
+
+  void _prepareForNextFrame() {
+    if (_state != CLOSED && _state != FAILURE) _state = START;
+    _fin = false;
+    _opcode = -1;
+    _len = -1;
+    _remainingLenBytes = -1;
+    _remainingMaskingKeyBytes = 4;
+    _remainingPayloadBytes = -1;
+    _unmaskingIndex = 0;
+  }
+}
+
+class _WebSocketPing {
+  final List<int> payload;
+  _WebSocketPing([this.payload = null]);
+}
+
+class _WebSocketPong {
+  final List<int> payload;
+  _WebSocketPong([this.payload = null]);
+}
+
+typedef /*String|Future<String>*/ _ProtocolSelector(List<String> protocols);
+
+class _WebSocketTransformerImpl
+    extends StreamTransformerBase<HttpRequest, WebSocket>
+    implements WebSocketTransformer {
+  final StreamController<WebSocket> _controller =
+      new StreamController<WebSocket>(sync: true);
+  final _ProtocolSelector _protocolSelector;
+  final CompressionOptions _compression;
+
+  _WebSocketTransformerImpl(this._protocolSelector, this._compression);
+
+  Stream<WebSocket> bind(Stream<HttpRequest> stream) {
+    stream.listen((request) {
+      _upgrade(request, _protocolSelector, _compression)
+          .then((WebSocket webSocket) => _controller.add(webSocket))
+          .catchError(_controller.addError);
+    }, onDone: () {
+      _controller.close();
+    });
+
+    return _controller.stream;
+  }
+
+  static List<String> _tokenizeFieldValue(String headerValue) {
+    List<String> tokens = new List<String>();
+    int start = 0;
+    int index = 0;
+    while (index < headerValue.length) {
+      if (headerValue[index] == ",") {
+        tokens.add(headerValue.substring(start, index));
+        start = index + 1;
+      } else if (headerValue[index] == " " || headerValue[index] == "\t") {
+        start++;
+      }
+      index++;
+    }
+    tokens.add(headerValue.substring(start, index));
+    return tokens;
+  }
+
+  static Future<WebSocket> _upgrade(HttpRequest request,
+      _ProtocolSelector _protocolSelector, CompressionOptions compression) {
+    var response = request.response;
+    if (!_isUpgradeRequest(request)) {
+      // Send error response.
+      response
+        ..statusCode = HttpStatus.badRequest
+        ..close();
+      return new Future.error(
+          new WebSocketException("Invalid WebSocket upgrade request"));
+    }
+
+    Future<WebSocket> upgrade(String protocol) {
+      // Send the upgrade response.
+      response
+        ..statusCode = HttpStatus.switchingProtocols
+        ..headers.add(HttpHeaders.connectionHeader, "Upgrade")
+        ..headers.add(HttpHeaders.upgradeHeader, "websocket");
+      String key = request.headers.value("Sec-WebSocket-Key");
+      _SHA1 sha1 = new _SHA1();
+      sha1.add("$key$_webSocketGUID".codeUnits);
+      String accept = _CryptoUtils.bytesToBase64(sha1.close());
+      response.headers.add("Sec-WebSocket-Accept", accept);
+      if (protocol != null) {
+        response.headers.add("Sec-WebSocket-Protocol", protocol);
+      }
+
+      var deflate = _negotiateCompression(request, response, compression);
+
+      response.headers.contentLength = 0;
+      return response.detachSocket().then<WebSocket>((socket) =>
+          new _WebSocketImpl._fromSocket(
+              socket, protocol, compression, true, deflate));
+    }
+
+    var protocols = request.headers['Sec-WebSocket-Protocol'];
+    if (protocols != null && _protocolSelector != null) {
+      // The suggested protocols can be spread over multiple lines, each
+      // consisting of multiple protocols. To unify all of them, first join
+      // the lists with ', ' and then tokenize.
+      protocols = _tokenizeFieldValue(protocols.join(', '));
+      return new Future<String>(() => _protocolSelector(protocols))
+          .then<String>((protocol) {
+        if (protocols.indexOf(protocol) < 0) {
+          throw new WebSocketException(
+              "Selected protocol is not in the list of available protocols");
+        }
+        return protocol;
+      }).catchError((error) {
+        response
+          ..statusCode = HttpStatus.internalServerError
+          ..close();
+        throw error;
+      }).then<WebSocket>(upgrade);
+    } else {
+      return upgrade(null);
+    }
+  }
+
+  static _WebSocketPerMessageDeflate _negotiateCompression(HttpRequest request,
+      HttpResponse response, CompressionOptions compression) {
+    var extensionHeader = request.headers.value("Sec-WebSocket-Extensions");
+
+    extensionHeader ??= "";
+
+    var hv = HeaderValue.parse(extensionHeader, valueSeparator: ',');
+    if (compression.enabled && hv.value == _WebSocketImpl.PER_MESSAGE_DEFLATE) {
+      var info = compression._createHeader(hv);
+
+      response.headers.add("Sec-WebSocket-Extensions", info.headerValue);
+      var serverNoContextTakeover =
+          (hv.parameters.containsKey(_serverNoContextTakeover) &&
+              compression.serverNoContextTakeover);
+      var clientNoContextTakeover =
+          (hv.parameters.containsKey(_clientNoContextTakeover) &&
+              compression.clientNoContextTakeover);
+      var deflate = new _WebSocketPerMessageDeflate(
+          serverNoContextTakeover: serverNoContextTakeover,
+          clientNoContextTakeover: clientNoContextTakeover,
+          serverMaxWindowBits: info.maxWindowBits,
+          clientMaxWindowBits: info.maxWindowBits,
+          serverSide: true);
+
+      return deflate;
+    }
+
+    return null;
+  }
+
+  static bool _isUpgradeRequest(HttpRequest request) {
+    if (request.method != "GET") {
+      return false;
+    }
+    if (request.headers[HttpHeaders.connectionHeader] == null) {
+      return false;
+    }
+    bool isUpgrade = false;
+    request.headers[HttpHeaders.connectionHeader].forEach((String value) {
+      if (value.toLowerCase() == "upgrade") isUpgrade = true;
+    });
+    if (!isUpgrade) return false;
+    String upgrade = request.headers.value(HttpHeaders.upgradeHeader);
+    if (upgrade == null || upgrade.toLowerCase() != "websocket") {
+      return false;
+    }
+    String version = request.headers.value("Sec-WebSocket-Version");
+    if (version == null || version != "13") {
+      return false;
+    }
+    String key = request.headers.value("Sec-WebSocket-Key");
+    if (key == null) {
+      return false;
+    }
+    return true;
+  }
+}
+
+class _WebSocketPerMessageDeflate {
+  bool serverNoContextTakeover;
+  bool clientNoContextTakeover;
+  int clientMaxWindowBits;
+  int serverMaxWindowBits;
+  bool serverSide;
+
+  RawZLibFilter decoder;
+  RawZLibFilter encoder;
+
+  _WebSocketPerMessageDeflate(
+      {this.clientMaxWindowBits: _WebSocketImpl.DEFAULT_WINDOW_BITS,
+      this.serverMaxWindowBits: _WebSocketImpl.DEFAULT_WINDOW_BITS,
+      this.serverNoContextTakeover: false,
+      this.clientNoContextTakeover: false,
+      this.serverSide: false});
+
+  void _ensureDecoder() {
+    if (decoder == null) {
+      decoder = new RawZLibFilter.inflateFilter(
+          windowBits: serverSide ? clientMaxWindowBits : serverMaxWindowBits,
+          raw: true);
+    }
+  }
+
+  void _ensureEncoder() {
+    if (encoder == null) {
+      encoder = new RawZLibFilter.deflateFilter(
+          windowBits: serverSide ? serverMaxWindowBits : clientMaxWindowBits,
+          raw: true);
+    }
+  }
+
+  Uint8List processIncomingMessage(List<int> msg) {
+    _ensureDecoder();
+
+    var data = <int>[];
+    data.addAll(msg);
+    data.addAll(const [0x00, 0x00, 0xff, 0xff]);
+
+    decoder.process(data, 0, data.length);
+    var result = <int>[];
+    List<int> out;
+
+    while ((out = decoder.processed()) != null) {
+      result.addAll(out);
+    }
+
+    if ((serverSide && clientNoContextTakeover) ||
+        (!serverSide && serverNoContextTakeover)) {
+      decoder = null;
+    }
+
+    return new Uint8List.fromList(result);
+  }
+
+  List<int> processOutgoingMessage(List<int> msg) {
+    _ensureEncoder();
+    var result = <int>[];
+    Uint8List buffer;
+
+    if (msg is! Uint8List) {
+      for (var i = 0; i < msg.length; i++) {
+        if (msg[i] < 0 || 255 < msg[i]) {
+          throw new ArgumentError("List element is not a byte value "
+              "(value ${msg[i]} at index $i)");
+        }
+      }
+      buffer = new Uint8List.fromList(msg);
+    } else {
+      buffer = msg;
+    }
+
+    encoder.process(buffer, 0, buffer.length);
+
+    List<int> out;
+    while ((out = encoder.processed()) != null) {
+      result.addAll(out);
+    }
+
+    if ((!serverSide && clientNoContextTakeover) ||
+        (serverSide && serverNoContextTakeover)) {
+      encoder = null;
+    }
+
+    if (result.length > 4) {
+      result = result.sublist(0, result.length - 4);
+    }
+
+    // RFC 7692 7.2.3.6. "Generating an Empty Fragment" says that if the
+    // compression library doesn't generate any data when the bufer is empty,
+    // then an empty uncompressed deflate block is used for this purpose. The
+    // 0x00 block has the BFINAL header bit set to 0 and the BTYPE header set to
+    // 00 along with 5 bits of padding. This block decodes to zero bytes.
+    if (result.length == 0) {
+      return [0x00];
+    }
+
+    return result;
+  }
+}
+
+// TODO(ajohnsen): Make this transformer reusable.
+class _WebSocketOutgoingTransformer
+    extends StreamTransformerBase<dynamic, List<int>> implements EventSink {
+  final _WebSocketImpl webSocket;
+  EventSink<List<int>> _eventSink;
+
+  _WebSocketPerMessageDeflate _deflateHelper;
+
+  _WebSocketOutgoingTransformer(this.webSocket) {
+    _deflateHelper = webSocket._deflate;
+  }
+
+  Stream<List<int>> bind(Stream stream) {
+    return new Stream<List<int>>.eventTransformed(stream,
+        (EventSink<List<int>> eventSink) {
+      if (_eventSink != null) {
+        throw new StateError("WebSocket transformer already used");
+      }
+      _eventSink = eventSink;
+      return this;
+    });
+  }
+
+  void add(message) {
+    if (message is _WebSocketPong) {
+      addFrame(_WebSocketOpcode.PONG, message.payload);
+      return;
+    }
+    if (message is _WebSocketPing) {
+      addFrame(_WebSocketOpcode.PING, message.payload);
+      return;
+    }
+    List<int> data;
+    int opcode;
+    if (message != null) {
+      if (message is String) {
+        opcode = _WebSocketOpcode.TEXT;
+        data = utf8.encode(message);
+      } else if (message is List<int>) {
+        opcode = _WebSocketOpcode.BINARY;
+        data = message;
+      } else if (message is _EncodedString) {
+        opcode = _WebSocketOpcode.TEXT;
+        data = message.bytes;
+      } else {
+        throw new ArgumentError(message);
+      }
+
+      if (_deflateHelper != null) {
+        data = _deflateHelper.processOutgoingMessage(data);
+      }
+    } else {
+      opcode = _WebSocketOpcode.TEXT;
+    }
+    addFrame(opcode, data);
+  }
+
+  void addError(Object error, [StackTrace stackTrace]) {
+    _eventSink.addError(error, stackTrace);
+  }
+
+  void close() {
+    int code = webSocket._outCloseCode;
+    String reason = webSocket._outCloseReason;
+    List<int> data;
+    if (code != null) {
+      data = new List<int>();
+      data.add((code >> 8) & 0xFF);
+      data.add(code & 0xFF);
+      if (reason != null) {
+        data.addAll(utf8.encode(reason));
+      }
+    }
+    addFrame(_WebSocketOpcode.CLOSE, data);
+    _eventSink.close();
+  }
+
+  void addFrame(int opcode, List<int> data) {
+    createFrame(
+            opcode,
+            data,
+            webSocket._serverSide,
+            _deflateHelper != null &&
+                (opcode == _WebSocketOpcode.TEXT ||
+                    opcode == _WebSocketOpcode.BINARY))
+        .forEach((e) {
+      _eventSink.add(e);
+    });
+  }
+
+  static Iterable<List<int>> createFrame(
+      int opcode, List<int> data, bool serverSide, bool compressed) {
+    bool mask = !serverSide; // Masking not implemented for server.
+    int dataLength = data == null ? 0 : data.length;
+    // Determine the header size.
+    int headerSize = (mask) ? 6 : 2;
+    if (dataLength > 65535) {
+      headerSize += 8;
+    } else if (dataLength > 125) {
+      headerSize += 2;
+    }
+    Uint8List header = new Uint8List(headerSize);
+    int index = 0;
+
+    // Set FIN and opcode.
+    var hoc = _WebSocketProtocolTransformer.FIN |
+        (compressed ? _WebSocketProtocolTransformer.RSV1 : 0) |
+        (opcode & _WebSocketProtocolTransformer.OPCODE);
+
+    header[index++] = hoc;
+    // Determine size and position of length field.
+    int lengthBytes = 1;
+    if (dataLength > 65535) {
+      header[index++] = 127;
+      lengthBytes = 8;
+    } else if (dataLength > 125) {
+      header[index++] = 126;
+      lengthBytes = 2;
+    }
+    // Write the length in network byte order into the header.
+    for (int i = 0; i < lengthBytes; i++) {
+      header[index++] = dataLength >> (((lengthBytes - 1) - i) * 8) & 0xFF;
+    }
+    if (mask) {
+      header[1] |= 1 << 7;
+      var maskBytes = _CryptoUtils.getRandomBytes(4);
+      header.setRange(index, index + 4, maskBytes);
+      index += 4;
+      if (data != null) {
+        Uint8List list;
+        // If this is a text message just do the masking inside the
+        // encoded data.
+        if (opcode == _WebSocketOpcode.TEXT && data is Uint8List) {
+          list = data;
+        } else {
+          if (data is Uint8List) {
+            list = new Uint8List.fromList(data);
+          } else {
+            list = new Uint8List(data.length);
+            for (int i = 0; i < data.length; i++) {
+              if (data[i] < 0 || 255 < data[i]) {
+                throw new ArgumentError("List element is not a byte value "
+                    "(value ${data[i]} at index $i)");
+              }
+              list[i] = data[i];
+            }
+          }
+        }
+        const int BLOCK_SIZE = 16;
+        int blockCount = list.length ~/ BLOCK_SIZE;
+        if (blockCount > 0) {
+          // Create mask block.
+          int mask = 0;
+          for (int i = 3; i >= 0; i--) {
+            mask = (mask << 8) | maskBytes[i];
+          }
+          Int32x4 blockMask = new Int32x4(mask, mask, mask, mask);
+          Int32x4List blockBuffer =
+              new Int32x4List.view(list.buffer, 0, blockCount);
+          for (int i = 0; i < blockBuffer.length; i++) {
+            blockBuffer[i] ^= blockMask;
+          }
+        }
+        // Handle end.
+        for (int i = blockCount * BLOCK_SIZE; i < list.length; i++) {
+          list[i] ^= maskBytes[i & 3];
+        }
+        data = list;
+      }
+    }
+    assert(index == headerSize);
+    if (data == null) {
+      return [header];
+    } else {
+      return [header, data];
+    }
+  }
+}
+
+class _WebSocketConsumer implements StreamConsumer {
+  final _WebSocketImpl webSocket;
+  final Socket socket;
+  StreamController _controller;
+  StreamSubscription _subscription;
+  bool _issuedPause = false;
+  bool _closed = false;
+  Completer _closeCompleter = new Completer<WebSocket>();
+  Completer _completer;
+
+  _WebSocketConsumer(this.webSocket, this.socket);
+
+  void _onListen() {
+    if (_subscription != null) {
+      _subscription.cancel();
+    }
+  }
+
+  void _onPause() {
+    if (_subscription != null) {
+      _subscription.pause();
+    } else {
+      _issuedPause = true;
+    }
+  }
+
+  void _onResume() {
+    if (_subscription != null) {
+      _subscription.resume();
+    } else {
+      _issuedPause = false;
+    }
+  }
+
+  void _cancel() {
+    if (_subscription != null) {
+      var subscription = _subscription;
+      _subscription = null;
+      subscription.cancel();
+    }
+  }
+
+  _ensureController() {
+    if (_controller != null) return;
+    _controller = new StreamController(
+        sync: true,
+        onPause: _onPause,
+        onResume: _onResume,
+        onCancel: _onListen);
+    var stream = _controller.stream
+        .transform(new _WebSocketOutgoingTransformer(webSocket));
+    socket.addStream(stream).then((_) {
+      _done();
+      _closeCompleter.complete(webSocket);
+    }, onError: (error, StackTrace stackTrace) {
+      _closed = true;
+      _cancel();
+      if (error is ArgumentError) {
+        if (!_done(error, stackTrace)) {
+          _closeCompleter.completeError(error, stackTrace);
+        }
+      } else {
+        _done();
+        _closeCompleter.complete(webSocket);
+      }
+    });
+  }
+
+  bool _done([error, StackTrace stackTrace]) {
+    if (_completer == null) return false;
+    if (error != null) {
+      _completer.completeError(error, stackTrace);
+    } else {
+      _completer.complete(webSocket);
+    }
+    _completer = null;
+    return true;
+  }
+
+  Future addStream(var stream) {
+    if (_closed) {
+      stream.listen(null).cancel();
+      return new Future.value(webSocket);
+    }
+    _ensureController();
+    _completer = new Completer();
+    _subscription = stream.listen((data) {
+      _controller.add(data);
+    }, onDone: _done, onError: _done, cancelOnError: true);
+    if (_issuedPause) {
+      _subscription.pause();
+      _issuedPause = false;
+    }
+    return _completer.future;
+  }
+
+  Future close() {
+    _ensureController();
+    Future closeSocket() {
+      return socket.close().catchError((_) {}).then((_) => webSocket);
+    }
+
+    _controller.close();
+    return _closeCompleter.future.then((_) => closeSocket());
+  }
+
+  void add(data) {
+    if (_closed) return;
+    _ensureController();
+    // Stop sending message if _controller has been closed.
+    // https://github.com/dart-lang/sdk/issues/37441
+    if (_controller.isClosed) return;
+    _controller.add(data);
+  }
+
+  void closeSocket() {
+    _closed = true;
+    _cancel();
+    close();
+  }
+}
+
+class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
+  // Use default Map so we keep order.
+  static Map<int, _WebSocketImpl> _webSockets = new Map<int, _WebSocketImpl>();
+  static const int DEFAULT_WINDOW_BITS = 15;
+  static const String PER_MESSAGE_DEFLATE = "permessage-deflate";
+
+  final String protocol;
+
+  StreamController _controller;
+  StreamSubscription _subscription;
+  StreamSink _sink;
+
+  final _socket;
+  final bool _serverSide;
+  int _readyState = WebSocket.connecting;
+  bool _writeClosed = false;
+  int _closeCode;
+  String _closeReason;
+  Duration _pingInterval;
+  Timer _pingTimer;
+  _WebSocketConsumer _consumer;
+
+  int _outCloseCode;
+  String _outCloseReason;
+  Timer _closeTimer;
+  _WebSocketPerMessageDeflate _deflate;
+
+  static final HttpClient _httpClient = new HttpClient();
+
+  static Future<WebSocket> connect(
+      String url, Iterable<String> protocols, Map<String, dynamic> headers,
+      {CompressionOptions compression: CompressionOptions.compressionDefault}) {
+    Uri uri = Uri.parse(url);
+    if (uri.scheme != "ws" && uri.scheme != "wss") {
+      throw new WebSocketException("Unsupported URL scheme '${uri.scheme}'");
+    }
+
+    Random random = new Random();
+    // Generate 16 random bytes.
+    Uint8List nonceData = new Uint8List(16);
+    for (int i = 0; i < 16; i++) {
+      nonceData[i] = random.nextInt(256);
+    }
+    String nonce = _CryptoUtils.bytesToBase64(nonceData);
+
+    uri = new Uri(
+        scheme: uri.scheme == "wss" ? "https" : "http",
+        userInfo: uri.userInfo,
+        host: uri.host,
+        port: uri.port,
+        path: uri.path,
+        query: uri.query,
+        fragment: uri.fragment);
+    return _httpClient.openUrl("GET", uri).then((request) {
+      if (uri.userInfo != null && !uri.userInfo.isEmpty) {
+        // If the URL contains user information use that for basic
+        // authorization.
+        String auth = _CryptoUtils.bytesToBase64(utf8.encode(uri.userInfo));
+        request.headers.set(HttpHeaders.authorizationHeader, "Basic $auth");
+      }
+      if (headers != null) {
+        headers.forEach((field, value) => request.headers.add(field, value));
+      }
+      // Setup the initial handshake.
+      request.headers
+        ..set(HttpHeaders.connectionHeader, "Upgrade")
+        ..set(HttpHeaders.upgradeHeader, "websocket")
+        ..set("Sec-WebSocket-Key", nonce)
+        ..set("Cache-Control", "no-cache")
+        ..set("Sec-WebSocket-Version", "13");
+      if (protocols != null) {
+        request.headers.add("Sec-WebSocket-Protocol", protocols.toList());
+      }
+
+      if (compression.enabled) {
+        request.headers
+            .add("Sec-WebSocket-Extensions", compression._createHeader());
+      }
+
+      return request.close();
+    }).then((response) {
+      void error(String message) {
+        // Flush data.
+        response.detachSocket().then((socket) {
+          socket.destroy();
+        });
+        throw new WebSocketException(message);
+      }
+
+      if (response.statusCode != HttpStatus.switchingProtocols ||
+          response.headers[HttpHeaders.connectionHeader] == null ||
+          !response.headers[HttpHeaders.connectionHeader]
+              .any((value) => value.toLowerCase() == "upgrade") ||
+          response.headers.value(HttpHeaders.upgradeHeader).toLowerCase() !=
+              "websocket") {
+        error("Connection to '$uri' was not upgraded to websocket");
+      }
+      String accept = response.headers.value("Sec-WebSocket-Accept");
+      if (accept == null) {
+        error("Response did not contain a 'Sec-WebSocket-Accept' header");
+      }
+      _SHA1 sha1 = new _SHA1();
+      sha1.add("$nonce$_webSocketGUID".codeUnits);
+      List<int> expectedAccept = sha1.close();
+      List<int> receivedAccept = _CryptoUtils.base64StringToBytes(accept);
+      if (expectedAccept.length != receivedAccept.length) {
+        error("Response header 'Sec-WebSocket-Accept' is the wrong length");
+      }
+      for (int i = 0; i < expectedAccept.length; i++) {
+        if (expectedAccept[i] != receivedAccept[i]) {
+          error("Bad response 'Sec-WebSocket-Accept' header");
+        }
+      }
+      var protocol = response.headers.value('Sec-WebSocket-Protocol');
+
+      _WebSocketPerMessageDeflate deflate =
+          negotiateClientCompression(response, compression);
+
+      return response.detachSocket().then<WebSocket>((socket) =>
+          new _WebSocketImpl._fromSocket(
+              socket, protocol, compression, false, deflate));
+    });
+  }
+
+  static _WebSocketPerMessageDeflate negotiateClientCompression(
+      HttpClientResponse response, CompressionOptions compression) {
+    String extensionHeader = response.headers.value('Sec-WebSocket-Extensions');
+
+    if (extensionHeader == null) {
+      extensionHeader = "";
+    }
+
+    var hv = HeaderValue.parse(extensionHeader, valueSeparator: ',');
+
+    if (compression.enabled && hv.value == PER_MESSAGE_DEFLATE) {
+      var serverNoContextTakeover =
+          hv.parameters.containsKey(_serverNoContextTakeover);
+      var clientNoContextTakeover =
+          hv.parameters.containsKey(_clientNoContextTakeover);
+
+      int getWindowBits(String type) {
+        var o = hv.parameters[type];
+        if (o == null) {
+          return DEFAULT_WINDOW_BITS;
+        }
+
+        return int.parse(o, onError: (s) => DEFAULT_WINDOW_BITS);
+      }
+
+      return new _WebSocketPerMessageDeflate(
+          clientMaxWindowBits: getWindowBits(_clientMaxWindowBits),
+          serverMaxWindowBits: getWindowBits(_serverMaxWindowBits),
+          clientNoContextTakeover: clientNoContextTakeover,
+          serverNoContextTakeover: serverNoContextTakeover);
+    }
+
+    return null;
+  }
+
+  _WebSocketImpl._fromSocket(
+      this._socket, this.protocol, CompressionOptions compression,
+      [this._serverSide = false, _WebSocketPerMessageDeflate deflate]) {
+    _consumer = new _WebSocketConsumer(this, _socket);
+    _sink = new _StreamSinkImpl(_consumer);
+    _readyState = WebSocket.open;
+    _deflate = deflate;
+
+    var transformer = new _WebSocketProtocolTransformer(_serverSide, _deflate);
+    _subscription = transformer.bind(_socket).listen((data) {
+      if (data is _WebSocketPing) {
+        if (!_writeClosed) _consumer.add(new _WebSocketPong(data.payload));
+      } else if (data is _WebSocketPong) {
+        // Simply set pingInterval, as it'll cancel any timers.
+        pingInterval = _pingInterval;
+      } else {
+        _controller.add(data);
+      }
+    }, onError: (error, stackTrace) {
+      if (_closeTimer != null) _closeTimer.cancel();
+      if (error is FormatException) {
+        _close(WebSocketStatus.INVALID_FRAME_PAYLOAD_DATA);
+      } else {
+        _close(WebSocketStatus.PROTOCOL_ERROR);
+      }
+      // An error happened, set the close code set above.
+      _closeCode = _outCloseCode;
+      _closeReason = _outCloseReason;
+      _controller.close();
+    }, onDone: () {
+      if (_closeTimer != null) _closeTimer.cancel();
+      if (_readyState == WebSocket.open) {
+        _readyState = WebSocket.closing;
+        if (!_isReservedStatusCode(transformer.closeCode)) {
+          _close(transformer.closeCode, transformer.closeReason);
+        } else {
+          _close();
+        }
+        _readyState = WebSocket.closed;
+      }
+      // Protocol close, use close code from transformer.
+      _closeCode = transformer.closeCode;
+      _closeReason = transformer.closeReason;
+      _controller.close();
+    }, cancelOnError: true);
+    _subscription.pause();
+    _controller = new StreamController(
+        sync: true,
+        onListen: _subscription.resume,
+        onCancel: () {
+          _subscription.cancel();
+          _subscription = null;
+        },
+        onPause: _subscription.pause,
+        onResume: _subscription.resume);
+
+    _webSockets[_serviceId] = this;
+  }
+
+  StreamSubscription listen(void onData(message),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    return _controller.stream.listen(onData,
+        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+  }
+
+  Duration get pingInterval => _pingInterval;
+
+  void set pingInterval(Duration interval) {
+    if (_writeClosed) return;
+    if (_pingTimer != null) _pingTimer.cancel();
+    _pingInterval = interval;
+
+    if (_pingInterval == null) return;
+
+    _pingTimer = new Timer(_pingInterval, () {
+      if (_writeClosed) return;
+      _consumer.add(new _WebSocketPing());
+      _pingTimer = new Timer(_pingInterval, () {
+        // No pong received.
+        _close(WebSocketStatus.GOING_AWAY);
+      });
+    });
+  }
+
+  int get readyState => _readyState;
+
+  String get extensions => null;
+  int get closeCode => _closeCode;
+  String get closeReason => _closeReason;
+
+  void add(data) {
+    _sink.add(data);
+  }
+
+  void addUtf8Text(List<int> bytes) {
+    ArgumentError.checkNotNull(bytes, "bytes");
+    _sink.add(new _EncodedString(bytes));
+  }
+
+  void addError(error, [StackTrace stackTrace]) {
+    _sink.addError(error, stackTrace);
+  }
+
+  Future addStream(Stream stream) => _sink.addStream(stream);
+  Future get done => _sink.done;
+
+  Future close([int code, String reason]) {
+    if (_isReservedStatusCode(code)) {
+      throw new WebSocketException("Reserved status code $code");
+    }
+    if (_outCloseCode == null) {
+      _outCloseCode = code;
+      _outCloseReason = reason;
+    }
+    if (!_controller.isClosed) {
+      // If a close has not yet been received from the other end then
+      //   1) make sure to listen on the stream so the close frame will be
+      //      processed if received.
+      //   2) set a timer terminate the connection if a close frame is
+      //      not received.
+      if (!_controller.hasListener && _subscription != null) {
+        _controller.stream.drain().catchError((_) => {});
+      }
+      if (_closeTimer == null) {
+        // When closing the web-socket, we no longer accept data.
+        _closeTimer = new Timer(const Duration(seconds: 5), () {
+          // Reuse code and reason from the local close.
+          _closeCode = _outCloseCode;
+          _closeReason = _outCloseReason;
+          if (_subscription != null) _subscription.cancel();
+          _controller.close();
+          _webSockets.remove(_serviceId);
+        });
+      }
+    }
+    return _sink.close();
+  }
+
+  static String get userAgent => _httpClient.userAgent;
+
+  static set userAgent(String userAgent) {
+    _httpClient.userAgent = userAgent;
+  }
+
+  void _close([int code, String reason]) {
+    if (_writeClosed) return;
+    if (_outCloseCode == null) {
+      _outCloseCode = code;
+      _outCloseReason = reason;
+    }
+    _writeClosed = true;
+    _consumer.closeSocket();
+    _webSockets.remove(_serviceId);
+  }
+
+  String get _serviceTypePath => 'io/websockets';
+  String get _serviceTypeName => 'WebSocket';
+
+  Map<String, dynamic> _toJSON(bool ref) {
+    var name = '${_socket.address.host}:${_socket.port}';
+    var r = <String, dynamic>{
+      'id': _servicePath,
+      'type': _serviceType(ref),
+      'name': name,
+      'user_name': name,
+    };
+    if (ref) {
+      return r;
+    }
+    try {
+      r['socket'] = _socket._toJSON(true);
+    } catch (_) {
+      r['socket'] = {
+        'id': _servicePath,
+        'type': '@Socket',
+        'name': 'UserSocket',
+        'user_name': 'UserSocket',
+      };
+    }
+    return r;
+  }
+
+  static bool _isReservedStatusCode(int code) {
+    return code != null &&
+        (code < WebSocketStatus.NORMAL_CLOSURE ||
+            code == WebSocketStatus.RESERVED_1004 ||
+            code == WebSocketStatus.NO_STATUS_RECEIVED ||
+            code == WebSocketStatus.ABNORMAL_CLOSURE ||
+            (code > WebSocketStatus.INTERNAL_SERVER_ERROR &&
+                code < WebSocketStatus.RESERVED_1015) ||
+            (code >= WebSocketStatus.RESERVED_1015 && code < 3000));
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart
new file mode 100644
index 0000000..91d6847
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart
@@ -0,0 +1,595 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Support for interoperating with JavaScript.
+ *
+ * This library provides access to JavaScript objects from Dart, allowing
+ * Dart code to get and set properties, and call methods of JavaScript objects
+ * and invoke JavaScript functions. The library takes care of converting
+ * between Dart and JavaScript objects where possible, or providing proxies if
+ * conversion isn't possible.
+ *
+ * This library does not yet make Dart objects usable from JavaScript, their
+ * methods and proeprties are not accessible, though it does allow Dart
+ * functions to be passed into and called from JavaScript.
+ *
+ * [JsObject] is the core type and represents a proxy of a JavaScript object.
+ * JsObject gives access to the underlying JavaScript objects properties and
+ * methods. `JsObject`s can be acquired by calls to JavaScript, or they can be
+ * created from proxies to JavaScript constructors.
+ *
+ * The top-level getter [context] provides a [JsObject] that represents the
+ * global object in JavaScript, usually `window`.
+ *
+ * The following example shows an alert dialog via a JavaScript call to the
+ * global function `alert()`:
+ *
+ *     import 'dart:js';
+ *
+ *     main() => context.callMethod('alert', ['Hello from Dart!']);
+ *
+ * This example shows how to create a [JsObject] from a JavaScript constructor
+ * and access its properties:
+ *
+ *     import 'dart:js';
+ *
+ *     main() {
+ *       var object = new JsObject(context['Object']);
+ *       object['greeting'] = 'Hello';
+ *       object['greet'] = (name) => "${object['greeting']} $name";
+ *       var message = object.callMethod('greet', ['JavaScript']);
+ *       context['console'].callMethod('log', [message]);
+ *     }
+ *
+ * ## Proxying and automatic conversion
+ *
+ * When setting properties on a JsObject or passing arguments to a Javascript
+ * method or function, Dart objects are automatically converted or proxied to
+ * JavaScript objects. When accessing JavaScript properties, or when a Dart
+ * closure is invoked from JavaScript, the JavaScript objects are also
+ * converted to Dart.
+ *
+ * Functions and closures are proxied in such a way that they are callable. A
+ * Dart closure assigned to a JavaScript property is proxied by a function in
+ * JavaScript. A JavaScript function accessed from Dart is proxied by a
+ * [JsFunction], which has a [apply] method to invoke it.
+ *
+ * The following types are transferred directly and not proxied:
+ *
+ * * "Basic" types: `null`, `bool`, `num`, `String`, `DateTime`
+ * * `Blob`
+ * * `Event`
+ * * `HtmlCollection`
+ * * `ImageData`
+ * * `KeyRange`
+ * * `Node`
+ * * `NodeList`
+ * * `TypedData`, including its subclasses like `Int32List`, but _not_
+ *   `ByteBuffer`
+ * * `Window`
+ *
+ * ## Converting collections with JsObject.jsify()
+ *
+ * To create a JavaScript collection from a Dart collection use the
+ * [JsObject.jsify] constructor, which converts Dart [Map]s and [Iterable]s
+ * into JavaScript Objects and Arrays.
+ *
+ * The following expression creates a new JavaScript object with the properties
+ * `a` and `b` defined:
+ *
+ *     var jsMap = new JsObject.jsify({'a': 1, 'b': 2});
+ *
+ * This expression creates a JavaScript array:
+ *
+ *     var jsArray = new JsObject.jsify([1, 2, 3]);
+ */
+library dart.js;
+
+import 'dart:collection' show HashMap, ListMixin;
+
+import 'dart:_js_helper' show Primitives;
+import 'dart:_foreign_helper' show JS;
+import 'dart:_runtime' as dart;
+
+final JsObject context = _wrapToDart(dart.global_);
+
+/**
+ * Proxies a JavaScript object to Dart.
+ *
+ * The properties of the JavaScript object are accessible via the `[]` and
+ * `[]=` operators. Methods are callable via [callMethod].
+ */
+class JsObject {
+  // The wrapped JS object.
+  final dynamic _jsObject;
+
+  // This should only be called from _wrapToDart
+  JsObject._fromJs(this._jsObject) {
+    assert(_jsObject != null);
+  }
+
+  /**
+   * Constructs a new JavaScript object from [constructor] and returns a proxy
+   * to it.
+   */
+  factory JsObject(JsFunction constructor, [List arguments]) {
+    var ctor = constructor._jsObject;
+    if (arguments == null) {
+      return _wrapToDart(JS('', 'new #()', ctor));
+    }
+    var unwrapped = List.from(arguments.map(_convertToJS));
+    return _wrapToDart(JS('', 'new #(...#)', ctor, unwrapped));
+  }
+
+  /**
+   * Constructs a [JsObject] that proxies a native Dart object; _for expert use
+   * only_.
+   *
+   * Use this constructor only if you wish to get access to JavaScript
+   * properties attached to a browser host object, such as a Node or Blob, that
+   * is normally automatically converted into a native Dart object.
+   *
+   * An exception will be thrown if [object] either is `null` or has the type
+   * `bool`, `num`, or `String`.
+   */
+  factory JsObject.fromBrowserObject(object) {
+    if (object is num || object is String || object is bool || object == null) {
+      throw ArgumentError("object cannot be a num, string, bool, or null");
+    }
+    return _wrapToDart(_convertToJS(object));
+  }
+
+  /**
+   * Recursively converts a JSON-like collection of Dart objects to a
+   * collection of JavaScript objects and returns a [JsObject] proxy to it.
+   *
+   * [object] must be a [Map] or [Iterable], the contents of which are also
+   * converted. Maps and Iterables are copied to a new JavaScript object.
+   * Primitives and other transferable values are directly converted to their
+   * JavaScript type, and all other objects are proxied.
+   */
+  factory JsObject.jsify(object) {
+    if ((object is! Map) && (object is! Iterable)) {
+      throw ArgumentError("object must be a Map or Iterable");
+    }
+    return _wrapToDart(_convertDataTree(object));
+  }
+
+  static _convertDataTree(data) {
+    var _convertedObjects = HashMap.identity();
+
+    _convert(o) {
+      if (_convertedObjects.containsKey(o)) {
+        return _convertedObjects[o];
+      }
+      if (o is Map) {
+        final convertedMap = JS('', '{}');
+        _convertedObjects[o] = convertedMap;
+        for (var key in o.keys) {
+          JS('', '#[#] = #', convertedMap, key, _convert(o[key]));
+        }
+        return convertedMap;
+      } else if (o is Iterable) {
+        var convertedList = [];
+        _convertedObjects[o] = convertedList;
+        convertedList.addAll(o.map(_convert));
+        return convertedList;
+      } else {
+        return _convertToJS(o);
+      }
+    }
+
+    return _convert(data);
+  }
+
+  /**
+   * Returns the value associated with [property] from the proxied JavaScript
+   * object.
+   *
+   * The type of [property] must be either [String] or [num].
+   */
+  dynamic operator [](Object property) {
+    if (property is! String && property is! num) {
+      throw ArgumentError("property is not a String or num");
+    }
+    return _convertToDart(JS('', '#[#]', _jsObject, property));
+  }
+
+  /**
+   * Sets the value associated with [property] on the proxied JavaScript
+   * object.
+   *
+   * The type of [property] must be either [String] or [num].
+   */
+  void operator []=(Object property, value) {
+    if (property is! String && property is! num) {
+      throw ArgumentError("property is not a String or num");
+    }
+    JS('', '#[#] = #', _jsObject, property, _convertToJS(value));
+  }
+
+  int get hashCode => 0;
+
+  bool operator ==(other) =>
+      other is JsObject && JS<bool>('!', '# === #', _jsObject, other._jsObject);
+
+  /**
+   * Returns `true` if the JavaScript object contains the specified property
+   * either directly or though its prototype chain.
+   *
+   * This is the equivalent of the `in` operator in JavaScript.
+   */
+  bool hasProperty(property) {
+    if (property is! String && property is! num) {
+      throw ArgumentError("property is not a String or num");
+    }
+    return JS<bool>('!', '# in #', property, _jsObject);
+  }
+
+  /**
+   * Removes [property] from the JavaScript object.
+   *
+   * This is the equivalent of the `delete` operator in JavaScript.
+   */
+  void deleteProperty(property) {
+    if (property is! String && property is! num) {
+      throw ArgumentError("property is not a String or num");
+    }
+    JS<bool>('!', 'delete #[#]', _jsObject, property);
+  }
+
+  /**
+   * Returns `true` if the JavaScript object has [type] in its prototype chain.
+   *
+   * This is the equivalent of the `instanceof` operator in JavaScript.
+   */
+  bool instanceof(JsFunction type) {
+    return JS<bool>('!', '# instanceof #', _jsObject, _convertToJS(type));
+  }
+
+  /**
+   * Returns the result of the JavaScript objects `toString` method.
+   */
+  String toString() {
+    try {
+      return JS<String>('!', 'String(#)', _jsObject);
+    } catch (e) {
+      return super.toString();
+    }
+  }
+
+  /**
+   * Calls [method] on the JavaScript object with the arguments [args] and
+   * returns the result.
+   *
+   * The type of [method] must be either [String] or [num].
+   */
+  dynamic callMethod(method, [List args]) {
+    if (method is! String && method is! num) {
+      throw ArgumentError("method is not a String or num");
+    }
+    if (args != null) args = List.from(args.map(_convertToJS));
+    var fn = JS('', '#[#]', _jsObject, method);
+    if (JS<bool>('!', 'typeof(#) !== "function"', fn)) {
+      throw NoSuchMethodError(_jsObject, Symbol(method), args, {});
+    }
+    return _convertToDart(JS('', '#.apply(#, #)', fn, _jsObject, args));
+  }
+}
+
+/**
+ * Proxies a JavaScript Function object.
+ */
+class JsFunction extends JsObject {
+  /**
+   * Returns a [JsFunction] that captures its 'this' binding and calls [f]
+   * with the value of this passed as the first argument.
+   */
+  factory JsFunction.withThis(Function f) {
+    return JsFunction._fromJs(JS(
+        '',
+        'function(/*...arguments*/) {'
+            '  let args = [#(this)];'
+            '  for (let arg of arguments) {'
+            '    args.push(#(arg));'
+            '  }'
+            '  return #(#(...args));'
+            '}',
+        _convertToDart,
+        _convertToDart,
+        _convertToJS,
+        f));
+  }
+
+  JsFunction._fromJs(jsObject) : super._fromJs(jsObject);
+
+  /**
+   * Invokes the JavaScript function with arguments [args]. If [thisArg] is
+   * supplied it is the value of `this` for the invocation.
+   */
+  dynamic apply(List args, {thisArg}) => _convertToDart(JS(
+      '',
+      '#.apply(#, #)',
+      _jsObject,
+      _convertToJS(thisArg),
+      args == null ? null : List.from(args.map(_convertToJS))));
+}
+
+// TODO(jmesserly): this is totally unnecessary in dev_compiler.
+/** A [List] that proxies a JavaScript array. */
+class JsArray<E> extends JsObject with ListMixin<E> {
+  /**
+   * Creates a new JavaScript array.
+   */
+  JsArray() : super._fromJs([]);
+
+  /**
+   * Creates a new JavaScript array and initializes it to the contents of
+   * [other].
+   */
+  JsArray.from(Iterable<E> other)
+      : super._fromJs([]..addAll(other.map(_convertToJS)));
+
+  JsArray._fromJs(jsObject) : super._fromJs(jsObject);
+
+  _checkIndex(int index) {
+    if (index is int && (index < 0 || index >= length)) {
+      throw RangeError.range(index, 0, length);
+    }
+  }
+
+  _checkInsertIndex(int index) {
+    if (index is int && (index < 0 || index >= length + 1)) {
+      throw RangeError.range(index, 0, length);
+    }
+  }
+
+  static _checkRange(int start, int end, int length) {
+    if (start < 0 || start > length) {
+      throw RangeError.range(start, 0, length);
+    }
+    if (end < start || end > length) {
+      throw RangeError.range(end, start, length);
+    }
+  }
+
+  // Methods required by ListMixin
+
+  E operator [](Object index) {
+    // TODO(justinfagnani): fix the semantics for non-ints
+    // dartbug.com/14605
+    if (index is num && index == index.toInt()) {
+      _checkIndex(index);
+    }
+    return super[index] as E;
+  }
+
+  void operator []=(Object index, value) {
+    // TODO(justinfagnani): fix the semantics for non-ints
+    // dartbug.com/14605
+    if (index is num && index == index.toInt()) {
+      _checkIndex(index);
+    }
+    super[index] = value;
+  }
+
+  int get length {
+    // Check the length honours the List contract.
+    var len = JS('', '#.length', _jsObject);
+    // JavaScript arrays have lengths which are unsigned 32-bit integers.
+    if (JS<bool>(
+        '!', 'typeof # === "number" && (# >>> 0) === #', len, len, len)) {
+      return JS<int>('!', '#', len);
+    }
+    throw StateError('Bad JsArray length');
+  }
+
+  void set length(int length) {
+    super['length'] = length;
+  }
+
+  // Methods overridden for better performance
+
+  void add(E value) {
+    callMethod('push', [value]);
+  }
+
+  void addAll(Iterable<E> iterable) {
+    var list = (JS<bool>('!', '# instanceof Array', iterable))
+        ? iterable
+        : List.from(iterable);
+    callMethod('push', list);
+  }
+
+  void insert(int index, E element) {
+    _checkInsertIndex(index);
+    callMethod('splice', [index, 0, element]);
+  }
+
+  E removeAt(int index) {
+    _checkIndex(index);
+    return callMethod('splice', [index, 1])[0] as E;
+  }
+
+  E removeLast() {
+    if (length == 0) throw RangeError(-1);
+    return callMethod('pop') as E;
+  }
+
+  void removeRange(int start, int end) {
+    _checkRange(start, end, length);
+    callMethod('splice', [start, end - start]);
+  }
+
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+    _checkRange(start, end, this.length);
+    int length = end - start;
+    if (length == 0) return;
+    if (skipCount < 0) throw ArgumentError(skipCount);
+    var args = <Object>[start, length]
+      ..addAll(iterable.skip(skipCount).take(length));
+    callMethod('splice', args);
+  }
+
+  void sort([int compare(E a, E b)]) {
+    // Note: arr.sort(null) is a type error in FF
+    callMethod('sort', compare == null ? [] : [compare]);
+  }
+}
+
+// Cross frame objects should not be considered browser types.
+// We include the instanceof Object test to filter out cross frame objects
+// on FireFox. Surprisingly on FireFox the instanceof Window test succeeds for
+// cross frame windows while the instanceof Object test fails.
+bool _isBrowserType(o) => JS(
+    'bool',
+    '# instanceof Object && ('
+        '# instanceof Blob || '
+        '# instanceof Event || '
+        '(window.KeyRange && # instanceof KeyRange) || '
+        '(window.IDBKeyRange && # instanceof IDBKeyRange) || '
+        '# instanceof ImageData || '
+        '# instanceof Node || '
+        // Int8Array.__proto__ is TypedArray.
+        '(window.Int8Array && # instanceof Int8Array.__proto__) || '
+        '# instanceof Window)',
+    o,
+    o,
+    o,
+    o,
+    o,
+    o,
+    o,
+    o,
+    o);
+
+class _DartObject {
+  final _dartObj;
+  _DartObject(this._dartObj);
+}
+
+dynamic _convertToJS(dynamic o) {
+  if (o == null || o is String || o is num || o is bool || _isBrowserType(o)) {
+    return o;
+  } else if (o is DateTime) {
+    return Primitives.lazyAsJsDate(o);
+  } else if (o is JsObject) {
+    return o._jsObject;
+  } else if (o is Function) {
+    return _putIfAbsent(_jsProxies, o, _wrapDartFunction);
+  } else {
+    // TODO(jmesserly): for now, we wrap other objects, to keep compatibility
+    // with the original dart:js behavior.
+    return _putIfAbsent(_jsProxies, o, (o) => _DartObject(o));
+  }
+}
+
+dynamic _wrapDartFunction(f) {
+  var wrapper = JS(
+      '',
+      'function(/*...arguments*/) {'
+          '  let args = Array.prototype.map.call(arguments, #);'
+          '  return #(#(...args));'
+          '}',
+      _convertToDart,
+      _convertToJS,
+      f);
+  JS('', '#.set(#, #)', _dartProxies, wrapper, f);
+
+  return wrapper;
+}
+
+// converts a Dart object to a reference to a native JS object
+// which might be a DartObject JS->Dart proxy
+Object _convertToDart(o) {
+  if (o == null || o is String || o is num || o is bool || _isBrowserType(o)) {
+    return o;
+  } else if (JS('!', '# instanceof Date', o)) {
+    num ms = JS('!', '#.getTime()', o);
+    return DateTime.fromMillisecondsSinceEpoch(ms);
+  } else if (o is _DartObject &&
+      !identical(dart.getReifiedType(o), dart.jsobject)) {
+    return o._dartObj;
+  } else {
+    return _wrapToDart(o);
+  }
+}
+
+Object _wrapToDart(o) => _putIfAbsent(_dartProxies, o, _wrapToDartHelper);
+
+Object _wrapToDartHelper(o) {
+  if (JS<bool>('!', 'typeof # == "function"', o)) {
+    return JsFunction._fromJs(o);
+  }
+  if (JS<bool>('!', '# instanceof Array', o)) {
+    return JsArray._fromJs(o);
+  }
+  return JsObject._fromJs(o);
+}
+
+final _dartProxies = JS('', 'new WeakMap()');
+final _jsProxies = JS('', 'new WeakMap()');
+
+Object _putIfAbsent(weakMap, o, getValue(o)) {
+  var value = JS('', '#.get(#)', weakMap, o);
+  if (value == null) {
+    value = getValue(o);
+    JS('', '#.set(#, #)', weakMap, o, value);
+  }
+  return value;
+}
+
+Expando<Function> _interopExpando = Expando<Function>();
+
+/// Returns a wrapper around function [f] that can be called from JavaScript
+/// using the package:js Dart-JavaScript interop.
+///
+/// For performance reasons in Dart2Js, by default Dart functions cannot be
+/// passed directly to JavaScript unless this method is called to create
+/// a Function compatible with both Dart and JavaScript.
+/// Calling this method repeatedly on a function will return the same function.
+/// The [Function] returned by this method can be used from both Dart and
+/// JavaScript. We may remove the need to call this method completely in the
+/// future if Dart2Js is refactored so that its function calling conventions
+/// are more compatible with JavaScript.
+F allowInterop<F extends Function>(F f) {
+  var ret = _interopExpando[f];
+  if (ret == null) {
+    ret = JS(
+        '',
+        'function (...args) {'
+            ' return #(#, args);'
+            '}',
+        dart.dcall,
+        f);
+    _interopExpando[f] = ret;
+  }
+  return ret;
+}
+
+Expando<Function> _interopCaptureThisExpando = Expando<Function>();
+
+/// Returns a [Function] that when called from JavaScript captures its 'this'
+/// binding and calls [f] with the value of this passed as the first argument.
+/// When called from Dart, [null] will be passed as the first argument.
+///
+/// See the documentation for [allowInterop]. This method should only be used
+/// with package:js Dart-JavaScript interop.
+Function allowInteropCaptureThis(Function f) {
+  var ret = _interopCaptureThisExpando[f];
+  if (ret == null) {
+    ret = JS(
+        '',
+        'function(...arguments) {'
+            '  let args = [this];'
+            '  args.push.apply(args, arguments);'
+            '  return #(#, args);'
+            '}',
+        dart.dcall,
+        f);
+    _interopCaptureThisExpando[f] = ret;
+  }
+  return ret;
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/lib/js_util/dart2js/js_util_dart2js.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/lib/js_util/dart2js/js_util_dart2js.dart
new file mode 100644
index 0000000..4b9fdb0
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/lib/js_util/dart2js/js_util_dart2js.dart
@@ -0,0 +1,126 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Utility methods to efficiently manipulate typed JSInterop objects in cases
+/// where the name to call is not known at runtime. You should only use these
+/// methods when the same effect cannot be achieved with @JS annotations.
+/// These methods would be extension methods on JSObject if Dart supported
+/// extension methods.
+library dart.js_util;
+
+import 'dart:_foreign_helper' show JS;
+import 'dart:collection' show HashMap;
+
+/// WARNING: performance of this method is much worse than other uitil
+/// methods in this library. Only use this method as a last resort.
+///
+/// Recursively converts a JSON-like collection of Dart objects to a
+/// collection of JavaScript objects and returns a [JsObject] proxy to it.
+///
+/// [object] must be a [Map] or [Iterable], the contents of which are also
+/// converted. Maps and Iterables are copied to a new JavaScript object.
+/// Primitives and other transferrable values are directly converted to their
+/// JavaScript type, and all other objects are proxied.
+jsify(object) {
+  if ((object is! Map) && (object is! Iterable)) {
+    throw ArgumentError("object must be a Map or Iterable");
+  }
+  return _convertDataTree(object);
+}
+
+_convertDataTree(data) {
+  var _convertedObjects = HashMap.identity();
+
+  _convert(o) {
+    if (_convertedObjects.containsKey(o)) {
+      return _convertedObjects[o];
+    }
+    if (o is Map) {
+      final convertedMap = JS('=Object', '{}');
+      _convertedObjects[o] = convertedMap;
+      for (var key in o.keys) {
+        JS('=Object', '#[#]=#', convertedMap, key, _convert(o[key]));
+      }
+      return convertedMap;
+    } else if (o is Iterable) {
+      var convertedList = [];
+      _convertedObjects[o] = convertedList;
+      convertedList.addAll(o.map(_convert));
+      return convertedList;
+    } else {
+      return o;
+    }
+  }
+
+  return _convert(data);
+}
+
+newObject() => JS('=Object', '{}');
+
+hasProperty(o, name) => JS<bool>('!', '# in #', name, o);
+getProperty(o, name) => JS('Object', '#[#]', o, name);
+setProperty(o, name, value) => JS('', '#[#]=#', o, name, value);
+
+callMethod(o, String method, List args) =>
+    JS('Object', '#[#].apply(#, #)', o, method, o, args);
+
+instanceof(o, Function type) => JS<bool>('!', '# instanceof #', o, type);
+callConstructor(Function constr, List arguments) {
+  if (arguments == null) {
+    return JS('Object', 'new #()', constr);
+  }
+
+  if (JS<bool>('!', '# instanceof Array', arguments)) {
+    int argumentCount = JS('!', '#.length', arguments);
+    switch (argumentCount) {
+      case 0:
+        return JS('Object', 'new #()', constr);
+
+      case 1:
+        var arg0 = JS('', '#[0]', arguments);
+        return JS('Object', 'new #(#)', constr, arg0);
+
+      case 2:
+        var arg0 = JS('', '#[0]', arguments);
+        var arg1 = JS('', '#[1]', arguments);
+        return JS('Object', 'new #(#, #)', constr, arg0, arg1);
+
+      case 3:
+        var arg0 = JS('', '#[0]', arguments);
+        var arg1 = JS('', '#[1]', arguments);
+        var arg2 = JS('', '#[2]', arguments);
+        return JS('Object', 'new #(#, #, #)', constr, arg0, arg1, arg2);
+
+      case 4:
+        var arg0 = JS('', '#[0]', arguments);
+        var arg1 = JS('', '#[1]', arguments);
+        var arg2 = JS('', '#[2]', arguments);
+        var arg3 = JS('', '#[3]', arguments);
+        return JS(
+            'Object', 'new #(#, #, #, #)', constr, arg0, arg1, arg2, arg3);
+    }
+  }
+
+  // The following code solves the problem of invoking a JavaScript
+  // constructor with an unknown number arguments.
+  // First bind the constructor to the argument list using bind.apply().
+  // The first argument to bind() is the binding of 't', so add 'null' to
+  // the arguments list passed to apply().
+  // After that, use the JavaScript 'new' operator which overrides any binding
+  // of 'this' with the new instance.
+  var args = <dynamic>[null]..addAll(arguments);
+  var factoryFunction = JS('', '#.bind.apply(#, #)', constr, constr, args);
+  // Without this line, calling factoryFunction as a constructor throws
+  JS<String>('!', 'String(#)', factoryFunction);
+  // This could return an UnknownJavaScriptObject, or a native
+  // object for which there is an interceptor
+  return JS('Object', 'new #()', factoryFunction);
+
+  // TODO(sra): Investigate:
+  //
+  //     var jsObj = JS('', 'Object.create(#.prototype)', constr);
+  //     JS('', '#.apply(#, #)', constr, jsObj,
+  //         []..addAll(arguments.map(_convertToJS)));
+  //     return _wrapToDart(jsObj);
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/libraries.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/libraries.dart
new file mode 100644
index 0000000..d5cffa2
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/libraries.dart
@@ -0,0 +1,310 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library libraries;
+
+/**
+ * A bit flag used by [LibraryInfo] indicating that a library is used by dart2js
+ */
+const int DART2JS_PLATFORM = 1;
+
+/**
+ * A bit flag used by [LibraryInfo] indicating that a library is used by the VM
+ */
+const int VM_PLATFORM = 2;
+
+/// The contexts that a library can be used from.
+enum Category {
+  /// Indicates that a library can be used in a browser context.
+  client,
+
+  /// Indicates that a library can be used in a command line context.
+  server,
+
+  /// Indicates that a library can be used from embedded devices.
+  embedded
+}
+
+Category parseCategory(String name) {
+  switch (name) {
+    case "Client":
+      return Category.client;
+    case "Server":
+      return Category.server;
+    case "Embedded":
+      return Category.embedded;
+  }
+  return null;
+}
+
+/// Mapping of "dart:" library name (e.g. "core") to information about that
+/// library.
+const Map<String, LibraryInfo> libraries = const {
+  "async": const LibraryInfo("async/async.dart",
+      categories: "Client,Server",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/async_patch.dart"),
+  "collection": const LibraryInfo("collection/collection.dart",
+      categories: "Client,Server,Embedded",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/collection_patch.dart"),
+  "convert": const LibraryInfo("convert/convert.dart",
+      categories: "Client,Server",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/convert_patch.dart"),
+  "core": const LibraryInfo("core/core.dart",
+      categories: "Client,Server,Embedded",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/core_patch.dart"),
+  "developer": const LibraryInfo("developer/developer.dart",
+      categories: "Client,Server,Embedded",
+      maturity: Maturity.UNSTABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/developer_patch.dart"),
+  "html": const LibraryInfo("html/dart2js/html_dart2js.dart",
+      categories: "Client",
+      maturity: Maturity.WEB_STABLE,
+      platforms: DART2JS_PLATFORM),
+  "html_common": const LibraryInfo("html/html_common/html_common.dart",
+      categories: "Client",
+      maturity: Maturity.WEB_STABLE,
+      dart2jsPath: "html/html_common/html_common_dart2js.dart",
+      documented: false,
+      implementation: true),
+  "indexed_db": const LibraryInfo("indexed_db/dart2js/indexed_db_dart2js.dart",
+      categories: "Client",
+      maturity: Maturity.WEB_STABLE,
+      platforms: DART2JS_PLATFORM),
+  "_http":
+      const LibraryInfo("_http/http.dart", categories: "", documented: false),
+  "io": const LibraryInfo("io/io.dart",
+      categories: "Server",
+      dart2jsPatchPath: "_internal/js_runtime/lib/io_patch.dart"),
+  "isolate": const LibraryInfo("isolate/isolate.dart",
+      categories: "Client,Server",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/isolate_patch.dart"),
+  "js": const LibraryInfo("js/dart2js/js_dart2js.dart",
+      categories: "Client",
+      maturity: Maturity.STABLE,
+      platforms: DART2JS_PLATFORM),
+  "js_util": const LibraryInfo("js_util/dart2js/js_util_dart2js.dart",
+      categories: "Client",
+      maturity: Maturity.STABLE,
+      platforms: DART2JS_PLATFORM),
+  "math": const LibraryInfo("math/math.dart",
+      categories: "Client,Server,Embedded",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/math_patch.dart"),
+  "mirrors": const LibraryInfo("mirrors/mirrors.dart",
+      categories: "Client,Server",
+      maturity: Maturity.UNSTABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/mirrors_patch.dart"),
+  "nativewrappers": const LibraryInfo("html/dartium/nativewrappers.dart",
+      categories: "Client",
+      implementation: true,
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+  "typed_data": const LibraryInfo("typed_data/typed_data.dart",
+      categories: "Client,Server,Embedded",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/typed_data_patch.dart"),
+  "_native_typed_data": const LibraryInfo(
+      "_internal/js_runtime/lib/native_typed_data.dart",
+      categories: "",
+      implementation: true,
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+  "cli": const LibraryInfo("cli/cli.dart",
+      categories: "Server",
+      dart2jsPatchPath: "_internal/js_runtime/lib/cli_patch.dart"),
+  "svg": const LibraryInfo("svg/dart2js/svg_dart2js.dart",
+      categories: "Client",
+      maturity: Maturity.WEB_STABLE,
+      platforms: DART2JS_PLATFORM),
+  "web_audio": const LibraryInfo("web_audio/dart2js/web_audio_dart2js.dart",
+      categories: "Client",
+      maturity: Maturity.WEB_STABLE,
+      platforms: DART2JS_PLATFORM),
+  "web_gl": const LibraryInfo("web_gl/dart2js/web_gl_dart2js.dart",
+      categories: "Client",
+      maturity: Maturity.WEB_STABLE,
+      platforms: DART2JS_PLATFORM),
+  "web_sql": const LibraryInfo("web_sql/dart2js/web_sql_dart2js.dart",
+      categories: "Client",
+      maturity: Maturity.WEB_STABLE,
+      platforms: DART2JS_PLATFORM),
+  "_internal": const LibraryInfo("internal/internal.dart",
+      categories: "",
+      documented: false,
+      dart2jsPatchPath: "_internal/js_runtime/lib/internal_patch.dart"),
+  "_js_helper": const LibraryInfo("_internal/js_runtime/lib/js_helper.dart",
+      categories: "", documented: false, platforms: DART2JS_PLATFORM),
+  "_interceptors": const LibraryInfo(
+      "_internal/js_runtime/lib/interceptors.dart",
+      categories: "",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+  "_foreign_helper": const LibraryInfo(
+      "_internal/js_runtime/lib/foreign_helper.dart",
+      categories: "",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+  "_isolate_helper": const LibraryInfo(
+      "_internal/js_runtime/lib/isolate_helper.dart",
+      categories: "",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+  "_js_mirrors": const LibraryInfo("_internal/js_runtime/lib/js_mirrors.dart",
+      categories: "", documented: false, platforms: DART2JS_PLATFORM),
+  "_js_primitives": const LibraryInfo(
+      "_internal/js_runtime/lib/js_primitives.dart",
+      categories: "",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+  "_metadata": const LibraryInfo("html/html_common/metadata.dart",
+      categories: "", documented: false, platforms: DART2JS_PLATFORM),
+  "_debugger": const LibraryInfo("_internal/js_runtime/lib/debugger.dart",
+      category: "", documented: false, platforms: DART2JS_PLATFORM),
+  "_runtime": const LibraryInfo(
+      "_internal/js_runtime/lib/ddc_runtime/runtime.dart",
+      category: "",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+};
+
+/**
+ * Information about a "dart:" library.
+ */
+class LibraryInfo {
+  /**
+   * Path to the library's *.dart file relative to this file.
+   */
+  final String path;
+
+  /**
+   * The categories in which the library can be used encoded as a
+   * comma-separated String.
+   */
+  final String _categories;
+
+  /**
+   * Path to the dart2js library's *.dart file relative to this file
+   * or null if dart2js uses the common library path defined above.
+   * Access using the [#getDart2JsPath()] method.
+   */
+  final String dart2jsPath;
+
+  /**
+   * Path to the dart2js library's patch file relative to this file
+   * or null if no dart2js patch file associated with this library.
+   * Access using the [#getDart2JsPatchPath()] method.
+   */
+  final String dart2jsPatchPath;
+
+  /**
+   * True if this library is documented and should be shown to the user.
+   */
+  final bool documented;
+
+  /**
+   * Bit flags indicating which platforms consume this library.
+   * See [DART2JS_LIBRARY] and [VM_LIBRARY].
+   */
+  final int platforms;
+
+  /**
+   * True if the library contains implementation details for another library.
+   * The implication is that these libraries are less commonly used
+   * and that tools like Dart Editor should not show these libraries
+   * in a list of all libraries unless the user specifically asks the tool to
+   * do so.
+   */
+  final bool implementation;
+
+  /**
+   * States the current maturity of this library.
+   */
+  final Maturity maturity;
+
+  const LibraryInfo(this.path,
+      {String categories: "",
+      this.dart2jsPath,
+      this.dart2jsPatchPath,
+      this.implementation: false,
+      this.documented: true,
+      this.maturity: Maturity.UNSPECIFIED,
+      this.platforms: DART2JS_PLATFORM | VM_PLATFORM})
+      : _categories = categories;
+
+  bool get isDart2jsLibrary => (platforms & DART2JS_PLATFORM) != 0;
+  bool get isVmLibrary => (platforms & VM_PLATFORM) != 0;
+
+  /**
+   * The categories in which the library can be used.
+   *
+   * If no categories are specified, the library is internal and can not be
+   * loaded by user code.
+   */
+  List<Category> get categories {
+    // `"".split(,)` returns [""] not [], so we handle that case separately.
+    if (_categories == "") return const <Category>[];
+    return _categories.split(",").map(parseCategory).toList();
+  }
+
+  bool get isInternal => categories.isEmpty;
+
+  /// The original "categories" String that was passed to the constructor.
+  ///
+  /// Can be used to construct a slightly modified copy of this LibraryInfo.
+  String get categoriesString {
+    return _categories;
+  }
+}
+
+/**
+ * Abstraction to capture the maturity of a library.
+ */
+class Maturity {
+  final int level;
+  final String name;
+  final String description;
+
+  const Maturity(this.level, this.name, this.description);
+
+  String toString() => "$name: $level\n$description\n";
+
+  static const Maturity DEPRECATED = const Maturity(0, "Deprecated",
+      "This library will be remove before next major release.");
+
+  static const Maturity EXPERIMENTAL = const Maturity(
+      1,
+      "Experimental",
+      "This library is experimental and will likely change or be removed\n"
+          "in future versions.");
+
+  static const Maturity UNSTABLE = const Maturity(
+      2,
+      "Unstable",
+      "This library is in still changing and have not yet endured\n"
+          "sufficient real-world testing.\n"
+          "Backwards-compatibility is NOT guaranteed.");
+
+  static const Maturity WEB_STABLE = const Maturity(
+      3,
+      "Web Stable",
+      "This library is tracking the DOM evolution as defined by WC3.\n"
+          "Backwards-compatibility is NOT guaranteed.");
+
+  static const Maturity STABLE = const Maturity(
+      4,
+      "Stable",
+      "The library is stable. API backwards-compatibility is guaranteed.\n"
+          "However implementation details might change.");
+
+  static const Maturity LOCKED = const Maturity(5, "Locked",
+      "This library will not change except when serious bugs are encountered.");
+
+  static const Maturity UNSPECIFIED = const Maturity(-1, "Unspecified",
+      "The maturity for this library has not been specified.");
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/async_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/async_patch.dart
new file mode 100644
index 0000000..894aef4
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/async_patch.dart
@@ -0,0 +1,472 @@
+// Copyright (c) 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.
+
+// Patch file for the dart:async library.
+
+import 'dart:_js_helper' show notNull, patch, ReifyFunctionTypes;
+import 'dart:_isolate_helper' show TimerImpl;
+import 'dart:_foreign_helper' show JS, JSExportName;
+import 'dart:_runtime' as dart;
+
+/// This function adapts ES6 generators to implement Dart's async/await.
+///
+/// It's designed to interact with Dart's Future and follow Dart async/await
+/// semantics.
+///
+/// See https://github.com/dart-lang/sdk/issues/27315 for ideas on reconciling
+/// Dart's Future and ES6 Promise. At that point we should use native JS
+/// async/await.
+///
+/// Inspired by `co`: https://github.com/tj/co/blob/master/index.js, which is a
+/// stepping stone for ES async/await.
+@JSExportName('async')
+@ReifyFunctionTypes(false)
+_async<T>(Function() initGenerator) {
+  var iter;
+  Object Function(Object) onValue;
+  Object Function(Object, StackTrace) onError;
+
+  onAwait(Object value) {
+    _Future f;
+    if (value is _Future) {
+      f = value;
+    } else if (value is Future) {
+      f = _Future();
+      _Future._chainForeignFuture(value, f);
+    } else {
+      f = _Future.value(value);
+    }
+    f = JS('', '#', f._thenAwait(onValue, onError));
+    return f;
+  }
+
+  onValue = (value) {
+    var iteratorResult = JS('', '#.next(#)', iter, value);
+    value = JS('', '#.value', iteratorResult);
+    return JS<bool>('!', '#.done', iteratorResult) ? value : onAwait(value);
+  };
+
+  // If the awaited Future throws, we want to convert this to an exception
+  // thrown from the `yield` point, as if it was thrown there.
+  //
+  // If the exception is not caught inside `gen`, it will emerge here, which
+  // will send it to anyone listening on this async function's Future<T>.
+  //
+  // In essence, we are giving the code inside the generator a chance to
+  // use try-catch-finally.
+  onError = (value, stackTrace) {
+    var iteratorResult = JS(
+        '', '#.throw(#)', iter, dart.createErrorWithStack(value, stackTrace));
+    value = JS('', '#.value', iteratorResult);
+    return JS<bool>('!', '#.done', iteratorResult) ? value : onAwait(value);
+  };
+
+  var zone = Zone.current;
+  if (!identical(zone, _rootZone)) {
+    onValue = zone.registerUnaryCallback(onValue);
+    onError = zone.registerBinaryCallback(onError);
+  }
+
+  var asyncFuture = _Future<T>();
+
+  // This will be set to true once we've yielded to the event loop.
+  //
+  // Before we've done that, we need to complete the future asynchronously to
+  // match dart2js/VM. See https://github.com/dart-lang/sdk/issues/33330
+  //
+  // Once we've yielded to the event loop we can complete synchronously.
+  // Other implementations call this `isSync` to indicate that.
+  bool isRunningAsEvent = false;
+  runBody() {
+    try {
+      iter = JS('', '#[Symbol.iterator]()', initGenerator());
+      var iteratorValue = JS('', '#.next(null)', iter);
+      var value = JS('', '#.value', iteratorValue);
+      if (JS<bool>('!', '#.done', iteratorValue)) {
+        // TODO(jmesserly): this is a workaround for ignored cast failures.
+        // Remove it once we've fixed those. We should be able to call:
+        //
+        //     if (isRunningAsEvent) {
+        //       asyncFuture._complete(value);
+        //     } else {
+        //       asyncFuture._asyncComplete(value);
+        //     }
+        //
+        // But if the user code returns `Future<dynamic>` instead of
+        // `Future<T>`, that function won't recognize it as a future and will
+        // instead treat it as a completed value.
+        if (value is Future) {
+          if (value is _Future) {
+            _Future._chainCoreFuture(value, asyncFuture);
+          } else {
+            _Future._chainForeignFuture(value, asyncFuture);
+          }
+        } else if (isRunningAsEvent) {
+          asyncFuture._completeWithValue(JS('', '#', value));
+        } else {
+          asyncFuture._asyncComplete(JS('', '#', value));
+        }
+      } else {
+        _Future._chainCoreFuture(onAwait(value), asyncFuture);
+      }
+    } catch (e, s) {
+      if (isRunningAsEvent) {
+        _completeWithErrorCallback(asyncFuture, e, s);
+      } else {
+        _asyncCompleteWithErrorCallback(asyncFuture, e, s);
+      }
+    }
+  }
+
+  if (dart.startAsyncSynchronously) {
+    runBody();
+    isRunningAsEvent = true;
+  } else {
+    isRunningAsEvent = true;
+    scheduleMicrotask(runBody);
+  }
+  return asyncFuture;
+}
+
+@patch
+class _AsyncRun {
+  @patch
+  static void _scheduleImmediate(void Function() callback) {
+    _scheduleImmediateClosure(callback);
+  }
+
+  // Lazily initialized.
+  static final _scheduleImmediateClosure = _initializeScheduleImmediate();
+
+  static void Function(void Function()) _initializeScheduleImmediate() {
+    // d8 support, see preambles/d8.js for the definiton of `scheduleImmediate`.
+    //
+    // TODO(jmesserly): do we need this? It's only for our d8 stack trace test.
+    if (JS('', '#.scheduleImmediate', dart.global_) != null) {
+      return _scheduleImmediateJSOverride;
+    }
+    return _scheduleImmediateWithPromise;
+  }
+
+  @ReifyFunctionTypes(false)
+  static void _scheduleImmediateJSOverride(void Function() callback) {
+    dart.addAsyncCallback();
+    JS('void', '#.scheduleImmediate(#)', dart.global_, () {
+      dart.removeAsyncCallback();
+      callback();
+    });
+  }
+
+  @ReifyFunctionTypes(false)
+  static Object _scheduleImmediateWithPromise(void Function() callback) {
+    dart.addAsyncCallback();
+    JS('', '#.Promise.resolve(null).then(#)', dart.global_, () {
+      dart.removeAsyncCallback();
+      callback();
+    });
+  }
+}
+
+@patch
+class DeferredLibrary {
+  @patch
+  Future<Null> load() {
+    throw 'DeferredLibrary not supported. '
+        'please use the `import "lib.dart" deferred as lib` syntax.';
+  }
+}
+
+@patch
+class Timer {
+  @patch
+  static Timer _createTimer(Duration duration, void callback()) {
+    int milliseconds = duration.inMilliseconds;
+    if (milliseconds < 0) milliseconds = 0;
+    return TimerImpl(milliseconds, callback);
+  }
+
+  @patch
+  static Timer _createPeriodicTimer(
+      Duration duration, void callback(Timer timer)) {
+    int milliseconds = duration.inMilliseconds;
+    if (milliseconds < 0) milliseconds = 0;
+    return TimerImpl.periodic(milliseconds, callback);
+  }
+}
+
+@patch
+void _rethrow(Object error, StackTrace stackTrace) {
+  JS('', 'throw #', dart.createErrorWithStack(error, stackTrace));
+}
+
+/// Used by the compiler to implement `async*` functions.
+///
+/// This is inspired by _AsyncStarStreamController in dart-lang/sdk's
+/// runtime/lib/core_patch.dart
+///
+/// Given input like:
+///
+///     foo() async* {
+///       yield 1;
+///       yield* bar();
+///       print(await baz());
+///     }
+///
+/// This compiles to:
+///
+///     function foo() {
+///       return new (AsyncStarImplOfT()).new(function*(stream) {
+///         if (stream.add(1)) return;
+///         yield;
+///         if (stream.addStream(bar()) return;
+///         yield;
+///         print(yield baz());
+///      });
+///     }
+///
+class _AsyncStarImpl<T> {
+  StreamController<T> controller;
+  Object Function(_AsyncStarImpl<T>) initGenerator;
+  @notNull
+  bool isSuspendedAtYieldStar = false;
+  @notNull
+  bool onListenReceived = false;
+  @notNull
+  bool isScheduled = false;
+  @notNull
+  bool isSuspendedAtYield = false;
+
+  /// Whether we're suspended at an `await`.
+  @notNull
+  bool isSuspendedAtAwait = false;
+
+  Completer cancellationCompleter;
+  Object jsIterator;
+
+  Null Function(Object, StackTrace) _handleErrorCallback;
+  void Function([Object]) _runBodyCallback;
+
+  _AsyncStarImpl(this.initGenerator) {
+    controller = StreamController(
+        onListen: JS('!', 'this.onListen.bind(this)'),
+        onResume: JS('!', 'this.onResume.bind(this)'),
+        onCancel: JS('!', 'this.onCancel.bind(this)'));
+    jsIterator = JS('!', '#[Symbol.iterator]()', initGenerator(this));
+  }
+
+  /// The stream produced by this `async*` function.
+  Stream<T> get stream => controller.stream;
+
+  /// Returns the callback used for error handling.
+  ///
+  /// This callback throws the error back into the user code, at the appropriate
+  /// location (e.g. `await` `yield` or `yield*`). This gives user code a chance
+  /// to handle it try-catch. If they do not handle, the error gets routed to
+  /// the [stream] as an error via [addError].
+  ///
+  /// As a performance optimization, this callback is only bound once to the
+  /// current [Zone]. This works because a single subscription stream should
+  /// always be running in its original zone. An `async*` method will always
+  /// save/restore the zone that was active when `listen()` was first called,
+  /// similar to a stream. This follows from section 16.14 of the Dart 4th
+  /// edition spec:
+  ///
+  /// > If `f` is marked `async*` (9), then a fresh instance `s` implementing
+  /// > the built-in class `Stream` is associated with the invocation and
+  /// > immediately returned. When `s` is listened to, execution of the body of
+  /// > `f` will begin.
+  ///
+  Null Function(Object, StackTrace) get handleError {
+    if (_handleErrorCallback == null) {
+      _handleErrorCallback = (error, StackTrace stackTrace) {
+        try {
+          JS('', '#.throw(#)', jsIterator,
+              dart.createErrorWithStack(error, stackTrace));
+        } catch (e, newStack) {
+          // The generator didn't catch the error, or it threw a new one.
+          // Make sure to propagate the new error.
+          addError(e, newStack);
+        }
+      };
+      var zone = Zone.current;
+      if (!identical(zone, Zone.root)) {
+        _handleErrorCallback = zone.bindBinaryCallback(_handleErrorCallback);
+      }
+    }
+    return _handleErrorCallback;
+  }
+
+  void scheduleGenerator() {
+    // TODO(jmesserly): is this isPaused check in the right place? Assuming the
+    // async* Stream yields, then is paused (by other code), the body will
+    // already be scheduled. This will cause at least one more iteration to
+    // run (adding another data item to the Stream) before actually pausing.
+    // It could be fixed by moving the `isPaused` check inside `runBody`.
+    if (isScheduled ||
+        controller.isPaused ||
+        isSuspendedAtYieldStar ||
+        isSuspendedAtAwait) {
+      return;
+    }
+    isScheduled = true;
+    // Capture the current zone. See comment on [handleError] for more
+    // information about this optimization.
+    var zone = Zone.current;
+    if (_runBodyCallback == null) {
+      _runBodyCallback = JS('!', '#.bind(this)', runBody);
+      if (!identical(zone, Zone.root)) {
+        var registered = zone.registerUnaryCallback(_runBodyCallback);
+        _runBodyCallback = ([arg]) => zone.runUnaryGuarded(registered, arg);
+      }
+    }
+    zone.scheduleMicrotask(_runBodyCallback);
+  }
+
+  void runBody(awaitValue) {
+    isScheduled = false;
+    isSuspendedAtYield = false;
+    isSuspendedAtAwait = false;
+
+    Object iterResult;
+    try {
+      iterResult = JS('', '#.next(#)', jsIterator, awaitValue);
+    } catch (e, s) {
+      addError(e, s);
+      return null;
+    }
+
+    if (JS('!', '#.done', iterResult)) {
+      close();
+      return null;
+    }
+
+    // If we're suspended at a yield/yield*, we're done for now.
+    if (isSuspendedAtYield || isSuspendedAtYieldStar) return null;
+
+    // Handle `await`: if we get a value passed to `yield` it means we are
+    // waiting on this Future. Make sure to prevent scheduling, and pass the
+    // value back as the result of the `yield`.
+    //
+    // TODO(jmesserly): is the timing here correct? The assumption here is
+    // that we should schedule `await` in `async*` the same as in `async`.
+    isSuspendedAtAwait = true;
+    FutureOr<Object> value = JS('', '#.value', iterResult);
+
+    // TODO(jmesserly): this logic was copied from `async` function impl.
+    _Future f;
+    if (value is _Future) {
+      f = value;
+    } else if (value is Future) {
+      f = _Future();
+      _Future._chainForeignFuture(value, f);
+    } else {
+      f = _Future.value(value);
+    }
+    f._thenAwait(_runBodyCallback, handleError);
+  }
+
+  /// Adds element to [stream] and returns true if the caller should terminate
+  /// execution of the generator.
+  ///
+  /// This is called from generated code like this:
+  ///
+  ///     if (controller.add(1)) return;
+  ///     yield;
+  //
+  // TODO(hausner): Per spec, the generator should be suspended before exiting
+  // when the stream is closed. We could add a getter like this:
+  //
+  //     get isCancelled => controller.hasListener;
+  //
+  // The generator would translate a 'yield e' statement to
+  //
+  //     controller.add(1);
+  //     suspend; // this is `yield` in JS.
+  //     if (controller.isCancelled) return;
+  bool add(T event) {
+    if (!onListenReceived) _fatal("yield before stream is listened to");
+    if (isSuspendedAtYield) _fatal("unexpected yield");
+    // If stream is cancelled, tell caller to exit the async generator.
+    if (!controller.hasListener) {
+      return true;
+    }
+    controller.add(event);
+    scheduleGenerator();
+    isSuspendedAtYield = true;
+    return false;
+  }
+
+  /// Adds the elements of [stream] into this [controller]'s stream, and returns
+  /// true if the caller should terminate execution of the generator.
+  ///
+  /// The generator will be scheduled again when all of the elements of the
+  /// added stream have been consumed.
+  bool addStream(Stream<T> stream) {
+    if (!onListenReceived) _fatal("yield* before stream is listened to");
+    // If stream is cancelled, tell caller to exit the async generator.
+    if (!controller.hasListener) return true;
+    isSuspendedAtYieldStar = true;
+    var whenDoneAdding = controller.addStream(stream, cancelOnError: false);
+    whenDoneAdding.then((_) {
+      isSuspendedAtYieldStar = false;
+      scheduleGenerator();
+      if (!isScheduled) isSuspendedAtYield = true;
+    }, onError: handleError);
+    return false;
+  }
+
+  void addError(Object error, StackTrace stackTrace) {
+    if (cancellationCompleter != null && !cancellationCompleter.isCompleted) {
+      // If the stream has been cancelled, complete the cancellation future
+      // with the error.
+      cancellationCompleter.completeError(error, stackTrace);
+    } else if (controller.hasListener) {
+      controller.addError(error, stackTrace);
+    }
+    // No need to schedule the generator body here. This code is only
+    // called from the catch clause of the implicit try-catch-finally
+    // around the generator body. That is, we are on the error path out
+    // of the generator and do not need to run the generator again.
+    close();
+  }
+
+  void close() {
+    if (cancellationCompleter != null && !cancellationCompleter.isCompleted) {
+      // If the stream has been cancelled, complete the cancellation future
+      // with the error.
+      cancellationCompleter.complete();
+    }
+    controller.close();
+  }
+
+  onListen() {
+    assert(!onListenReceived);
+    onListenReceived = true;
+    scheduleGenerator();
+  }
+
+  onResume() {
+    if (isSuspendedAtYield) {
+      scheduleGenerator();
+    }
+  }
+
+  onCancel() {
+    if (controller.isClosed) {
+      return null;
+    }
+    if (cancellationCompleter == null) {
+      cancellationCompleter = Completer();
+      // Only resume the generator if it is suspended at a yield.
+      // Cancellation does not affect an async generator that is
+      // suspended at an await.
+      if (isSuspendedAtYield) {
+        scheduleGenerator();
+      }
+    }
+    return cancellationCompleter.future;
+  }
+
+  _fatal(String message) => throw StateError(message);
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/cli_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/cli_patch.dart
new file mode 100644
index 0000000..b1c3841
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/cli_patch.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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:_js_helper' show patch;
+
+@patch
+void _waitForEvent(int timeoutMillis) {
+  throw UnsupportedError("waitForEvent");
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/collection_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/collection_patch.dart
new file mode 100644
index 0000000..daa3bf8
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/collection_patch.dart
@@ -0,0 +1,602 @@
+// 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.
+
+// Patch file for dart:collection classes.
+import 'dart:_foreign_helper' show JS, JSExportName;
+import 'dart:_runtime' as dart;
+import 'dart:_interceptors' show JSArray;
+import 'dart:_js_helper'
+    show
+        NoInline,
+        NoSideEffects,
+        NoThrows,
+        patch,
+        LinkedMap,
+        IdentityMap,
+        CustomHashMap,
+        CustomKeyHashMap,
+        DartIterator,
+        notNull,
+        putLinkedMapKey;
+
+@patch
+class HashMap<K, V> {
+  @patch
+  factory HashMap(
+      {bool equals(K key1, K key2),
+      int hashCode(K key),
+      bool isValidKey(Object potentialKey)}) {
+    if (isValidKey == null) {
+      if (hashCode == null) {
+        if (equals == null) {
+          if (identical(K, String) || identical(K, int)) {
+            return IdentityMap<K, V>();
+          }
+          return LinkedMap<K, V>();
+        }
+        hashCode = dart.hashCode;
+      } else if (identical(identityHashCode, hashCode) &&
+          identical(identical, equals)) {
+        return IdentityMap<K, V>();
+      }
+      return CustomHashMap<K, V>(equals ?? dart.equals, hashCode);
+    }
+    return CustomKeyHashMap<K, V>(
+        equals ?? dart.equals, hashCode ?? dart.hashCode, isValidKey);
+  }
+
+  @patch
+  factory HashMap.identity() = IdentityMap<K, V>;
+}
+
+@patch
+class LinkedHashMap<K, V> {
+  @patch
+  factory LinkedHashMap(
+      {bool equals(K key1, K key2),
+      int hashCode(K key),
+      bool isValidKey(Object potentialKey)}) {
+    if (isValidKey == null) {
+      if (hashCode == null) {
+        if (equals == null) {
+          if (identical(K, String) || identical(K, int)) {
+            return IdentityMap<K, V>();
+          }
+          return LinkedMap<K, V>();
+        }
+        hashCode = dart.hashCode;
+      } else if (identical(identityHashCode, hashCode) &&
+          identical(identical, equals)) {
+        return IdentityMap<K, V>();
+      }
+      return CustomHashMap<K, V>(equals ?? dart.equals, hashCode);
+    }
+    return CustomKeyHashMap<K, V>(
+        equals ?? dart.equals, hashCode ?? dart.hashCode, isValidKey);
+  }
+
+  @patch
+  factory LinkedHashMap.identity() = IdentityMap<K, V>;
+}
+
+@patch
+class HashSet<E> {
+  @patch
+  factory HashSet(
+      {bool equals(E e1, E e2),
+      int hashCode(E e),
+      bool isValidKey(Object potentialKey)}) {
+    if (isValidKey == null) {
+      if (hashCode == null) {
+        if (equals == null) {
+          if (identical(E, String) || identical(E, int)) {
+            return _IdentityHashSet<E>();
+          }
+          return _HashSet<E>();
+        }
+        hashCode = dart.hashCode;
+      } else if (identical(identityHashCode, hashCode) &&
+          identical(identical, equals)) {
+        return _IdentityHashSet<E>();
+      }
+      return _CustomHashSet<E>(
+          equals ?? dart.equals, hashCode ?? dart.hashCode);
+    }
+    return _CustomKeyHashSet<E>(
+        equals ?? dart.equals, hashCode ?? dart.hashCode, isValidKey);
+  }
+
+  @patch
+  factory HashSet.identity() = _IdentityHashSet<E>;
+}
+
+@patch
+class LinkedHashSet<E> {
+  @patch
+  factory LinkedHashSet(
+      {bool equals(E e1, E e2),
+      int hashCode(E e),
+      bool isValidKey(Object potentialKey)}) {
+    if (isValidKey == null) {
+      if (hashCode == null) {
+        if (equals == null) {
+          if (identical(E, String) || identical(E, int)) {
+            return _IdentityHashSet<E>();
+          }
+          return _HashSet<E>();
+        }
+        hashCode = dart.hashCode;
+      } else if (identical(identityHashCode, hashCode) &&
+          identical(identical, equals)) {
+        return _IdentityHashSet<E>();
+      }
+      return _CustomHashSet<E>(
+          equals ?? dart.equals, hashCode ?? dart.hashCode);
+    }
+    return _CustomKeyHashSet<E>(
+        equals ?? dart.equals, hashCode ?? dart.hashCode, isValidKey);
+  }
+
+  @patch
+  factory LinkedHashSet.identity() = _IdentityHashSet<E>;
+}
+
+class _HashSet<E> extends _InternalSet<E>
+    implements HashSet<E>, LinkedHashSet<E> {
+  /// The backing store for this set.
+  ///
+  /// Keys that use identity equality are stored directly. For other types of
+  /// keys, we first look them up (by hashCode) in the [_keyMap] map, then
+  /// we lookup the key in this map.
+  @notNull
+  final _map = JS('', 'new Set()');
+
+  /// Items that use custom equality semantics.
+  ///
+  /// This maps from the item's hashCode to the canonical key, which is then
+  /// used to lookup the item in [_map]. Keeping the data in our primary backing
+  /// map gives us the ordering semantics requred by [LinkedHashMap], while
+  /// also providing convenient access to keys/values.
+  @notNull
+  final _keyMap = JS('', 'new Map()');
+
+  // We track the number of modifications done to the key set of the
+  // hash map to be able to throw when the map is modified while being
+  // iterated over.
+  //
+  // Value cycles after 2^30 modifications so that modification counts are
+  // always unboxed (Smi) values. Modification detection will be missed if you
+  // make exactly some multiple of 2^30 modifications between advances of an
+  // iterator.
+  @notNull
+  int _modifications = 0;
+
+  _HashSet();
+
+  Set<E> _newSet() => _HashSet<E>();
+
+  Set<R> _newSimilarSet<R>() => _HashSet<R>();
+
+  bool contains(Object key) {
+    if (key == null) {
+      key = null;
+    } else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
+        dart.identityEquals)) {
+      @notNull
+      var k = key;
+      var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode);
+      if (buckets != null) {
+        for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
+          k = JS('', '#[#]', buckets, i);
+          if (k == key) return true;
+        }
+      }
+      return false;
+    }
+    return JS<bool>('!', '#.has(#)', _map, key);
+  }
+
+  E lookup(Object key) {
+    if (key == null) return null;
+    if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
+        dart.identityEquals)) {
+      @notNull
+      var k = key;
+      var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode);
+      if (buckets != null) {
+        for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
+          k = JS('', '#[#]', buckets, i);
+          if (k == key) return JS('', '#', k);
+        }
+      }
+      return null;
+    }
+    return JS('', '#.has(#) ? # : null', _map, key, key);
+  }
+
+  bool add(E key) {
+    var map = _map;
+    if (key == null) {
+      if (JS('', '#.has(null)', map)) return false;
+      key = null;
+    } else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
+        dart.identityEquals)) {
+      var keyMap = _keyMap;
+      @notNull
+      var k = key;
+      int hash = JS('!', '# & 0x3ffffff', k.hashCode);
+      var buckets = JS('', '#.get(#)', keyMap, hash);
+      if (buckets == null) {
+        JS('', '#.set(#, [#])', keyMap, hash, key);
+      } else {
+        for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
+          k = JS('', '#[#]', buckets, i);
+          if (k == key) return false;
+        }
+        JS('', '#.push(#)', buckets, key);
+      }
+    } else if (JS('', '#.has(#)', map, key)) {
+      return false;
+    }
+    JS('', '#.add(#)', map, key);
+    _modifications = (_modifications + 1) & 0x3ffffff;
+    return true;
+  }
+
+  void addAll(Iterable<E> objects) {
+    var map = _map;
+    int length = JS('', '#.size', map);
+    for (E key in objects) {
+      if (key == null) {
+        key = null; // converts undefined to null, if needed.
+      } else if (JS<bool>('!', '#[#] !== #', key,
+          dart.extensionSymbol('_equals'), dart.identityEquals)) {
+        key = putLinkedMapKey(key, _keyMap);
+      }
+      JS('', '#.add(#)', map, key);
+    }
+    if (length != JS<int>('!', '#.size', map)) {
+      _modifications = (_modifications + 1) & 0x3ffffff;
+    }
+  }
+
+  bool remove(Object key) {
+    if (key == null) {
+      key = null;
+    } else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
+        dart.identityEquals)) {
+      @notNull
+      var k = key;
+      int hash = JS('!', '# & 0x3ffffff', k.hashCode);
+      var buckets = JS('', '#.get(#)', _keyMap, hash);
+      if (buckets == null) return false; // not found
+      for (int i = 0, n = JS('!', '#.length', buckets);;) {
+        k = JS('', '#[#]', buckets, i);
+        if (k == key) {
+          key = k;
+          if (n == 1) {
+            JS('', '#.delete(#)', _keyMap, hash);
+          } else {
+            JS('', '#.splice(#, 1)', buckets, i);
+          }
+          break;
+        }
+        if (++i >= n) return false; // not found
+      }
+    }
+    var map = _map;
+    if (JS<bool>('!', '#.delete(#)', map, key)) {
+      _modifications = (_modifications + 1) & 0x3ffffff;
+      return true;
+    }
+    return false;
+  }
+
+  void clear() {
+    var map = _map;
+    if (JS<int>('!', '#.size', map) > 0) {
+      JS('', '#.clear()', map);
+      JS('', '#.clear()', _keyMap);
+      _modifications = (_modifications + 1) & 0x3ffffff;
+    }
+  }
+}
+
+// Used for DDC const sets.
+class _ImmutableSet<E> extends _HashSet<E> {
+  _ImmutableSet.from(JSArray entries) {
+    var map = _map;
+    for (Object key in entries) {
+      if (key == null) {
+        key = null; // converts undefined to null, if needed.
+      } else if (JS<bool>('!', '#[#] !== #', key,
+          dart.extensionSymbol('_equals'), dart.identityEquals)) {
+        key = putLinkedMapKey(key, _keyMap);
+      }
+      JS('', '#.add(#)', map, key);
+    }
+  }
+
+  bool add(Object other) => throw _unsupported();
+  void addAll(Object other) => throw _unsupported();
+  void clear() => throw _unsupported();
+  bool remove(Object key) => throw _unsupported();
+
+  static Error _unsupported() =>
+      UnsupportedError("Cannot modify unmodifiable set");
+}
+
+class _IdentityHashSet<E> extends _InternalSet<E>
+    implements HashSet<E>, LinkedHashSet<E> {
+  /// The backing store for this set.
+  @notNull
+  final _map = JS('', 'new Set()');
+
+  @notNull
+  int _modifications = 0;
+
+  _IdentityHashSet();
+
+  Set<E> _newSet() => _IdentityHashSet<E>();
+
+  Set<R> _newSimilarSet<R>() => _IdentityHashSet<R>();
+
+  bool contains(Object element) {
+    return JS('', '#.has(#)', _map, element);
+  }
+
+  E lookup(Object element) {
+    return JS('', '#.has(#)', _map, element) ? element : null;
+  }
+
+  bool add(E element) {
+    var map = _map;
+    if (JS<bool>('!', '#.has(#)', map, element)) return false;
+    JS('', '#.add(#)', map, element);
+    _modifications = (_modifications + 1) & 0x3ffffff;
+    return true;
+  }
+
+  void addAll(Iterable<E> objects) {
+    var map = _map;
+    int length = JS('', '#.size', map);
+    for (E key in objects) {
+      JS('', '#.add(#)', map, key);
+    }
+    if (length != JS<int>('!', '#.size', map)) {
+      _modifications = (_modifications + 1) & 0x3ffffff;
+    }
+  }
+
+  bool remove(Object element) {
+    if (JS<bool>('!', '#.delete(#)', _map, element)) {
+      _modifications = (_modifications + 1) & 0x3ffffff;
+      return true;
+    }
+    return false;
+  }
+
+  void clear() {
+    var map = _map;
+    if (JS<int>('!', '#.size', map) > 0) {
+      JS('', '#.clear()', map);
+      _modifications = (_modifications + 1) & 0x3ffffff;
+    }
+  }
+}
+
+class _CustomKeyHashSet<E> extends _CustomHashSet<E> {
+  _Predicate<Object> _validKey;
+  _CustomKeyHashSet(_Equality<E> equals, _Hasher<E> hashCode, this._validKey)
+      : super(equals, hashCode);
+
+  Set<E> _newSet() => _CustomKeyHashSet<E>(_equals, _hashCode, _validKey);
+
+  Set<R> _newSimilarSet<R>() => _HashSet<R>();
+
+  bool contains(Object element) {
+    // TODO(jmesserly): there is a subtle difference here compared to Dart 1.
+    // See the comment on CustomKeyHashMap.containsKey for more information.
+    // Treatment of `null` is different due to strong mode's requirement to
+    // perform an `element is E` check before calling equals/hashCode.
+    if (!_validKey(element)) return false;
+    return super.contains(element);
+  }
+
+  E lookup(Object element) {
+    if (!_validKey(element)) return null;
+    return super.lookup(element);
+  }
+
+  bool remove(Object element) {
+    if (!_validKey(element)) return false;
+    return super.remove(element);
+  }
+}
+
+class _CustomHashSet<E> extends _InternalSet<E>
+    implements HashSet<E>, LinkedHashSet<E> {
+  _Equality<E> _equals;
+  _Hasher<E> _hashCode;
+
+  // We track the number of modifications done to the key set of the
+  // hash map to be able to throw when the map is modified while being
+  // iterated over.
+  //
+  // Value cycles after 2^30 modifications so that modification counts are
+  // always unboxed (Smi) values. Modification detection will be missed if you
+  // make exactly some multiple of 2^30 modifications between advances of an
+  // iterator.
+  @notNull
+  int _modifications = 0;
+
+  /// The backing store for this set, used to handle ordering.
+  // TODO(jmesserly): a non-linked custom hash set could skip this.
+  @notNull
+  final _map = JS('', 'new Set()');
+
+  /// Our map used to map keys onto the canonical key that is stored in [_map].
+  @notNull
+  final _keyMap = JS('', 'new Map()');
+
+  _CustomHashSet(this._equals, this._hashCode);
+
+  Set<E> _newSet() => _CustomHashSet<E>(_equals, _hashCode);
+  Set<R> _newSimilarSet<R>() => _HashSet<R>();
+
+  bool contains(Object key) {
+    if (key is E) {
+      var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key));
+      if (buckets != null) {
+        var equals = _equals;
+        for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
+          E k = JS('', '#[#]', buckets, i);
+          if (equals(k, key)) return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  E lookup(Object key) {
+    if (key is E) {
+      var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key));
+      if (buckets != null) {
+        var equals = _equals;
+        for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
+          E k = JS('', '#[#]', buckets, i);
+          if (equals(k, key)) return k;
+        }
+      }
+    }
+    return null;
+  }
+
+  bool add(E key) {
+    var keyMap = _keyMap;
+    var hash = JS<int>('!', '# & 0x3ffffff', _hashCode(key));
+    var buckets = JS('', '#.get(#)', keyMap, hash);
+    if (buckets == null) {
+      JS('', '#.set(#, [#])', keyMap, hash, key);
+    } else {
+      var equals = _equals;
+      for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
+        E k = JS('', '#[#]', buckets, i);
+        if (equals(k, key)) return false;
+      }
+      JS('', '#.push(#)', buckets, key);
+    }
+    JS('', '#.add(#)', _map, key);
+    _modifications = (_modifications + 1) & 0x3ffffff;
+    return true;
+  }
+
+  void addAll(Iterable<E> objects) {
+    // TODO(jmesserly): it'd be nice to skip the covariance check here.
+    for (E element in objects) add(element);
+  }
+
+  bool remove(Object key) {
+    if (key is E) {
+      var hash = JS<int>('!', '# & 0x3ffffff', _hashCode(key));
+      var keyMap = _keyMap;
+      var buckets = JS('', '#.get(#)', keyMap, hash);
+      if (buckets == null) return false; // not found
+      var equals = _equals;
+      for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
+        E k = JS('', '#[#]', buckets, i);
+        if (equals(k, key)) {
+          if (n == 1) {
+            JS('', '#.delete(#)', keyMap, hash);
+          } else {
+            JS('', '#.splice(#, 1)', buckets, i);
+          }
+          JS('', '#.delete(#)', _map, k);
+          _modifications = (_modifications + 1) & 0x3ffffff;
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  void clear() {
+    var map = _map;
+    if (JS<int>('!', '#.size', map) > 0) {
+      JS('', '#.clear()', map);
+      JS('', '#.clear()', _keyMap);
+      _modifications = (_modifications + 1) & 0x3ffffff;
+    }
+  }
+}
+
+/// Base class for our internal [LinkedHashSet]/[HashSet] implementations.
+///
+/// This implements the common functionality.
+abstract class _InternalSet<E> extends _SetBase<E> {
+  @notNull
+  get _map;
+
+  @notNull
+  int get _modifications;
+
+  @notNull
+  int get length => JS<int>('!', '#.size', _map);
+
+  @notNull
+  bool get isEmpty => JS<bool>('!', '#.size == 0', _map);
+
+  @notNull
+  bool get isNotEmpty => JS<bool>('!', '#.size != 0', _map);
+
+  Iterator<E> get iterator => DartIterator<E>(_jsIterator());
+
+  @JSExportName('Symbol.iterator')
+  _jsIterator() {
+    var self = this;
+    var iterator = JS('', '#.values()', self._map);
+    int modifications = self._modifications;
+    return JS(
+        '',
+        '''{
+      next() {
+        if (# != #) {
+          throw #;
+        }
+        return #.next();
+      }
+    }''',
+        modifications,
+        self._modifications,
+        ConcurrentModificationError(self),
+        iterator);
+  }
+}
+
+@patch
+abstract class _SplayTree<K, Node extends _SplayTreeNode<K>> {
+  @patch
+  Node _splayMin(Node node) {
+    Node current = node;
+    while (current.left != null) {
+      Node left = current.left;
+      current.left = left.right;
+      left.right = current;
+      current = left;
+    }
+    return current;
+  }
+
+  @patch
+  Node _splayMax(Node node) {
+    Node current = node;
+    while (current.right != null) {
+      Node right = current.right;
+      current.right = right.left;
+      right.left = current;
+      current = right;
+    }
+    return current;
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.dart
new file mode 100644
index 0000000..486473b
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.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.
+
+// Patch file for dart:convert library.
+
+import 'dart:_js_helper' show argumentErrorValue, patch;
+import 'dart:_foreign_helper' show JS;
+import 'dart:_interceptors' show JSExtendableArray;
+import 'dart:_internal' show MappedIterable, ListIterable;
+import 'dart:collection' show Maps, LinkedHashMap, MapBase;
+import 'dart:_native_typed_data' show NativeUint8List;
+
+/**
+ * Parses [json] and builds the corresponding parsed JSON value.
+ *
+ * Parsed JSON values Nare of the types [num], [String], [bool], [Null],
+ * [List]s of parsed JSON values or [Map]s from [String] to parsed
+ * JSON values.
+ *
+ * The optional [reviver] function, if provided, is called once for each object
+ * or list property parsed. The arguments are the property name ([String]) or
+ * list index ([int]), and the value is the parsed value.  The return value of
+ * the reviver will be used as the value of that property instead of the parsed
+ * value.  The top level value is passed to the reviver with the empty string as
+ * a key.
+ *
+ * Throws [FormatException] if the input is not valid JSON text.
+ */
+@patch
+_parseJson(String source, reviver(Object key, Object value)) {
+  if (source is! String) throw argumentErrorValue(source);
+
+  var parsed;
+  try {
+    parsed = JS('=Object|JSExtendableArray|Null|bool|num|String',
+        'JSON.parse(#)', source);
+  } catch (e) {
+    throw FormatException(JS<String>('!', 'String(#)', e));
+  }
+
+  if (reviver == null) {
+    return _convertJsonToDartLazy(parsed);
+  } else {
+    return _convertJsonToDart(parsed, reviver);
+  }
+}
+
+/**
+ * Walks the raw JavaScript value [json], replacing JavaScript Objects with
+ * Maps. [json] is expected to be freshly allocated so elements can be replaced
+ * in-place.
+ */
+_convertJsonToDart(json, reviver(Object key, Object value)) {
+  assert(reviver != null);
+  walk(e) {
+    // JavaScript null, string, number, bool are in the correct representation.
+    if (JS<bool>('!', '# == null', e) ||
+        JS<bool>('!', 'typeof # != "object"', e)) {
+      return e;
+    }
+
+    // This test is needed to avoid identifying '{"__proto__":[]}' as an Array.
+    // TODO(sra): Replace this test with cheaper '#.constructor === Array' when
+    // bug 621 below is fixed.
+    if (JS<bool>('!', 'Object.getPrototypeOf(#) === Array.prototype', e)) {
+      // In-place update of the elements since JS Array is a Dart List.
+      for (int i = 0; i < JS<int>('!', '#.length', e); i++) {
+        // Use JS indexing to avoid range checks.  We know this is the only
+        // reference to the list, but the compiler will likely never be able to
+        // tell that this instance of the list cannot have its length changed by
+        // the reviver even though it later will be passed to the reviver at the
+        // outer level.
+        var item = JS('', '#[#]', e, i);
+        JS('', '#[#]=#', e, i, reviver(i, walk(item)));
+      }
+      return e;
+    }
+
+    // Otherwise it is a plain object, so copy to a JSON map, so we process
+    // and revive all entries recursively.
+    _JsonMap map = _JsonMap(e);
+    var processed = map._processed;
+    List<String> keys = map._computeKeys();
+    for (int i = 0; i < keys.length; i++) {
+      String key = keys[i];
+      var revived = reviver(key, walk(JS('', '#[#]', e, key)));
+      JS('', '#[#]=#', processed, key, revived);
+    }
+
+    // Update the JSON map structure so future access is cheaper.
+    map._original = processed; // Don't keep two objects around.
+    return map;
+  }
+
+  return reviver(null, walk(json));
+}
+
+_convertJsonToDartLazy(object) {
+  // JavaScript null and undefined are represented as null.
+  if (object == null) return null;
+
+  // JavaScript string, number, bool already has the correct representation.
+  if (JS<bool>('!', 'typeof # != "object"', object)) {
+    return object;
+  }
+
+  // This test is needed to avoid identifying '{"__proto__":[]}' as an array.
+  // TODO(sra): Replace this test with cheaper '#.constructor === Array' when
+  // bug https://code.google.com/p/v8/issues/detail?id=621 is fixed.
+  if (JS<bool>('!', 'Object.getPrototypeOf(#) !== Array.prototype', object)) {
+    return _JsonMap(object);
+  }
+
+  // Update the elements in place since JS arrays are Dart lists.
+  for (int i = 0; i < JS<int>('!', '#.length', object); i++) {
+    // Use JS indexing to avoid range checks.  We know this is the only
+    // reference to the list, but the compiler will likely never be able to
+    // tell that this instance of the list cannot have its length changed by
+    // the reviver even though it later will be passed to the reviver at the
+    // outer level.
+    var item = JS('', '#[#]', object, i);
+    JS('', '#[#]=#', object, i, _convertJsonToDartLazy(item));
+  }
+  return object;
+}
+
+class _JsonMap extends MapBase<String, dynamic> {
+  // The original JavaScript object remains unchanged until
+  // the map is eventually upgraded, in which case we null it
+  // out to reclaim the memory used by it.
+  var _original;
+
+  // We keep track of the map entries that we have already
+  // processed by adding them to a separate JavaScript object.
+  var _processed = _newJavaScriptObject();
+
+  // If the data slot isn't null, it represents either the list
+  // of keys (for non-upgraded JSON maps) or the upgraded map.
+  var _data = null;
+
+  _JsonMap(this._original);
+
+  operator [](key) {
+    if (_isUpgraded) {
+      return _upgradedMap[key];
+    } else if (key is! String) {
+      return null;
+    } else {
+      var result = _getProperty(_processed, key);
+      if (_isUnprocessed(result)) result = _process(key);
+      return result;
+    }
+  }
+
+  int get length => _isUpgraded ? _upgradedMap.length : _computeKeys().length;
+
+  bool get isEmpty => length == 0;
+  bool get isNotEmpty => length > 0;
+
+  Iterable<String> get keys {
+    if (_isUpgraded) return _upgradedMap.keys;
+    return _JsonMapKeyIterable(this);
+  }
+
+  Iterable get values {
+    if (_isUpgraded) return _upgradedMap.values;
+    return MappedIterable(_computeKeys(), (each) => this[each]);
+  }
+
+  operator []=(key, value) {
+    if (_isUpgraded) {
+      _upgradedMap[key] = value;
+    } else if (containsKey(key)) {
+      var processed = _processed;
+      _setProperty(processed, key, value);
+      var original = _original;
+      if (!identical(original, processed)) {
+        _setProperty(original, key, null); // Reclaim memory.
+      }
+    } else {
+      _upgrade()[key] = value;
+    }
+  }
+
+  void addAll(Map<String, dynamic> other) {
+    other.forEach((key, value) {
+      this[key] = value;
+    });
+  }
+
+  bool containsValue(value) {
+    if (_isUpgraded) return _upgradedMap.containsValue(value);
+    List<String> keys = _computeKeys();
+    for (int i = 0; i < keys.length; i++) {
+      String key = keys[i];
+      if (this[key] == value) return true;
+    }
+    return false;
+  }
+
+  bool containsKey(key) {
+    if (_isUpgraded) return _upgradedMap.containsKey(key);
+    if (key is! String) return false;
+    return _hasProperty(_original, key);
+  }
+
+  putIfAbsent(key, ifAbsent()) {
+    if (containsKey(key)) return this[key];
+    var value = ifAbsent();
+    this[key] = value;
+    return value;
+  }
+
+  remove(Object key) {
+    if (!_isUpgraded && !containsKey(key)) return null;
+    return _upgrade().remove(key);
+  }
+
+  void clear() {
+    if (_isUpgraded) {
+      _upgradedMap.clear();
+    } else {
+      if (_data != null) {
+        // Clear the list of keys to make sure we force
+        // a concurrent modification error if anyone is
+        // currently iterating over it.
+        _data.clear();
+      }
+      _original = _processed = null;
+      _data = {};
+    }
+  }
+
+  void forEach(void f(String key, value)) {
+    if (_isUpgraded) return _upgradedMap.forEach(f);
+    List<String> keys = _computeKeys();
+    for (int i = 0; i < keys.length; i++) {
+      String key = keys[i];
+
+      // Compute the value under the assumption that the property
+      // is present but potentially not processed.
+      var value = _getProperty(_processed, key);
+      if (_isUnprocessed(value)) {
+        value = _convertJsonToDartLazy(_getProperty(_original, key));
+        _setProperty(_processed, key, value);
+      }
+
+      // Do the callback.
+      f(key, value);
+
+      // Check if invoking the callback function changed
+      // the key set. If so, throw an exception.
+      if (!identical(keys, _data)) {
+        throw ConcurrentModificationError(this);
+      }
+    }
+  }
+
+  // ------------------------------------------
+  // Private helper methods.
+  // ------------------------------------------
+
+  bool get _isUpgraded => _processed == null;
+
+  Map<String, dynamic> get _upgradedMap {
+    assert(_isUpgraded);
+    // 'cast' the union type to LinkedHashMap.  It would be even better if we
+    // could 'cast' to the implementation type, since LinkedHashMap includes
+    // _JsonMap.
+    return JS('LinkedHashMap', '#', _data);
+  }
+
+  List<String> _computeKeys() {
+    assert(!_isUpgraded);
+    List keys = _data;
+    if (keys == null) {
+      keys = _data = _getPropertyNames(_original);
+    }
+    return JS('JSExtendableArray', '#', keys);
+  }
+
+  Map<String, dynamic> _upgrade() {
+    if (_isUpgraded) return _upgradedMap;
+
+    // Copy all the (key, value) pairs to a freshly allocated
+    // linked hash map thus preserving the ordering.
+    var result = <String, dynamic>{};
+    List<String> keys = _computeKeys();
+    for (int i = 0; i < keys.length; i++) {
+      String key = keys[i];
+      result[key] = this[key];
+    }
+
+    // We only upgrade when we need to extend the map, so we can
+    // safely force a concurrent modification error in case
+    // someone is iterating over the map here.
+    if (keys.isEmpty) {
+      keys.add(null);
+    } else {
+      keys.clear();
+    }
+
+    // Clear out the associated JavaScript objects and mark the
+    // map as having been upgraded.
+    _original = _processed = null;
+    _data = result;
+    assert(_isUpgraded);
+    return result;
+  }
+
+  _process(String key) {
+    if (!_hasProperty(_original, key)) return null;
+    var result = _convertJsonToDartLazy(_getProperty(_original, key));
+    return _setProperty(_processed, key, result);
+  }
+
+  // ------------------------------------------
+  // Private JavaScript helper methods.
+  // ------------------------------------------
+
+  static bool _hasProperty(object, String key) =>
+      JS<bool>('!', 'Object.prototype.hasOwnProperty.call(#,#)', object, key);
+  static _getProperty(object, String key) => JS('', '#[#]', object, key);
+  static _setProperty(object, String key, value) =>
+      JS('', '#[#]=#', object, key, value);
+  static List _getPropertyNames(object) =>
+      JS('JSExtendableArray', 'Object.keys(#)', object);
+  static bool _isUnprocessed(object) =>
+      JS<bool>('!', 'typeof(#)=="undefined"', object);
+  static _newJavaScriptObject() => JS('=Object', 'Object.create(null)');
+}
+
+class _JsonMapKeyIterable extends ListIterable<String> {
+  final _JsonMap _parent;
+
+  _JsonMapKeyIterable(this._parent);
+
+  int get length => _parent.length;
+
+  String elementAt(int index) {
+    return _parent._isUpgraded
+        ? _parent.keys.elementAt(index)
+        : _parent._computeKeys()[index];
+  }
+
+  /// Although [ListIterable] defines its own iterator, we return the iterator
+  /// of the underlying list [_keys] in order to propagate
+  /// [ConcurrentModificationError]s.
+  Iterator<String> get iterator {
+    return _parent._isUpgraded
+        ? _parent.keys.iterator
+        : _parent._computeKeys().iterator;
+  }
+
+  /// Delegate to [parent.containsKey] to ensure the performance expected
+  /// from [Map.keys.containsKey].
+  bool contains(Object key) => _parent.containsKey(key);
+}
+
+@patch
+class JsonDecoder {
+  @patch
+  StringConversionSink startChunkedConversion(Sink<Object> sink) {
+    return _JsonDecoderSink(_reviver, sink);
+  }
+}
+
+/**
+ * Implements the chunked conversion from a JSON string to its corresponding
+ * object.
+ *
+ * The sink only creates one object, but its input can be chunked.
+ */
+// TODO(floitsch): don't accumulate everything before starting to decode.
+class _JsonDecoderSink extends _StringSinkConversionSink {
+  final Function(Object key, Object value) _reviver;
+  final Sink<Object> _sink;
+
+  _JsonDecoderSink(this._reviver, this._sink) : super(StringBuffer(''));
+
+  void close() {
+    super.close();
+    StringBuffer buffer = _stringSink;
+    String accumulated = buffer.toString();
+    buffer.clear();
+    Object decoded = _parseJson(accumulated, _reviver);
+    _sink.add(decoded);
+    _sink.close();
+  }
+}
+
+@patch
+class Utf8Decoder {
+  @patch
+  Converter<List<int>, T> fuse<T>(Converter<String, T> next) {
+    return super.fuse(next);
+  }
+
+  // Currently not intercepting UTF8 decoding.
+  @patch
+  static String _convertIntercepted(
+      bool allowMalformed, List<int> codeUnits, int start, int end) {
+    // Test `codeUnits is NativeUint8List`. Dart's NativeUint8List is
+    // implemented by JavaScript's Uint8Array.
+    if (JS<bool>('!', '# instanceof Uint8Array', codeUnits)) {
+      // JS 'cast' to avoid a downcast equivalent to the is-check we hand-coded.
+      NativeUint8List casted = JS<NativeUint8List>('!', '#', codeUnits);
+      return _convertInterceptedUint8List(allowMalformed, casted, start, end);
+    }
+  }
+
+  static String _convertInterceptedUint8List(
+      bool allowMalformed, NativeUint8List codeUnits, int start, int end) {
+    if (allowMalformed) {
+      // TextDecoder with option {fatal: false} does not produce the same result
+      // as [Utf8Decoder]. It disagrees on the number of `U+FFFD` (REPLACEMENT
+      // CHARACTER) generated for some malformed sequences. We could use
+      // TextDecoder with option {fatal: true}, catch the error, and re-try
+      // without acceleration. That turns out to be extremely slow (the Error
+      // captures a stack trace).
+      // TODO(31370): Bring Utf8Decoder into alignment with TextDecoder.
+      // TODO(sra): If we can't do that, can we detect valid input fast enough
+      // to use a check like the [_unsafe] check below?
+      return null;
+    }
+
+    var decoder = _decoder;
+    if (decoder == null) return null;
+    if (0 == start && end == null) {
+      return _useTextDecoderChecked(decoder, codeUnits);
+    }
+
+    int length = codeUnits.length;
+    end = RangeError.checkValidRange(start, end, length);
+
+    if (0 == start && end == codeUnits.length) {
+      return _useTextDecoderChecked(decoder, codeUnits);
+    }
+
+    return _useTextDecoderChecked(decoder,
+        JS<NativeUint8List>('!', '#.subarray(#, #)', codeUnits, start, end));
+  }
+
+  static String _useTextDecoderChecked(decoder, NativeUint8List codeUnits) {
+    if (_unsafe(codeUnits)) return null;
+    return _useTextDecoderUnchecked(decoder, codeUnits);
+  }
+
+  static String _useTextDecoderUnchecked(decoder, NativeUint8List codeUnits) {
+    // If the input is malformed, catch the exception and return `null` to fall
+    // back on unintercepted decoder. The fallback will either succeed in
+    // decoding, or report the problem better than TextDecoder.
+    try {
+      return JS<String>('!', '#.decode(#)', decoder, codeUnits);
+    } catch (e) {}
+    return null;
+  }
+
+  /// Returns `true` if [codeUnits] contains problematic encodings.
+  ///
+  /// TextDecoder behaves differently to [Utf8Encoder] when the input encodes a
+  /// surrogate (U+D800 through U+DFFF). TextDecoder considers the surrogate to
+  /// be an encoding error and, depending on the `fatal` option, either throws
+  /// and Error or encodes the surrogate as U+FFFD. [Utf8Decoder] does not
+  /// consider the surrogate to be an error and returns the code unit encoded by
+  /// the surrogate.
+  ///
+  /// Throwing an `Error` captures the stack, whoch makes it so expensive that
+  /// it is worth checking the input for surrogates and avoiding TextDecoder in
+  /// this case.
+  static bool _unsafe(NativeUint8List codeUnits) {
+    // Surrogates encode as (hex) ED Ax xx or ED Bx xx.
+    int limit = codeUnits.length - 2;
+    for (int i = 0; i < limit; i++) {
+      int unit1 = codeUnits[i];
+      if (unit1 == 0xED) {
+        int unit2 = JS('!', '#', codeUnits[i + 1]);
+        if ((unit2 & 0xE0) == 0xA0) return true;
+      }
+    }
+    return false;
+  }
+
+  //// TextDecoder is not defined on some browsers and on the stand-alone d8 and
+  /// jsshell engines. Use a lazy initializer to do feature detection once.
+  static final _decoder = () {
+    try {
+      // Use `{fatal: true}`. 'fatal' does not correspond exactly to
+      // `!allowMalformed`: TextDecoder rejects unpaired surrogates which
+      // [Utf8Decoder] accepts.  In non-fatal mode, TextDecoder translates
+      // unpaired surrogates to REPLACEMENT CHARACTER (U+FFFD) whereas
+      // [Utf8Decoder] leaves the surrogate intact.
+      return JS('', 'new TextDecoder("utf-8", {fatal: true})');
+    } catch (e) {}
+    return null;
+  }();
+}
+
+@patch
+int _scanOneByteCharacters(List<int> units, int from, int endIndex) {
+  final to = endIndex;
+  for (var i = from; i < to; i++) {
+    final unit = units[i];
+    if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
+  }
+  return to - from;
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart
new file mode 100644
index 0000000..746ac61
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart
@@ -0,0 +1,2910 @@
+// Copyright (c) 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.
+
+// Patch file for dart:core classes.
+import "dart:_internal" as _symbol_dev;
+import 'dart:_interceptors';
+import 'dart:_js_helper'
+    show
+        patch,
+        checkInt,
+        getRuntimeType,
+        LinkedMap,
+        JSSyntaxRegExp,
+        NoInline,
+        notNull,
+        nullCheck,
+        Primitives,
+        PrivateSymbol,
+        quoteStringForRegExp,
+        undefined;
+import 'dart:_runtime' as dart;
+import 'dart:_foreign_helper' show JS;
+import 'dart:_native_typed_data' show NativeUint8List;
+import 'dart:collection' show UnmodifiableMapView;
+import 'dart:convert' show Encoding, utf8;
+import 'dart:typed_data' show Endian, Uint8List, Uint16List;
+
+String _symbolToString(Symbol symbol) => symbol is PrivateSymbol
+    ? PrivateSymbol.getName(symbol)
+    : _symbol_dev.Symbol.getName(symbol);
+
+@patch
+int identityHashCode(Object object) {
+  if (object == null) return 0;
+  // Note: this works for primitives because we define the `identityHashCode`
+  // for them to be equivalent to their computed hashCode function.
+  int hash = JS('int|Null', r'#[#]', object, dart.identityHashCode_);
+  if (hash == null) {
+    hash = JS<int>('!', '(Math.random() * 0x3fffffff) | 0');
+    JS('void', r'#[#] = #', object, dart.identityHashCode_, hash);
+  }
+  return JS<int>('!', '#', hash);
+}
+
+// Patch for Object implementation.
+@patch
+class Object {
+  @patch
+  bool operator ==(other) => identical(this, other);
+
+  @patch
+  int get hashCode => identityHashCode(this);
+
+  @patch
+  String toString() =>
+      "Instance of '${dart.typeName(dart.getReifiedType(this))}'";
+
+  @patch
+  noSuchMethod(Invocation invocation) {
+    return dart.defaultNoSuchMethod(this, invocation);
+  }
+
+  @patch
+  Type get runtimeType => dart.wrapType(dart.getReifiedType(this));
+}
+
+@patch
+class Null {
+  @patch
+  int get hashCode => super.hashCode;
+}
+
+// Patch for Function implementation.
+@patch
+class Function {
+  @patch
+  static apply(Function f, List positionalArguments,
+      [Map<Symbol, dynamic> namedArguments]) {
+    positionalArguments ??= [];
+    // dcall expects the namedArguments as a JS map in the last slot.
+    if (namedArguments != null && namedArguments.isNotEmpty) {
+      var map = JS('', '{}');
+      namedArguments.forEach((symbol, arg) {
+        JS('', '#[#] = #', map, _symbolToString(symbol), arg);
+      });
+      return dart.dcall(f, positionalArguments, map);
+    }
+    return dart.dcall(f, positionalArguments);
+  }
+
+  static Map<String, dynamic> _toMangledNames(
+      Map<Symbol, dynamic> namedArguments) {
+    Map<String, dynamic> result = {};
+    namedArguments.forEach((symbol, value) {
+      result[_symbolToString(symbol)] = value;
+    });
+    return result;
+  }
+}
+
+// TODO(jmesserly): switch to WeakMap
+// Patch for Expando implementation.
+@patch
+class Expando<T> {
+  @patch
+  Expando([String name]) : this.name = name;
+
+  @patch
+  T operator [](Object object) {
+    var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME);
+    return (values == null) ? null : Primitives.getProperty(values, _getKey());
+  }
+
+  @patch
+  void operator []=(Object object, T value) {
+    var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME);
+    if (values == null) {
+      values = Object();
+      Primitives.setProperty(object, _EXPANDO_PROPERTY_NAME, values);
+    }
+    Primitives.setProperty(values, _getKey(), value);
+  }
+
+  String _getKey() {
+    String key = Primitives.getProperty(this, _KEY_PROPERTY_NAME);
+    if (key == null) {
+      key = "expando\$key\$${_keyCount++}";
+      Primitives.setProperty(this, _KEY_PROPERTY_NAME, key);
+    }
+    return key;
+  }
+
+  static const String _KEY_PROPERTY_NAME = 'expando\$key';
+  static const String _EXPANDO_PROPERTY_NAME = 'expando\$values';
+  static int _keyCount = 0;
+}
+
+Null _kNull(_) => null;
+
+@patch
+class int {
+  @patch
+  static int parse(String source,
+      {int radix, @deprecated int onError(String source)}) {
+    return Primitives.parseInt(source, radix, onError);
+  }
+
+  @patch
+  static int tryParse(String source, {int radix}) {
+    return Primitives.parseInt(source, radix, _kNull);
+  }
+
+  @patch
+  factory int.fromEnvironment(String name, {int defaultValue}) {
+    // ignore: const_constructor_throws_exception
+    throw UnsupportedError(
+        'int.fromEnvironment can only be used as a const constructor');
+  }
+}
+
+@patch
+class double {
+  @patch
+  static double parse(String source,
+      [@deprecated double onError(String source)]) {
+    return Primitives.parseDouble(source, onError);
+  }
+
+  @patch
+  static double tryParse(String source) {
+    return Primitives.parseDouble(source, _kNull);
+  }
+}
+
+@patch
+class BigInt implements Comparable<BigInt> {
+  @patch
+  static BigInt get zero => _BigIntImpl.zero;
+  @patch
+  static BigInt get one => _BigIntImpl.one;
+  @patch
+  static BigInt get two => _BigIntImpl.two;
+
+  @patch
+  static BigInt parse(String source, {int radix}) =>
+      _BigIntImpl.parse(source, radix: radix);
+
+  @patch
+  static BigInt tryParse(String source, {int radix}) =>
+      _BigIntImpl._tryParse(source, radix: radix);
+
+  @patch
+  factory BigInt.from(num value) = _BigIntImpl.from;
+}
+
+@patch
+class Error {
+  @patch
+  static String _objectToString(Object object) {
+    return "Instance of '${dart.typeName(dart.getReifiedType(object))}'";
+  }
+
+  @patch
+  static String _stringToSafeString(String string) {
+    return JS("String", "JSON.stringify(#)", string);
+  }
+
+  @patch
+  StackTrace get stackTrace => dart.stackTraceForError(this);
+}
+
+@patch
+class FallThroughError {
+  @patch
+  FallThroughError._create(String url, int line);
+
+  @patch
+  String toString() => super.toString();
+}
+
+@patch
+class AbstractClassInstantiationError {
+  @patch
+  String toString() => "Cannot instantiate abstract class: '$_className'";
+}
+
+// Patch for DateTime implementation.
+@patch
+class DateTime {
+  @patch
+  DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
+      {bool isUtc = false})
+      : this._withValue(millisecondsSinceEpoch, isUtc: isUtc);
+
+  @patch
+  DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch,
+      {bool isUtc = false})
+      : this._withValue(
+            _microsecondInRoundedMilliseconds(microsecondsSinceEpoch),
+            isUtc: isUtc);
+
+  @patch
+  DateTime._internal(int year, int month, int day, int hour, int minute,
+      int second, int millisecond, int microsecond, bool isUtc)
+      // checkBool is manually inlined here because dart2js doesn't inline it
+      // and [isUtc] is usually a constant.
+      : this.isUtc =
+            isUtc is bool ? isUtc : throw ArgumentError.value(isUtc, 'isUtc'),
+        _value = checkInt(Primitives.valueFromDecomposedDate(
+            year,
+            month,
+            day,
+            hour,
+            minute,
+            second,
+            millisecond + _microsecondInRoundedMilliseconds(microsecond),
+            isUtc));
+
+  @patch
+  DateTime._now()
+      : isUtc = false,
+        _value = Primitives.dateNow();
+
+  /// Rounds the given [microsecond] to the nearest milliseconds value.
+  ///
+  /// For example, invoked with argument `2600` returns `3`.
+  static int _microsecondInRoundedMilliseconds(int microsecond) {
+    return (microsecond / 1000).round();
+  }
+
+  @patch
+  static int _brokenDownDateToValue(int year, int month, int day, int hour,
+      int minute, int second, int millisecond, int microsecond, bool isUtc) {
+    return Primitives.valueFromDecomposedDate(
+        year,
+        month,
+        day,
+        hour,
+        minute,
+        second,
+        millisecond + _microsecondInRoundedMilliseconds(microsecond),
+        isUtc);
+  }
+
+  @patch
+  String get timeZoneName {
+    if (isUtc) return "UTC";
+    return Primitives.getTimeZoneName(this);
+  }
+
+  @patch
+  Duration get timeZoneOffset {
+    if (isUtc) return Duration();
+    return Duration(minutes: Primitives.getTimeZoneOffsetInMinutes(this));
+  }
+
+  @patch
+  DateTime add(Duration duration) {
+    return DateTime._withValue(_value + duration.inMilliseconds, isUtc: isUtc);
+  }
+
+  @patch
+  DateTime subtract(Duration duration) {
+    return DateTime._withValue(_value - duration.inMilliseconds, isUtc: isUtc);
+  }
+
+  @patch
+  Duration difference(DateTime other) {
+    return Duration(milliseconds: _value - other._value);
+  }
+
+  @patch
+  int get millisecondsSinceEpoch => _value;
+
+  @patch
+  int get microsecondsSinceEpoch => _value * 1000;
+
+  @patch
+  int get year => Primitives.getYear(this);
+
+  @patch
+  int get month => Primitives.getMonth(this);
+
+  @patch
+  int get day => Primitives.getDay(this);
+
+  @patch
+  int get hour => Primitives.getHours(this);
+
+  @patch
+  int get minute => Primitives.getMinutes(this);
+
+  @patch
+  int get second => Primitives.getSeconds(this);
+
+  @patch
+  int get millisecond => Primitives.getMilliseconds(this);
+
+  @patch
+  int get microsecond => 0;
+
+  @patch
+  int get weekday => Primitives.getWeekday(this);
+
+  @patch
+  bool operator ==(dynamic other) =>
+      other is DateTime &&
+      _value == other.millisecondsSinceEpoch &&
+      isUtc == other.isUtc;
+
+  @patch
+  bool isBefore(DateTime other) => _value < other.millisecondsSinceEpoch;
+
+  @patch
+  bool isAfter(DateTime other) => _value > other.millisecondsSinceEpoch;
+
+  @patch
+  bool isAtSameMomentAs(DateTime other) =>
+      _value == other.millisecondsSinceEpoch;
+
+  @patch
+  int compareTo(DateTime other) =>
+      _value.compareTo(other.millisecondsSinceEpoch);
+}
+
+// Patch for Stopwatch implementation.
+@patch
+class Stopwatch {
+  @patch
+  static void _initTicker() {
+    Primitives.initTicker();
+    _frequency = Primitives.timerFrequency;
+  }
+
+  @patch
+  static int _now() => Primitives.timerTicks();
+
+  @patch
+  int get elapsedMicroseconds {
+    int ticks = elapsedTicks;
+    if (_frequency == 1000000) return ticks;
+    assert(_frequency == 1000);
+    return ticks * 1000;
+  }
+
+  @patch
+  int get elapsedMilliseconds {
+    int ticks = elapsedTicks;
+    if (_frequency == 1000) return ticks;
+    assert(_frequency == 1000000);
+    return ticks ~/ 1000;
+  }
+}
+
+// Patch for List implementation.
+@patch
+class List<E> {
+  @patch
+  factory List([@undefined int _length]) {
+    dynamic list;
+    if (JS<bool>('!', '# === void 0', _length)) {
+      list = JS('', '[]');
+    } else {
+      int length = JS('!', '#', _length);
+      if (_length == null || length < 0) {
+        throw ArgumentError("Length must be a non-negative integer: $_length");
+      }
+      list = JS('', 'new Array(#)', length);
+      JS('', '#.fill(null)', list);
+      JSArray.markFixedList(list);
+    }
+    return JSArray<E>.of(list);
+  }
+
+  @patch
+  factory List.filled(@nullCheck int length, E fill, {bool growable = false}) {
+    var list = JSArray<E>.of(JS('', 'new Array(#)', length));
+    JS('', '#.fill(#)', list, fill);
+    if (!growable) JSArray.markFixedList(list);
+    return list;
+  }
+
+  @patch
+  factory List.from(Iterable elements, {bool growable = true}) {
+    var list = JSArray<E>.of(JS('', '[]'));
+    // Specialize the copy loop for the case that doesn't need a
+    // runtime check.
+    if (elements is Iterable<E>) {
+      for (var e in elements) {
+        list.add(e);
+      }
+    } else {
+      for (var e in elements) {
+        list.add(e as E);
+      }
+    }
+    if (!growable) JSArray.markFixedList(list);
+    return list;
+  }
+
+  @patch
+  factory List.unmodifiable(Iterable elements) {
+    var list = List<E>.from(elements);
+    JSArray.markUnmodifiableList(list);
+    return list;
+  }
+}
+
+@patch
+class Map<K, V> {
+  @patch
+  factory Map.unmodifiable(Map other) {
+    return UnmodifiableMapView<K, V>(Map<K, V>.from(other));
+  }
+
+  @patch
+  factory Map() = LinkedMap<K, V>;
+}
+
+@patch
+class String {
+  @patch
+  factory String.fromCharCodes(Iterable<int> charCodes,
+      [int start = 0, int end]) {
+    if (charCodes is JSArray) {
+      return _stringFromJSArray(charCodes, start, end);
+    }
+    if (charCodes is NativeUint8List) {
+      return _stringFromUint8List(charCodes, start, end);
+    }
+    return _stringFromIterable(charCodes, start, end);
+  }
+
+  @patch
+  factory String.fromCharCode(int charCode) {
+    return Primitives.stringFromCharCode(charCode);
+  }
+
+  @patch
+  factory String.fromEnvironment(String name, {String defaultValue}) {
+    // ignore: const_constructor_throws_exception
+    throw UnsupportedError(
+        'String.fromEnvironment can only be used as a const constructor');
+  }
+
+  static String _stringFromJSArray(
+      /*=JSArray<int>*/ list,
+      int start,
+      int endOrNull) {
+    int len = list.length;
+    int end = RangeError.checkValidRange(start, endOrNull, len);
+    if (start > 0 || end < len) {
+      list = list.sublist(start, end);
+    }
+    return Primitives.stringFromCharCodes(list);
+  }
+
+  static String _stringFromUint8List(
+      NativeUint8List charCodes, int start, int endOrNull) {
+    int len = charCodes.length;
+    int end = RangeError.checkValidRange(start, endOrNull, len);
+    return Primitives.stringFromNativeUint8List(charCodes, start, end);
+  }
+
+  static String _stringFromIterable(
+      Iterable<int> charCodes, int start, int end) {
+    if (start < 0) throw RangeError.range(start, 0, charCodes.length);
+    if (end != null && end < start) {
+      throw RangeError.range(end, start, charCodes.length);
+    }
+    var it = charCodes.iterator;
+    for (int i = 0; i < start; i++) {
+      if (!it.moveNext()) {
+        throw RangeError.range(start, 0, i);
+      }
+    }
+    var list = <int>[];
+    if (end == null) {
+      while (it.moveNext()) list.add(it.current);
+    } else {
+      for (int i = start; i < end; i++) {
+        if (!it.moveNext()) {
+          throw RangeError.range(end, start, i);
+        }
+        list.add(it.current);
+      }
+    }
+    return Primitives.stringFromCharCodes(list);
+  }
+}
+
+@patch
+class bool {
+  @patch
+  factory bool.fromEnvironment(String name, {bool defaultValue = false}) {
+    // ignore: const_constructor_throws_exception
+    throw UnsupportedError(
+        'bool.fromEnvironment can only be used as a const constructor');
+  }
+
+  @patch
+  int get hashCode => super.hashCode;
+}
+
+@patch
+class RegExp {
+  @patch
+  factory RegExp(String source,
+          {bool multiLine = false,
+          bool caseSensitive = true,
+          bool unicode = false,
+          bool dotAll = false}) =>
+      JSSyntaxRegExp(source,
+          multiLine: multiLine,
+          caseSensitive: caseSensitive,
+          unicode: unicode,
+          dotAll: dotAll);
+
+  @patch
+  static String escape(String text) => quoteStringForRegExp(text);
+}
+
+// Patch for 'identical' function.
+@patch
+bool identical(Object a, Object b) {
+  return JS<bool>('!', '(# == null ? # == null : # === #)', a, b, a, b);
+}
+
+@patch
+class StringBuffer {
+  String _contents;
+
+  @patch
+  StringBuffer([Object content = ""]) : _contents = '$content';
+
+  @patch
+  int get length => _contents.length;
+
+  @patch
+  void write(Object obj) {
+    _writeString('$obj');
+  }
+
+  @patch
+  void writeCharCode(int charCode) {
+    _writeString(String.fromCharCode(charCode));
+  }
+
+  @patch
+  void writeAll(Iterable objects, [String separator = ""]) {
+    _contents = _writeAll(_contents, objects, separator);
+  }
+
+  @patch
+  void writeln([Object obj = ""]) {
+    _writeString('$obj\n');
+  }
+
+  @patch
+  void clear() {
+    _contents = "";
+  }
+
+  @patch
+  String toString() => Primitives.flattenString(_contents);
+
+  void _writeString(str) {
+    _contents = Primitives.stringConcatUnchecked(_contents, str);
+  }
+
+  static String _writeAll(String string, Iterable objects, String separator) {
+    Iterator iterator = objects.iterator;
+    if (!iterator.moveNext()) return string;
+    if (separator.isEmpty) {
+      do {
+        string = _writeOne(string, iterator.current);
+      } while (iterator.moveNext());
+    } else {
+      string = _writeOne(string, iterator.current);
+      while (iterator.moveNext()) {
+        string = _writeOne(string, separator);
+        string = _writeOne(string, iterator.current);
+      }
+    }
+    return string;
+  }
+
+  static String _writeOne(String string, Object obj) {
+    return Primitives.stringConcatUnchecked(string, '$obj');
+  }
+}
+
+// TODO(jmesserly): kernel expects to find this in our SDK.
+class _CompileTimeError extends Error {
+  final String _errorMsg;
+  _CompileTimeError(this._errorMsg);
+  String toString() => _errorMsg;
+}
+
+@patch
+class NoSuchMethodError {
+  final Object _receiver;
+  final Symbol _memberName;
+  final List _arguments;
+  final Map<Symbol, dynamic> _namedArguments;
+  final List _existingArgumentNames;
+  final Invocation _invocation;
+
+  @patch
+  NoSuchMethodError(Object receiver, Symbol memberName,
+      List positionalArguments, Map<Symbol, dynamic> namedArguments,
+      [List existingArgumentNames = null])
+      : _receiver = receiver,
+        _memberName = memberName,
+        _arguments = positionalArguments,
+        _namedArguments = namedArguments,
+        _existingArgumentNames = existingArgumentNames,
+        _invocation = null;
+
+  @patch
+  NoSuchMethodError.withInvocation(Object receiver, Invocation invocation)
+      : _receiver = receiver,
+        _memberName = invocation.memberName,
+        _arguments = invocation.positionalArguments,
+        _namedArguments = invocation.namedArguments,
+        _existingArgumentNames = null,
+        _invocation = invocation;
+
+  @patch
+  String toString() {
+    StringBuffer sb = StringBuffer('');
+    String comma = '';
+    if (_arguments != null) {
+      for (var argument in _arguments) {
+        sb.write(comma);
+        sb.write(Error.safeToString(argument));
+        comma = ', ';
+      }
+    }
+    if (_namedArguments != null) {
+      _namedArguments.forEach((Symbol key, var value) {
+        sb.write(comma);
+        sb.write(_symbolToString(key));
+        sb.write(": ");
+        sb.write(Error.safeToString(value));
+        comma = ', ';
+      });
+    }
+    String memberName = _symbolToString(_memberName);
+    String receiverText = Error.safeToString(_receiver);
+    String actualParameters = '$sb';
+    var failureMessage = (_invocation is dart.InvocationImpl)
+        ? (_invocation as dart.InvocationImpl).failureMessage
+        : 'method not found';
+    if (_existingArgumentNames == null) {
+      return "NoSuchMethodError: '$memberName'\n"
+          "$failureMessage\n"
+          "Receiver: ${receiverText}\n"
+          "Arguments: [$actualParameters]";
+    } else {
+      String formalParameters = _existingArgumentNames.join(', ');
+      return "NoSuchMethodError: incorrect number of arguments passed to "
+          "method named '$memberName'\n"
+          "Receiver: ${receiverText}\n"
+          "Tried calling: $memberName($actualParameters)\n"
+          "Found: $memberName($formalParameters)";
+    }
+  }
+}
+
+@patch
+class Uri {
+  @patch
+  static Uri get base {
+    String uri = Primitives.currentUri();
+    if (uri != null) return Uri.parse(uri);
+    throw UnsupportedError("'Uri.base' is not supported");
+  }
+}
+
+@patch
+class _Uri {
+  @patch
+  static bool get _isWindows => _isWindowsCached;
+
+  static final bool _isWindowsCached = JS(
+      'bool',
+      'typeof process != "undefined" && '
+          'Object.prototype.toString.call(process) == "[object process]" && '
+          'process.platform == "win32"');
+
+  // Matches a String that _uriEncodes to itself regardless of the kind of
+  // component.  This corresponds to [_unreservedTable], i.e. characters that
+  // are not encoded by any encoding table.
+  static final RegExp _needsNoEncoding = RegExp(r'^[\-\.0-9A-Z_a-z~]*$');
+
+  /**
+   * This is the internal implementation of JavaScript's encodeURI function.
+   * It encodes all characters in the string [text] except for those
+   * that appear in [canonicalTable], and returns the escaped string.
+   */
+  @patch
+  static String _uriEncode(List<int> canonicalTable, String text,
+      Encoding encoding, bool spaceToPlus) {
+    if (identical(encoding, utf8) && _needsNoEncoding.hasMatch(text)) {
+      return text;
+    }
+
+    // Encode the string into bytes then generate an ASCII only string
+    // by percent encoding selected bytes.
+    StringBuffer result = StringBuffer('');
+    var bytes = encoding.encode(text);
+    for (int i = 0; i < bytes.length; i++) {
+      int byte = bytes[i];
+      if (byte < 128 &&
+          ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) {
+        result.writeCharCode(byte);
+      } else if (spaceToPlus && byte == _SPACE) {
+        result.write('+');
+      } else {
+        const String hexDigits = '0123456789ABCDEF';
+        result.write('%');
+        result.write(hexDigits[(byte >> 4) & 0x0f]);
+        result.write(hexDigits[byte & 0x0f]);
+      }
+    }
+    return result.toString();
+  }
+}
+
+@patch
+class StackTrace {
+  @patch
+  @NoInline()
+  static StackTrace get current {
+    return dart.stackTrace(JS('', 'Error()'));
+  }
+}
+
+// TODO(jmesserly): this class is supposed to be obsolete in Strong Mode, but
+// the front-end crashes without it
+class _DuplicatedFieldInitializerError {
+  final String _name;
+
+  _DuplicatedFieldInitializerError(this._name);
+
+  toString() => "Error: field '$_name' is already initialized.";
+}
+
+// TODO(jmesserly): The rest of this core_patch.dart source should reside in an
+// included part file instead of being inlined. However, part files are not
+// properly supported here.
+
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.core;
+
+int _max(int a, int b) => a > b ? a : b;
+int _min(int a, int b) => a < b ? a : b;
+
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+ * Copyright (c) 2003-2005  Tom Wu
+ * Copyright (c) 2012 Adam Singer (adam@solvr.io)
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following condition applies:
+ *
+ * All redistributions must retain an intact copy of this copyright notice
+ * and disclaimer.
+ */
+
+/**
+ * An implementation for the arbitrarily large integer.
+ *
+ * The integer number is represented by a sign, an array of 16-bit unsigned
+ * integers in little endian format, and a number of used digits in that array.
+ */
+class _BigIntImpl implements BigInt {
+  // Bits per digit.
+  static const int _digitBits = 16;
+  static const int _digitBase = 1 << _digitBits;
+  static const int _digitMask = (1 << _digitBits) - 1;
+
+  static final _BigIntImpl zero = _BigIntImpl._fromInt(0);
+  static final _BigIntImpl one = _BigIntImpl._fromInt(1);
+  static final _BigIntImpl two = _BigIntImpl._fromInt(2);
+
+  static final _BigIntImpl _minusOne = -one;
+  static final _BigIntImpl _bigInt10000 = _BigIntImpl._fromInt(10000);
+
+  // Result cache for last _divRem call.
+  // Result cache for last _divRem call.
+  static Uint16List _lastDividendDigits;
+  static int _lastDividendUsed;
+  static Uint16List _lastDivisorDigits;
+  static int _lastDivisorUsed;
+  static Uint16List _lastQuoRemDigits;
+  static int _lastQuoRemUsed;
+  static int _lastRemUsed;
+  static int _lastRem_nsh;
+
+  /// Whether this bigint is negative.
+  final bool _isNegative;
+
+  /// The unsigned digits of this bigint.
+  ///
+  /// The least significant digit is in slot 0.
+  /// The list may have more digits than needed. That is, `_digits.length` may
+  /// be strictly greater than `_used`.
+  final Uint16List _digits;
+
+  /// The number of used entries in [_digits].
+  ///
+  /// To avoid reallocating [Uint16List]s, lists that are too big are not
+  /// replaced.
+  final int _used;
+
+  /**
+   * Parses [source] as a, possibly signed, integer literal and returns its
+   * value.
+   *
+   * The [source] must be a non-empty sequence of base-[radix] digits,
+   * optionally prefixed with a minus or plus sign ('-' or '+').
+   *
+   * The [radix] must be in the range 2..36. The digits used are
+   * first the decimal digits 0..9, and then the letters 'a'..'z' with
+   * values 10 through 35. Also accepts upper-case letters with the same
+   * values as the lower-case ones.
+   *
+   * If no [radix] is given then it defaults to 10. In this case, the [source]
+   * digits may also start with `0x`, in which case the number is interpreted
+   * as a hexadecimal literal, which effectively means that the `0x` is ignored
+   * and the radix is instead set to 16.
+   *
+   * For any int `n` and radix `r`, it is guaranteed that
+   * `n == int.parse(n.toRadixString(r), radix: r)`.
+   *
+   * Throws a [FormatException] if the [source] is not a valid integer literal,
+   * optionally prefixed by a sign.
+   */
+  static _BigIntImpl parse(String source, {int radix}) {
+    var result = _tryParse(source, radix: radix);
+    if (result == null) {
+      throw FormatException("Could not parse BigInt", source);
+    }
+    return result;
+  }
+
+  /// Parses a decimal bigint literal.
+  ///
+  /// The [source] must not contain leading or trailing whitespace.
+  static _BigIntImpl _parseDecimal(String source, bool isNegative) {
+    const _0 = 48;
+
+    int part = 0;
+    _BigIntImpl result = zero;
+    // Read in the source 4 digits at a time.
+    // The first part may have a few leading virtual '0's to make the remaining
+    // parts all have exactly 4 digits.
+    int digitInPartCount = 4 - source.length.remainder(4);
+    if (digitInPartCount == 4) digitInPartCount = 0;
+    for (int i = 0; i < source.length; i++) {
+      part = part * 10 + source.codeUnitAt(i) - _0;
+      if (++digitInPartCount == 4) {
+        result = result * _bigInt10000 + _BigIntImpl._fromInt(part);
+        part = 0;
+        digitInPartCount = 0;
+      }
+    }
+    if (isNegative) return -result;
+    return result;
+  }
+
+  /// Returns the value of a given source digit.
+  ///
+  /// Source digits between "0" and "9" (inclusive) return their decimal value.
+  ///
+  /// Source digits between "a" and "z", or "A" and "Z" (inclusive) return
+  /// 10 + their position in the ASCII alphabet.
+  ///
+  /// The incoming [codeUnit] must be an ASCII code-unit.
+  static int _codeUnitToRadixValue(int codeUnit) {
+    // We know that the characters must be ASCII as otherwise the
+    // regexp wouldn't have matched. Lowercasing by doing `| 0x20` is thus
+    // guaranteed to be a safe operation, since it preserves digits
+    // and lower-cases ASCII letters.
+    const int _0 = 48;
+    const int _9 = 57;
+    const int _a = 97;
+    if (_0 <= codeUnit && codeUnit <= _9) return codeUnit - _0;
+    codeUnit |= 0x20;
+    var result = codeUnit - _a + 10;
+    return result;
+  }
+
+  /// Parses the given [source] string, starting at [startPos], as a hex
+  /// literal.
+  ///
+  /// If [isNegative] is true, negates the result before returning it.
+  ///
+  /// The [source] (substring) must be a valid hex literal.
+  static _BigIntImpl _parseHex(String source, int startPos, bool isNegative) {
+    int hexDigitsPerChunk = _digitBits ~/ 4;
+    int sourceLength = source.length - startPos;
+    int chunkCount = (sourceLength / hexDigitsPerChunk).ceil();
+    var digits = Uint16List(chunkCount);
+
+    int lastDigitLength = sourceLength - (chunkCount - 1) * hexDigitsPerChunk;
+    int digitIndex = digits.length - 1;
+    int i = startPos;
+    int chunk = 0;
+    for (int j = 0; j < lastDigitLength; j++) {
+      var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i++));
+      if (digitValue >= 16) return null;
+      chunk = chunk * 16 + digitValue;
+    }
+    digits[digitIndex--] = chunk;
+
+    while (i < source.length) {
+      chunk = 0;
+      for (int j = 0; j < hexDigitsPerChunk; j++) {
+        var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i++));
+        if (digitValue >= 16) return null;
+        chunk = chunk * 16 + digitValue;
+      }
+      digits[digitIndex--] = chunk;
+    }
+    if (digits.length == 1 && digits[0] == 0) return zero;
+    return _BigIntImpl._(isNegative, digits.length, digits);
+  }
+
+  /// Parses the given [source] as a [radix] literal.
+  ///
+  /// The [source] will be checked for invalid characters. If it is invalid,
+  /// this function returns `null`.
+  static _BigIntImpl _parseRadix(String source, int radix, bool isNegative) {
+    var result = zero;
+    var base = _BigIntImpl._fromInt(radix);
+    for (int i = 0; i < source.length; i++) {
+      var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i));
+      if (digitValue >= radix) return null;
+      result = result * base + _BigIntImpl._fromInt(digitValue);
+    }
+    if (isNegative) return -result;
+    return result;
+  }
+
+  /// Tries to parse the given [source] as a [radix] literal.
+  ///
+  /// Returns the parsed big integer, or `null` if it failed.
+  ///
+  /// If the [radix] is `null` accepts decimal literals or `0x` hex literals.
+  static _BigIntImpl _tryParse(String source, {int radix}) {
+    if (source == "") return null;
+
+    var re = RegExp(r'^\s*([+-]?)((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$',
+        caseSensitive: false);
+    var match = re.firstMatch(source);
+    int signIndex = 1;
+    int hexIndex = 3;
+    int decimalIndex = 4;
+    int nonDecimalHexIndex = 5;
+    if (match == null) return null;
+
+    bool isNegative = match[signIndex] == "-";
+
+    String decimalMatch = match[decimalIndex];
+    String hexMatch = match[hexIndex];
+    String nonDecimalMatch = match[nonDecimalHexIndex];
+
+    if (radix == null) {
+      if (decimalMatch != null) {
+        // Cannot fail because we know that the digits are all decimal.
+        return _parseDecimal(decimalMatch, isNegative);
+      }
+      if (hexMatch != null) {
+        // Cannot fail because we know that the digits are all hex.
+        return _parseHex(hexMatch, 2, isNegative);
+      }
+      return null;
+    }
+
+    if (radix is! int) {
+      throw ArgumentError.value(radix, 'radix', 'is not an integer');
+    }
+    if (radix < 2 || radix > 36) {
+      throw RangeError.range(radix, 2, 36, 'radix');
+    }
+    if (radix == 10 && decimalMatch != null) {
+      return _parseDecimal(decimalMatch, isNegative);
+    }
+    if (radix == 16 && (decimalMatch != null || nonDecimalMatch != null)) {
+      return _parseHex(decimalMatch ?? nonDecimalMatch, 0, isNegative);
+    }
+
+    return _parseRadix(
+        decimalMatch ?? nonDecimalMatch ?? hexMatch, radix, isNegative);
+  }
+
+  /// Finds the amount significant digits in the provided [digits] array.
+  static int _normalize(int used, Uint16List digits) {
+    while (used > 0 && digits[used - 1] == 0) used--;
+    return used;
+  }
+
+  /// Factory returning an instance initialized with the given field values.
+  /// If the [digits] array contains leading 0s, the [used] value is adjusted
+  /// accordingly. The [digits] array is not modified.
+  _BigIntImpl._(bool isNegative, int used, Uint16List digits)
+      : this._normalized(isNegative, _normalize(used, digits), digits);
+
+  _BigIntImpl._normalized(bool isNegative, this._used, this._digits)
+      : _isNegative = _used == 0 ? false : isNegative;
+
+  /// Whether this big integer is zero.
+  bool get _isZero => _used == 0;
+
+  /// Allocates an array of the given [length] and copies the [digits] in the
+  /// range [from] to [to-1], starting at index 0, followed by leading zero
+  /// digits.
+  static Uint16List _cloneDigits(
+      Uint16List digits, int from, int to, int length) {
+    var resultDigits = Uint16List(length);
+    var n = to - from;
+    for (var i = 0; i < n; i++) {
+      resultDigits[i] = digits[from + i];
+    }
+    return resultDigits;
+  }
+
+  /// Allocates a big integer from the provided [value] number.
+  factory _BigIntImpl.from(num value) {
+    if (value == 0) return zero;
+    if (value == 1) return one;
+    if (value == 2) return two;
+
+    // Given this order dart2js will use the `_fromInt` for smaller value and
+    // then use the bit-manipulating `_fromDouble` for all other values.
+    if (value.abs() < 0x100000000) return _BigIntImpl._fromInt(value.toInt());
+    if (value is double) return _BigIntImpl._fromDouble(value);
+    return _BigIntImpl._fromInt(value);
+  }
+
+  factory _BigIntImpl._fromInt(int value) {
+    bool isNegative = value < 0;
+    assert(_digitBits == 16);
+    if (isNegative) {
+      // Handle the min 64-bit value differently, since its negation is not
+      // positive.
+      const int minInt64 = -0x80000000 * 0x100000000;
+      if (value == minInt64) {
+        var digits = Uint16List(4);
+        digits[3] = 0x8000;
+        return _BigIntImpl._(true, 4, digits);
+      }
+      value = -value;
+    }
+    if (value < _digitBase) {
+      var digits = Uint16List(1);
+      digits[0] = value;
+      return _BigIntImpl._(isNegative, 1, digits);
+    }
+    if (value <= 0xFFFFFFFF) {
+      var digits = Uint16List(2);
+      digits[0] = value & _digitMask;
+      digits[1] = value >> _digitBits;
+      return _BigIntImpl._(isNegative, 2, digits);
+    }
+
+    var bits = value.bitLength;
+    var digits = Uint16List((bits - 1) ~/ _digitBits + 1);
+    var i = 0;
+    while (value != 0) {
+      digits[i++] = value & _digitMask;
+      value = value ~/ _digitBase;
+    }
+    return _BigIntImpl._(isNegative, digits.length, digits);
+  }
+
+  /// An 8-byte Uint8List we can reuse for [_fromDouble] to avoid generating
+  /// garbage.
+  static final Uint8List _bitsForFromDouble = Uint8List(8);
+
+  factory _BigIntImpl._fromDouble(double value) {
+    const int exponentBias = 1075;
+
+    if (value.isNaN || value.isInfinite) {
+      throw ArgumentError("Value must be finite: $value");
+    }
+    bool isNegative = value < 0;
+    if (isNegative) value = -value;
+
+    value = value.floorToDouble();
+    if (value == 0) return zero;
+
+    var bits = _bitsForFromDouble;
+    for (int i = 0; i < 8; i++) {
+      bits[i] = 0;
+    }
+    bits.buffer.asByteData().setFloat64(0, value, Endian.little);
+    // The exponent is in bits 53..63.
+    var biasedExponent = (bits[7] << 4) + (bits[6] >> 4);
+    var exponent = biasedExponent - exponentBias;
+
+    assert(_digitBits == 16);
+    // The significant bits are in 0 .. 52.
+    var unshiftedDigits = Uint16List(4);
+    unshiftedDigits[0] = (bits[1] << 8) + bits[0];
+    unshiftedDigits[1] = (bits[3] << 8) + bits[2];
+    unshiftedDigits[2] = (bits[5] << 8) + bits[4];
+    // Don't forget to add the hidden bit.
+    unshiftedDigits[3] = 0x10 | (bits[6] & 0xF);
+
+    var unshiftedBig = _BigIntImpl._normalized(false, 4, unshiftedDigits);
+    _BigIntImpl absResult = unshiftedBig;
+    if (exponent < 0) {
+      absResult = unshiftedBig >> -exponent;
+    } else if (exponent > 0) {
+      absResult = unshiftedBig << exponent;
+    }
+    if (isNegative) return -absResult;
+    return absResult;
+  }
+
+  /**
+   * Return the negative value of this integer.
+   *
+   * The result of negating an integer always has the opposite sign, except
+   * for zero, which is its own negation.
+   */
+  _BigIntImpl operator -() {
+    if (_used == 0) return this;
+    return _BigIntImpl._(!_isNegative, _used, _digits);
+  }
+
+  /**
+   * Returns the absolute value of this integer.
+   *
+   * For any integer `x`, the result is the same as `x < 0 ? -x : x`.
+   */
+  _BigIntImpl abs() => _isNegative ? -this : this;
+
+  /// Returns this << n *_DIGIT_BITS.
+  _BigIntImpl _dlShift(int n) {
+    final used = _used;
+    if (used == 0) {
+      return zero;
+    }
+    final resultUsed = used + n;
+    final digits = _digits;
+    final resultDigits = Uint16List(resultUsed);
+    for (int i = used - 1; i >= 0; i--) {
+      resultDigits[i + n] = digits[i];
+    }
+    return _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+  }
+
+  /// Same as [_dlShift] but works on the decomposed big integers.
+  ///
+  /// Returns `resultUsed`.
+  ///
+  /// `resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n*_DIGIT_BITS`.
+  static int _dlShiftDigits(
+      Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+    if (xUsed == 0) {
+      return 0;
+    }
+    if (n == 0 && identical(resultDigits, xDigits)) {
+      return xUsed;
+    }
+    final resultUsed = xUsed + n;
+    for (int i = xUsed - 1; i >= 0; i--) {
+      resultDigits[i + n] = xDigits[i];
+    }
+    for (int i = n - 1; i >= 0; i--) {
+      resultDigits[i] = 0;
+    }
+    return resultUsed;
+  }
+
+  /// Returns `this >> n*_DIGIT_BITS`.
+  _BigIntImpl _drShift(int n) {
+    final used = _used;
+    if (used == 0) {
+      return zero;
+    }
+    final resultUsed = used - n;
+    if (resultUsed <= 0) {
+      return _isNegative ? _minusOne : zero;
+    }
+    final digits = _digits;
+    final resultDigits = Uint16List(resultUsed);
+    for (var i = n; i < used; i++) {
+      resultDigits[i - n] = digits[i];
+    }
+    final result = _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+    if (_isNegative) {
+      // Round down if any bit was shifted out.
+      for (var i = 0; i < n; i++) {
+        if (digits[i] != 0) {
+          return result - one;
+        }
+      }
+    }
+    return result;
+  }
+
+  /// Shifts the digits of [xDigits] into the right place in [resultDigits].
+  ///
+  /// `resultDigits[ds..xUsed+ds] = xDigits[0..xUsed-1] << (n % _DIGIT_BITS)`
+  ///   where `ds = n ~/ _DIGIT_BITS`
+  ///
+  /// Does *not* clear digits below ds.
+  static void _lsh(
+      Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+    assert(xUsed > 0);
+    final digitShift = n ~/ _digitBits;
+    final bitShift = n % _digitBits;
+    final carryBitShift = _digitBits - bitShift;
+    final bitMask = (1 << carryBitShift) - 1;
+    var carry = 0;
+    for (int i = xUsed - 1; i >= 0; i--) {
+      final digit = xDigits[i];
+      resultDigits[i + digitShift + 1] = (digit >> carryBitShift) | carry;
+      carry = (digit & bitMask) << bitShift;
+    }
+    resultDigits[digitShift] = carry;
+  }
+
+  /**
+   * Shift the bits of this integer to the left by [shiftAmount].
+   *
+   * Shifting to the left makes the number larger, effectively multiplying
+   * the number by `pow(2, shiftIndex)`.
+   *
+   * There is no limit on the size of the result. It may be relevant to
+   * limit intermediate values by using the "and" operator with a suitable
+   * mask.
+   *
+   * It is an error if [shiftAmount] is negative.
+   */
+  _BigIntImpl operator <<(int shiftAmount) {
+    if (shiftAmount < 0) {
+      throw ArgumentError("shift-amount must be posititve $shiftAmount");
+    }
+    if (_isZero) return this;
+    final digitShift = shiftAmount ~/ _digitBits;
+    final bitShift = shiftAmount % _digitBits;
+    if (bitShift == 0) {
+      return _dlShift(digitShift);
+    }
+    var resultUsed = _used + digitShift + 1;
+    var resultDigits = Uint16List(resultUsed);
+    _lsh(_digits, _used, shiftAmount, resultDigits);
+    return _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+  }
+
+  // resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n.
+  // Returns resultUsed.
+  static int _lShiftDigits(
+      Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+    final digitsShift = n ~/ _digitBits;
+    final bitShift = n % _digitBits;
+    if (bitShift == 0) {
+      return _dlShiftDigits(xDigits, xUsed, digitsShift, resultDigits);
+    }
+    var resultUsed = xUsed + digitsShift + 1;
+    _lsh(xDigits, xUsed, n, resultDigits);
+    var i = digitsShift;
+    while (--i >= 0) {
+      resultDigits[i] = 0;
+    }
+    if (resultDigits[resultUsed - 1] == 0) {
+      resultUsed--; // Clamp result.
+    }
+    return resultUsed;
+  }
+
+  // resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] >> n.
+  static void _rsh(
+      Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+    assert(xUsed > 0);
+    final digitsShift = n ~/ _digitBits;
+    final bitShift = n % _digitBits;
+    final carryBitShift = _digitBits - bitShift;
+    final bitMask = (1 << bitShift) - 1;
+    var carry = xDigits[digitsShift] >> bitShift;
+    final last = xUsed - digitsShift - 1;
+    for (var i = 0; i < last; i++) {
+      final digit = xDigits[i + digitsShift + 1];
+      resultDigits[i] = ((digit & bitMask) << carryBitShift) | carry;
+      carry = digit >> bitShift;
+    }
+    resultDigits[last] = carry;
+  }
+
+  /**
+   * Shift the bits of this integer to the right by [shiftAmount].
+   *
+   * Shifting to the right makes the number smaller and drops the least
+   * significant bits, effectively doing an integer division by
+   *`pow(2, shiftIndex)`.
+   *
+   * It is an error if [shiftAmount] is negative.
+   */
+  _BigIntImpl operator >>(int shiftAmount) {
+    if (shiftAmount < 0) {
+      throw ArgumentError("shift-amount must be posititve $shiftAmount");
+    }
+    if (_isZero) return this;
+    final digitShift = shiftAmount ~/ _digitBits;
+    final bitShift = shiftAmount % _digitBits;
+    if (bitShift == 0) {
+      return _drShift(digitShift);
+    }
+    final used = _used;
+    final resultUsed = used - digitShift;
+    if (resultUsed <= 0) {
+      return _isNegative ? _minusOne : zero;
+    }
+    final digits = _digits;
+    final resultDigits = Uint16List(resultUsed);
+    _rsh(digits, used, shiftAmount, resultDigits);
+    final result = _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+    if (_isNegative) {
+      // Round down if any bit was shifted out.
+      if ((digits[digitShift] & ((1 << bitShift) - 1)) != 0) {
+        return result - one;
+      }
+      for (var i = 0; i < digitShift; i++) {
+        if (digits[i] != 0) {
+          return result - one;
+        }
+      }
+    }
+    return result;
+  }
+
+  /// Compares this to [other] taking the absolute value of both operands.
+  ///
+  /// Returns 0 if abs(this) == abs(other); a positive number if
+  /// abs(this) > abs(other); and a negative number if abs(this) < abs(other).
+  int _absCompare(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    return _compareDigits(_digits, _used, other._digits, other._used);
+  }
+
+  /**
+   * Compares this to `other`.
+   *
+   * Returns a negative number if `this` is less than `other`, zero if they are
+   * equal, and a positive number if `this` is greater than `other`.
+   */
+  int compareTo(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (_isNegative == other._isNegative) {
+      var result = _absCompare(other);
+      // Use 0 - result to avoid negative zero in JavaScript.
+      return _isNegative ? 0 - result : result;
+    }
+    return _isNegative ? -1 : 1;
+  }
+
+  /// Compares `digits[0..used-1]` with `otherDigits[0..otherUsed-1]`.
+  ///
+  /// Returns 0 if equal; a positive number if larger;
+  /// and a negative number if smaller.
+  static int _compareDigits(
+      Uint16List digits, int used, Uint16List otherDigits, int otherUsed) {
+    var result = used - otherUsed;
+    if (result == 0) {
+      for (int i = used - 1; i >= 0; i--) {
+        result = digits[i] - otherDigits[i];
+        if (result != 0) return result;
+      }
+    }
+    return result;
+  }
+
+  // resultDigits[0..used] = digits[0..used-1] + otherDigits[0..otherUsed-1].
+  // used >= otherUsed > 0.
+  static void _absAdd(Uint16List digits, int used, Uint16List otherDigits,
+      int otherUsed, Uint16List resultDigits) {
+    assert(used >= otherUsed && otherUsed > 0);
+    var carry = 0;
+    for (var i = 0; i < otherUsed; i++) {
+      carry += digits[i] + otherDigits[i];
+      resultDigits[i] = carry & _digitMask;
+      carry >>= _digitBits;
+    }
+    for (var i = otherUsed; i < used; i++) {
+      carry += digits[i];
+      resultDigits[i] = carry & _digitMask;
+      carry >>= _digitBits;
+    }
+    resultDigits[used] = carry;
+  }
+
+  // resultDigits[0..used-1] = digits[0..used-1] - otherDigits[0..otherUsed-1].
+  // used >= otherUsed > 0.
+  static void _absSub(Uint16List digits, int used, Uint16List otherDigits,
+      int otherUsed, Uint16List resultDigits) {
+    assert(used >= otherUsed && otherUsed > 0);
+
+    var carry = 0;
+    for (var i = 0; i < otherUsed; i++) {
+      carry += digits[i] - otherDigits[i];
+      resultDigits[i] = carry & _digitMask;
+      // Dart2js only supports unsigned shifts.
+      // Since the carry can only be -1 or 0 use this hack.
+      carry = 0 - ((carry >> _digitBits) & 1);
+    }
+    for (var i = otherUsed; i < used; i++) {
+      carry += digits[i];
+      resultDigits[i] = carry & _digitMask;
+      // Dart2js only supports unsigned shifts.
+      // Since the carry can only be -1 or 0 use this hack.
+      carry = 0 - ((carry >> _digitBits) & 1);
+    }
+  }
+
+  /// Returns `abs(this) + abs(other)` with sign set according to [isNegative].
+  _BigIntImpl _absAddSetSign(_BigIntImpl other, bool isNegative) {
+    var used = _used;
+    var otherUsed = other._used;
+    if (used < otherUsed) {
+      return other._absAddSetSign(this, isNegative);
+    }
+    if (used == 0) {
+      assert(!isNegative);
+      return zero;
+    }
+    if (otherUsed == 0) {
+      return _isNegative == isNegative ? this : -this;
+    }
+    var resultUsed = used + 1;
+    var resultDigits = Uint16List(resultUsed);
+    _absAdd(_digits, used, other._digits, otherUsed, resultDigits);
+    return _BigIntImpl._(isNegative, resultUsed, resultDigits);
+  }
+
+  /// Returns `abs(this) - abs(other)` with sign set according to [isNegative].
+  ///
+  /// Requirement: `abs(this) >= abs(other)`.
+  _BigIntImpl _absSubSetSign(_BigIntImpl other, bool isNegative) {
+    assert(_absCompare(other) >= 0);
+    var used = _used;
+    if (used == 0) {
+      assert(!isNegative);
+      return zero;
+    }
+    var otherUsed = other._used;
+    if (otherUsed == 0) {
+      return _isNegative == isNegative ? this : -this;
+    }
+    var resultDigits = Uint16List(used);
+    _absSub(_digits, used, other._digits, otherUsed, resultDigits);
+    return _BigIntImpl._(isNegative, used, resultDigits);
+  }
+
+  /// Returns `abs(this) & abs(other)` with sign set according to [isNegative].
+  _BigIntImpl _absAndSetSign(_BigIntImpl other, bool isNegative) {
+    var resultUsed = _min(_used, other._used);
+    var digits = _digits;
+    var otherDigits = other._digits;
+    var resultDigits = Uint16List(resultUsed);
+    for (var i = 0; i < resultUsed; i++) {
+      resultDigits[i] = digits[i] & otherDigits[i];
+    }
+    return _BigIntImpl._(isNegative, resultUsed, resultDigits);
+  }
+
+  /// Returns `abs(this) &~ abs(other)` with sign set according to [isNegative].
+  _BigIntImpl _absAndNotSetSign(_BigIntImpl other, bool isNegative) {
+    var resultUsed = _used;
+    var digits = _digits;
+    var otherDigits = other._digits;
+    var resultDigits = Uint16List(resultUsed);
+    var m = _min(resultUsed, other._used);
+    for (var i = 0; i < m; i++) {
+      resultDigits[i] = digits[i] & ~otherDigits[i];
+    }
+    for (var i = m; i < resultUsed; i++) {
+      resultDigits[i] = digits[i];
+    }
+    return _BigIntImpl._(isNegative, resultUsed, resultDigits);
+  }
+
+  /// Returns `abs(this) | abs(other)` with sign set according to [isNegative].
+  _BigIntImpl _absOrSetSign(_BigIntImpl other, bool isNegative) {
+    var used = _used;
+    var otherUsed = other._used;
+    var resultUsed = _max(used, otherUsed);
+    var digits = _digits;
+    var otherDigits = other._digits;
+    var resultDigits = Uint16List(resultUsed);
+    var l, m;
+    if (used < otherUsed) {
+      l = other;
+      m = used;
+    } else {
+      l = this;
+      m = otherUsed;
+    }
+    for (var i = 0; i < m; i++) {
+      resultDigits[i] = digits[i] | otherDigits[i];
+    }
+    var lDigits = l._digits;
+    for (var i = m; i < resultUsed; i++) {
+      resultDigits[i] = lDigits[i];
+    }
+    return _BigIntImpl._(isNegative, resultUsed, resultDigits);
+  }
+
+  /// Returns `abs(this) ^ abs(other)` with sign set according to [isNegative].
+  _BigIntImpl _absXorSetSign(_BigIntImpl other, bool isNegative) {
+    var used = _used;
+    var otherUsed = other._used;
+    var resultUsed = _max(used, otherUsed);
+    var digits = _digits;
+    var otherDigits = other._digits;
+    var resultDigits = Uint16List(resultUsed);
+    var l, m;
+    if (used < otherUsed) {
+      l = other;
+      m = used;
+    } else {
+      l = this;
+      m = otherUsed;
+    }
+    for (var i = 0; i < m; i++) {
+      resultDigits[i] = digits[i] ^ otherDigits[i];
+    }
+    var lDigits = l._digits;
+    for (var i = m; i < resultUsed; i++) {
+      resultDigits[i] = lDigits[i];
+    }
+    return _BigIntImpl._(isNegative, resultUsed, resultDigits);
+  }
+
+  /**
+   * Bit-wise and operator.
+   *
+   * Treating both `this` and [other] as sufficiently large two's component
+   * integers, the result is a number with only the bits set that are set in
+   * both `this` and [other]
+   *
+   * Of both operands are negative, the result is negative, otherwise
+   * the result is non-negative.
+   */
+  _BigIntImpl operator &(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (_isZero || other._isZero) return zero;
+    if (_isNegative == other._isNegative) {
+      if (_isNegative) {
+        // (-this) & (-other) == ~(this-1) & ~(other-1)
+        //                    == ~((this-1) | (other-1))
+        //                    == -(((this-1) | (other-1)) + 1)
+        _BigIntImpl this1 = _absSubSetSign(one, true);
+        _BigIntImpl other1 = other._absSubSetSign(one, true);
+        // Result cannot be zero if this and other are negative.
+        return this1._absOrSetSign(other1, true)._absAddSetSign(one, true);
+      }
+      return _absAndSetSign(other, false);
+    }
+    // _isNegative != other._isNegative
+    var p, n;
+    if (_isNegative) {
+      p = other;
+      n = this;
+    } else {
+      // & is symmetric.
+      p = this;
+      n = other;
+    }
+    // p & (-n) == p & ~(n-1) == p &~ (n-1)
+    var n1 = n._absSubSetSign(one, false);
+    return p._absAndNotSetSign(n1, false);
+  }
+
+  /**
+   * Bit-wise or operator.
+   *
+   * Treating both `this` and [other] as sufficiently large two's component
+   * integers, the result is a number with the bits set that are set in either
+   * of `this` and [other]
+   *
+   * If both operands are non-negative, the result is non-negative,
+   * otherwise the result us negative.
+   */
+  _BigIntImpl operator |(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (_isZero) return other;
+    if (other._isZero) return this;
+    if (_isNegative == other._isNegative) {
+      if (_isNegative) {
+        // (-this) | (-other) == ~(this-1) | ~(other-1)
+        //                    == ~((this-1) & (other-1))
+        //                    == -(((this-1) & (other-1)) + 1)
+        var this1 = _absSubSetSign(one, true);
+        var other1 = other._absSubSetSign(one, true);
+        // Result cannot be zero if this and a are negative.
+        return this1._absAndSetSign(other1, true)._absAddSetSign(one, true);
+      }
+      return _absOrSetSign(other, false);
+    }
+    // _neg != a._neg
+    var p, n;
+    if (_isNegative) {
+      p = other;
+      n = this;
+    } else {
+      // | is symmetric.
+      p = this;
+      n = other;
+    }
+    // p | (-n) == p | ~(n-1) == ~((n-1) &~ p) == -(~((n-1) &~ p) + 1)
+    var n1 = n._absSubSetSign(one, true);
+    // Result cannot be zero if only one of this or a is negative.
+    return n1._absAndNotSetSign(p, true)._absAddSetSign(one, true);
+  }
+
+  /**
+   * Bit-wise exclusive-or operator.
+   *
+   * Treating both `this` and [other] as sufficiently large two's component
+   * integers, the result is a number with the bits set that are set in one,
+   * but not both, of `this` and [other]
+   *
+   * If the operands have the same sign, the result is non-negative,
+   * otherwise the result is negative.
+   */
+  _BigIntImpl operator ^(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (_isZero) return other;
+    if (other._isZero) return this;
+    if (_isNegative == other._isNegative) {
+      if (_isNegative) {
+        // (-this) ^ (-other) == ~(this-1) ^ ~(other-1) == (this-1) ^ (other-1)
+        var this1 = _absSubSetSign(one, true);
+        var other1 = other._absSubSetSign(one, true);
+        return this1._absXorSetSign(other1, false);
+      }
+      return _absXorSetSign(other, false);
+    }
+    // _isNegative != a._isNegative
+    var p, n;
+    if (_isNegative) {
+      p = other;
+      n = this;
+    } else {
+      // ^ is symmetric.
+      p = this;
+      n = other;
+    }
+    // p ^ (-n) == p ^ ~(n-1) == ~(p ^ (n-1)) == -((p ^ (n-1)) + 1)
+    var n1 = n._absSubSetSign(one, true);
+    // Result cannot be zero if only one of this or a is negative.
+    return p._absXorSetSign(n1, true)._absAddSetSign(one, true);
+  }
+
+  /**
+   * The bit-wise negate operator.
+   *
+   * Treating `this` as a sufficiently large two's component integer,
+   * the result is a number with the opposite bits set.
+   *
+   * This maps any integer `x` to `-x - 1`.
+   */
+  _BigIntImpl operator ~() {
+    if (_isZero) return _minusOne;
+    if (_isNegative) {
+      // ~(-this) == ~(~(this-1)) == this-1
+      return _absSubSetSign(one, false);
+    }
+    // ~this == -this-1 == -(this+1)
+    // Result cannot be zero if this is positive.
+    return _absAddSetSign(one, true);
+  }
+
+  /// Addition operator.
+  _BigIntImpl operator +(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (_isZero) return other;
+    if (other._isZero) return this;
+    var isNegative = _isNegative;
+    if (isNegative == other._isNegative) {
+      // this + other == this + other
+      // (-this) + (-other) == -(this + other)
+      return _absAddSetSign(other, isNegative);
+    }
+    // this + (-other) == this - other == -(this - other)
+    // (-this) + other == other - this == -(this - other)
+    if (_absCompare(other) >= 0) {
+      return _absSubSetSign(other, isNegative);
+    }
+    return other._absSubSetSign(this, !isNegative);
+  }
+
+  /// Subtraction operator.
+  _BigIntImpl operator -(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (_isZero) return -other;
+    if (other._isZero) return this;
+    var isNegative = _isNegative;
+    if (isNegative != other._isNegative) {
+      // this - (-other) == this + other
+      // (-this) - other == -(this + other)
+      return _absAddSetSign(other, isNegative);
+    }
+    // this - other == this - a == -(this - other)
+    // (-this) - (-other) == other - this == -(this - other)
+    if (_absCompare(other) >= 0) {
+      return _absSubSetSign(other, isNegative);
+    }
+    return other._absSubSetSign(this, !isNegative);
+  }
+
+  /// Multiplies [x] with [multiplicandDigits] and adds the result to
+  /// [accumulatorDigits].
+  ///
+  /// The [multiplicandDigits] in the range [i] to [i]+[n]-1 are the
+  /// multiplicand digits.
+  ///
+  /// The [acculumatorDigits] in the range [j] to [j]+[n]-1 are the accumulator
+  /// digits.
+  ///
+  /// Adds the result of the multiplicand-digits * [x] to the accumulator.
+  ///
+  /// Concretely: `accumulatorDigits[j..j+n] += x * m_digits[i..i+n-1]`.
+  static void _mulAdd(int x, Uint16List multiplicandDigits, int i,
+      Uint16List accumulatorDigits, int j, int n) {
+    if (x == 0) {
+      // No-op if x is 0.
+      return;
+    }
+    int c = 0;
+    while (--n >= 0) {
+      int product = x * multiplicandDigits[i++];
+      int combined = product + accumulatorDigits[j] + c;
+      accumulatorDigits[j++] = combined & _digitMask;
+      // Note that this works with 53 bits, as the division will not lose
+      // bits.
+      c = combined ~/ _digitBase;
+    }
+    while (c != 0) {
+      int l = accumulatorDigits[j] + c;
+      accumulatorDigits[j++] = l & _digitMask;
+      c = l ~/ _digitBase;
+    }
+  }
+
+  /// Multiplication operator.
+  _BigIntImpl operator *(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    var used = _used;
+    var otherUsed = other._used;
+    if (used == 0 || otherUsed == 0) {
+      return zero;
+    }
+    var resultUsed = used + otherUsed;
+    var digits = _digits;
+    var otherDigits = other._digits;
+    var resultDigits = Uint16List(resultUsed);
+    var i = 0;
+    while (i < otherUsed) {
+      _mulAdd(otherDigits[i], digits, 0, resultDigits, i, used);
+      i++;
+    }
+    return _BigIntImpl._(
+        _isNegative != other._isNegative, resultUsed, resultDigits);
+  }
+
+  // r_digits[0..rUsed-1] = xDigits[0..xUsed-1]*otherDigits[0..otherUsed-1].
+  // Return resultUsed = xUsed + otherUsed.
+  static int _mulDigits(Uint16List xDigits, int xUsed, Uint16List otherDigits,
+      int otherUsed, Uint16List resultDigits) {
+    var resultUsed = xUsed + otherUsed;
+    var i = resultUsed;
+    assert(resultDigits.length >= i);
+    while (--i >= 0) {
+      resultDigits[i] = 0;
+    }
+    i = 0;
+    while (i < otherUsed) {
+      _mulAdd(otherDigits[i], xDigits, 0, resultDigits, i, xUsed);
+      i++;
+    }
+    return resultUsed;
+  }
+
+  /// Returns an estimate of `digits[i-1..i] ~/ topDigitDivisor`.
+  static int _estimateQuotientDigit(
+      int topDigitDivisor, Uint16List digits, int i) {
+    if (digits[i] == topDigitDivisor) return _digitMask;
+    var quotientDigit =
+        (digits[i] << _digitBits | digits[i - 1]) ~/ topDigitDivisor;
+    if (quotientDigit > _digitMask) return _digitMask;
+    return quotientDigit;
+  }
+
+  /// Returns `trunc(this / other)`, with `other != 0`.
+  _BigIntImpl _div(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    assert(other._used > 0);
+    if (_used < other._used) {
+      return zero;
+    }
+    _divRem(other);
+    // Return quotient, i.e.
+    // _lastQuoRem_digits[_lastRem_used.._lastQuoRem_used-1] with proper sign.
+    var lastQuo_used = _lastQuoRemUsed - _lastRemUsed;
+    var quo_digits = _cloneDigits(
+        _lastQuoRemDigits, _lastRemUsed, _lastQuoRemUsed, lastQuo_used);
+    var quo = _BigIntImpl._(false, lastQuo_used, quo_digits);
+    if ((_isNegative != other._isNegative) && (quo._used > 0)) {
+      quo = -quo;
+    }
+    return quo;
+  }
+
+  /// Returns `this - other * trunc(this / other)`, with `other != 0`.
+  _BigIntImpl _rem(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    assert(other._used > 0);
+    if (_used < other._used) {
+      return this;
+    }
+    _divRem(other);
+    // Return remainder, i.e.
+    // denormalized _lastQuoRem_digits[0.._lastRem_used-1] with proper sign.
+    var remDigits =
+        _cloneDigits(_lastQuoRemDigits, 0, _lastRemUsed, _lastRemUsed);
+    var rem = _BigIntImpl._(false, _lastRemUsed, remDigits);
+    if (_lastRem_nsh > 0) {
+      rem = rem >> _lastRem_nsh; // Denormalize remainder.
+    }
+    if (_isNegative && (rem._used > 0)) {
+      rem = -rem;
+    }
+    return rem;
+  }
+
+  /// Computes this ~/ other and this.remainder(other).
+  ///
+  /// Stores the result in [_lastQuoRemDigits], [_lastQuoRemUsed] and
+  /// [_lastRemUsed]. The [_lastQuoRemDigits] contains the digits of *both*, the
+  /// quotient and the remainder.
+  ///
+  /// Caches the input to avoid doing the work again when users write
+  /// `a ~/ b` followed by a `a % b`.
+  void _divRem(_BigIntImpl other) {
+    // Check if result is already cached.
+    if ((this._used == _lastDividendUsed) &&
+        (other._used == _lastDivisorUsed) &&
+        identical(this._digits, _lastDividendDigits) &&
+        identical(other._digits, _lastDivisorDigits)) {
+      return;
+    }
+    assert(_used >= other._used);
+
+    var nsh = _digitBits - other._digits[other._used - 1].bitLength;
+    // Concatenated positive quotient and normalized positive remainder.
+    // The resultDigits can have at most one more digit than the dividend.
+    Uint16List resultDigits;
+    int resultUsed;
+    // Normalized positive divisor.
+    // The normalized divisor has the most-significant bit of its most
+    // significant digit set.
+    // This makes estimating the quotient easier.
+    Uint16List yDigits;
+    int yUsed;
+    if (nsh > 0) {
+      yDigits = Uint16List(other._used + 5);
+      yUsed = _lShiftDigits(other._digits, other._used, nsh, yDigits);
+      resultDigits = Uint16List(_used + 5);
+      resultUsed = _lShiftDigits(_digits, _used, nsh, resultDigits);
+    } else {
+      yDigits = other._digits;
+      yUsed = other._used;
+      resultDigits = _cloneDigits(_digits, 0, _used, _used + 2);
+      resultUsed = _used;
+    }
+    var topDigitDivisor = yDigits[yUsed - 1];
+    var i = resultUsed;
+    var j = i - yUsed;
+    // tmpDigits is a temporary array of i (resultUsed) digits.
+    var tmpDigits = Uint16List(i);
+    var tmpUsed = _dlShiftDigits(yDigits, yUsed, j, tmpDigits);
+    // Explicit first division step in case normalized dividend is larger or
+    // equal to shifted normalized divisor.
+    if (_compareDigits(resultDigits, resultUsed, tmpDigits, tmpUsed) >= 0) {
+      assert(i == resultUsed);
+      resultDigits[resultUsed++] = 1; // Quotient = 1.
+      // Subtract divisor from remainder.
+      _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+    } else {
+      // Account for possible carry in _mulAdd step.
+      resultDigits[resultUsed++] = 0;
+    }
+
+    // Negate y so we can later use _mulAdd instead of non-existent _mulSub.
+    var nyDigits = Uint16List(yUsed + 2);
+    nyDigits[yUsed] = 1;
+    _absSub(nyDigits, yUsed + 1, yDigits, yUsed, nyDigits);
+    // nyDigits is read-only and has yUsed digits (possibly including several
+    // leading zeros).
+    // resultDigits is modified during iteration.
+    // resultDigits[0..yUsed-1] is the current remainder.
+    // resultDigits[yUsed..resultUsed-1] is the current quotient.
+    --i;
+
+    while (j > 0) {
+      var estimatedQuotientDigit =
+          _estimateQuotientDigit(topDigitDivisor, resultDigits, i);
+      j--;
+      _mulAdd(estimatedQuotientDigit, nyDigits, 0, resultDigits, j, yUsed);
+      if (resultDigits[i] < estimatedQuotientDigit) {
+        // Reusing the already existing tmpDigits array.
+        var tmpUsed = _dlShiftDigits(nyDigits, yUsed, j, tmpDigits);
+        _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+        while (resultDigits[i] < --estimatedQuotientDigit) {
+          _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+        }
+      }
+      i--;
+    }
+    // Cache result.
+    _lastDividendDigits = _digits;
+    _lastDividendUsed = _used;
+    _lastDivisorDigits = other._digits;
+    _lastDivisorUsed = other._used;
+    _lastQuoRemDigits = resultDigits;
+    _lastQuoRemUsed = resultUsed;
+    _lastRemUsed = yUsed;
+    _lastRem_nsh = nsh;
+  }
+
+  int get hashCode {
+    // This is the [Jenkins hash function][1] but using masking to keep
+    // values in SMI range.
+    //
+    // [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
+
+    int combine(int hash, int value) {
+      hash = 0x1fffffff & (hash + value);
+      hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
+      return hash ^ (hash >> 6);
+    }
+
+    int finish(int hash) {
+      hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
+      hash = hash ^ (hash >> 11);
+      return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
+    }
+
+    if (_isZero) return 6707; // Just a random number.
+    var hash = _isNegative ? 83585 : 429689; // Also random.
+    for (int i = 0; i < _used; i++) {
+      hash = combine(hash, _digits[i]);
+    }
+    return finish(hash);
+  }
+
+  /**
+   * Test whether this value is numerically equal to `other`.
+   *
+   * If [other] is a [_BigIntImpl] returns whether the two operands have the same
+   * value.
+   *
+   * Returns false if `other` is not a [_BigIntImpl].
+   */
+  bool operator ==(Object other) =>
+      other is _BigIntImpl && compareTo(other) == 0;
+
+  /**
+   * Returns the minimum number of bits required to store this big integer.
+   *
+   * The number of bits excludes the sign bit, which gives the natural length
+   * for non-negative (unsigned) values.  Negative values are complemented to
+   * return the bit position of the first bit that differs from the sign bit.
+   *
+   * To find the number of bits needed to store the value as a signed value,
+   * add one, i.e. use `x.bitLength + 1`.
+   *
+   * ```
+   * x.bitLength == (-x-1).bitLength
+   *
+   * new BigInt.from(3).bitLength == 2;   // 00000011
+   * new BigInt.from(2).bitLength == 2;   // 00000010
+   * new BigInt.from(1).bitLength == 1;   // 00000001
+   * new BigInt.from(0).bitLength == 0;   // 00000000
+   * new BigInt.from(-1).bitLength == 0;  // 11111111
+   * new BigInt.from(-2).bitLength == 1;  // 11111110
+   * new BigInt.from(-3).bitLength == 2;  // 11111101
+   * new BigInt.from(-4).bitLength == 2;  // 11111100
+   * ```
+   */
+  int get bitLength {
+    if (_used == 0) return 0;
+    if (_isNegative) return (~this).bitLength;
+    return _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
+  }
+
+  /**
+   * Truncating division operator.
+   *
+   * Performs a truncating integer division, where the remainder is discarded.
+   *
+   * The remainder can be computed using the [remainder] method.
+   *
+   * Examples:
+   * ```
+   * var seven = new BigInt.from(7);
+   * var three = new BigInt.from(3);
+   * seven ~/ three;    // => 2
+   * (-seven) ~/ three; // => -2
+   * seven ~/ -three;   // => -2
+   * seven.remainder(three);    // => 1
+   * (-seven).remainder(three); // => -1
+   * seven.remainder(-three);   // => 1
+   * ```
+   */
+  _BigIntImpl operator ~/(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (other._used == 0) {
+      throw const IntegerDivisionByZeroException();
+    }
+    return _div(other);
+  }
+
+  /**
+   * Returns the remainder of the truncating division of `this` by [other].
+   *
+   * The result `r` of this operation satisfies:
+   * `this == (this ~/ other) * other + r`.
+   * As a consequence the remainder `r` has the same sign as the divider `this`.
+   */
+  _BigIntImpl remainder(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (other._used == 0) {
+      throw const IntegerDivisionByZeroException();
+    }
+    return _rem(other);
+  }
+
+  /// Division operator.
+  double operator /(BigInt other) => this.toDouble() / other.toDouble();
+
+  /** Relational less than operator. */
+  bool operator <(BigInt other) => compareTo(other) < 0;
+
+  /** Relational less than or equal operator. */
+  bool operator <=(BigInt other) => compareTo(other) <= 0;
+
+  /** Relational greater than operator. */
+  bool operator >(BigInt other) => compareTo(other) > 0;
+
+  /** Relational greater than or equal operator. */
+  bool operator >=(BigInt other) => compareTo(other) >= 0;
+
+  /**
+   * Euclidean modulo operator.
+   *
+   * Returns the remainder of the Euclidean division. The Euclidean division of
+   * two integers `a` and `b` yields two integers `q` and `r` such that
+   * `a == b * q + r` and `0 <= r < b.abs()`.
+   *
+   * The sign of the returned value `r` is always positive.
+   *
+   * See [remainder] for the remainder of the truncating division.
+   */
+  _BigIntImpl operator %(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (other._used == 0) {
+      throw const IntegerDivisionByZeroException();
+    }
+    var result = _rem(other);
+    if (result._isNegative) {
+      if (other._isNegative) {
+        result = result - other;
+      } else {
+        result = result + other;
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Returns the sign of this big integer.
+   *
+   * Returns 0 for zero, -1 for values less than zero and
+   * +1 for values greater than zero.
+   */
+  int get sign {
+    if (_used == 0) return 0;
+    return _isNegative ? -1 : 1;
+  }
+
+  /// Whether this big integer is even.
+  bool get isEven => _used == 0 || (_digits[0] & 1) == 0;
+
+  /// Whether this big integer is odd.
+  bool get isOdd => !isEven;
+
+  /// Whether this number is negative.
+  bool get isNegative => _isNegative;
+
+  _BigIntImpl pow(int exponent) {
+    if (exponent < 0) {
+      throw ArgumentError("Exponent must not be negative: $exponent");
+    }
+    if (exponent == 0) return one;
+
+    // Exponentiation by squaring.
+    var result = one;
+    var base = this;
+    while (exponent != 0) {
+      if ((exponent & 1) == 1) {
+        result *= base;
+      }
+      exponent >>= 1;
+      // Skip unnecessary operation.
+      if (exponent != 0) {
+        base *= base;
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Returns this integer to the power of [exponent] modulo [modulus].
+   *
+   * The [exponent] must be non-negative and [modulus] must be
+   * positive.
+   */
+  _BigIntImpl modPow(BigInt bigExponent, BigInt bigModulus) {
+    _BigIntImpl exponent = bigExponent;
+    _BigIntImpl modulus = bigModulus;
+    if (exponent._isNegative) {
+      throw ArgumentError("exponent must be positive: $exponent");
+    }
+    if (modulus <= zero) {
+      throw ArgumentError("modulus must be strictly positive: $modulus");
+    }
+    if (exponent._isZero) return one;
+
+    final modulusUsed = modulus._used;
+    final modulusUsed2p4 = 2 * modulusUsed + 4;
+    final exponentBitlen = exponent.bitLength;
+    if (exponentBitlen <= 0) return one;
+    _BigIntReduction z = _BigIntClassic(modulus);
+    var resultDigits = Uint16List(modulusUsed2p4);
+    var result2Digits = Uint16List(modulusUsed2p4);
+    var gDigits = Uint16List(modulusUsed);
+    var gUsed = z.convert(this, gDigits);
+    // Initialize result with g.
+    // Copy leading zero if any.
+    for (int j = gUsed - 1; j >= 0; j--) {
+      resultDigits[j] = gDigits[j];
+    }
+    var resultUsed = gUsed;
+    var result2Used;
+    for (int i = exponentBitlen - 2; i >= 0; i--) {
+      result2Used = z.sqr(resultDigits, resultUsed, result2Digits);
+      if (!(exponent & (one << i))._isZero) {
+        resultUsed =
+            z.mul(result2Digits, result2Used, gDigits, gUsed, resultDigits);
+      } else {
+        // Swap result and result2.
+        var tmpDigits = resultDigits;
+        var tmpUsed = resultUsed;
+        resultDigits = result2Digits;
+        resultUsed = result2Used;
+        result2Digits = tmpDigits;
+        result2Used = tmpUsed;
+      }
+    }
+    return z.revert(resultDigits, resultUsed);
+  }
+
+  // If inv is false, returns gcd(x, y).
+  // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1.
+  // If inv is true and gcd(x, y) != 1, throws Exception("Not coprime").
+  static _BigIntImpl _binaryGcd(_BigIntImpl x, _BigIntImpl y, bool inv) {
+    var xDigits = x._digits;
+    var yDigits = y._digits;
+    var xUsed = x._used;
+    var yUsed = y._used;
+    var maxUsed = xUsed > yUsed ? xUsed : yUsed;
+    var unshiftedMaxUsed = maxUsed; // Keep
+    xDigits = _cloneDigits(xDigits, 0, xUsed, maxUsed);
+    yDigits = _cloneDigits(yDigits, 0, yUsed, maxUsed);
+    int shiftAmount = 0;
+    if (inv) {
+      if ((yUsed == 1) && (yDigits[0] == 1)) return one;
+      if ((yUsed == 0) || (yDigits[0].isEven && xDigits[0].isEven)) {
+        throw Exception("Not coprime");
+      }
+    } else {
+      if (x._isZero) {
+        throw ArgumentError.value(0, "this", "must not be zero");
+      }
+      if (y._isZero) {
+        throw ArgumentError.value(0, "other", "must not be zero");
+      }
+      if (((xUsed == 1) && (xDigits[0] == 1)) ||
+          ((yUsed == 1) && (yDigits[0] == 1))) return one;
+      while (((xDigits[0] & 1) == 0) && ((yDigits[0] & 1) == 0)) {
+        _rsh(xDigits, xUsed, 1, xDigits);
+        _rsh(yDigits, yUsed, 1, yDigits);
+        shiftAmount++;
+      }
+      if (shiftAmount >= _digitBits) {
+        var digitShiftAmount = shiftAmount ~/ _digitBits;
+        xUsed -= digitShiftAmount;
+        yUsed -= digitShiftAmount;
+        maxUsed -= digitShiftAmount;
+      }
+      if ((yDigits[0] & 1) == 1) {
+        // Swap x and y.
+        var tmpDigits = xDigits;
+        var tmpUsed = xUsed;
+        xDigits = yDigits;
+        xUsed = yUsed;
+        yDigits = tmpDigits;
+        yUsed = tmpUsed;
+      }
+    }
+    var uDigits = _cloneDigits(xDigits, 0, xUsed, unshiftedMaxUsed);
+    var vDigits =
+        _cloneDigits(yDigits, 0, yUsed, unshiftedMaxUsed + 2); // +2 for lsh.
+    final bool ac = (xDigits[0] & 1) == 0;
+
+    // Variables a, b, c, and d require one more digit.
+    final abcdUsed = maxUsed + 1;
+    final abcdLen = abcdUsed + 2; // +2 to satisfy _absAdd.
+    var aDigits, bDigits, cDigits, dDigits;
+    bool aIsNegative, bIsNegative, cIsNegative, dIsNegative;
+    if (ac) {
+      aDigits = Uint16List(abcdLen);
+      aIsNegative = false;
+      aDigits[0] = 1;
+      cDigits = Uint16List(abcdLen);
+      cIsNegative = false;
+    }
+    bDigits = Uint16List(abcdLen);
+    bIsNegative = false;
+    dDigits = Uint16List(abcdLen);
+    dIsNegative = false;
+    dDigits[0] = 1;
+
+    while (true) {
+      while ((uDigits[0] & 1) == 0) {
+        _rsh(uDigits, maxUsed, 1, uDigits);
+        if (ac) {
+          if (((aDigits[0] & 1) == 1) || ((bDigits[0] & 1) == 1)) {
+            // a += y
+            if (aIsNegative) {
+              if ((aDigits[maxUsed] != 0) ||
+                  (_compareDigits(aDigits, maxUsed, yDigits, maxUsed)) > 0) {
+                _absSub(aDigits, abcdUsed, yDigits, maxUsed, aDigits);
+              } else {
+                _absSub(yDigits, maxUsed, aDigits, maxUsed, aDigits);
+                aIsNegative = false;
+              }
+            } else {
+              _absAdd(aDigits, abcdUsed, yDigits, maxUsed, aDigits);
+            }
+            // b -= x
+            if (bIsNegative) {
+              _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+            } else if ((bDigits[maxUsed] != 0) ||
+                (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) {
+              _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+            } else {
+              _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits);
+              bIsNegative = true;
+            }
+          }
+          _rsh(aDigits, abcdUsed, 1, aDigits);
+        } else if ((bDigits[0] & 1) == 1) {
+          // b -= x
+          if (bIsNegative) {
+            _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+          } else if ((bDigits[maxUsed] != 0) ||
+              (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) {
+            _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+          } else {
+            _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits);
+            bIsNegative = true;
+          }
+        }
+        _rsh(bDigits, abcdUsed, 1, bDigits);
+      }
+      while ((vDigits[0] & 1) == 0) {
+        _rsh(vDigits, maxUsed, 1, vDigits);
+        if (ac) {
+          if (((cDigits[0] & 1) == 1) || ((dDigits[0] & 1) == 1)) {
+            // c += y
+            if (cIsNegative) {
+              if ((cDigits[maxUsed] != 0) ||
+                  (_compareDigits(cDigits, maxUsed, yDigits, maxUsed) > 0)) {
+                _absSub(cDigits, abcdUsed, yDigits, maxUsed, cDigits);
+              } else {
+                _absSub(yDigits, maxUsed, cDigits, maxUsed, cDigits);
+                cIsNegative = false;
+              }
+            } else {
+              _absAdd(cDigits, abcdUsed, yDigits, maxUsed, cDigits);
+            }
+            // d -= x
+            if (dIsNegative) {
+              _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+            } else if ((dDigits[maxUsed] != 0) ||
+                (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+              _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+            } else {
+              _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+              dIsNegative = true;
+            }
+          }
+          _rsh(cDigits, abcdUsed, 1, cDigits);
+        } else if ((dDigits[0] & 1) == 1) {
+          // d -= x
+          if (dIsNegative) {
+            _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+          } else if ((dDigits[maxUsed] != 0) ||
+              (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+            _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+          } else {
+            _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+            dIsNegative = true;
+          }
+        }
+        _rsh(dDigits, abcdUsed, 1, dDigits);
+      }
+      if (_compareDigits(uDigits, maxUsed, vDigits, maxUsed) >= 0) {
+        // u -= v
+        _absSub(uDigits, maxUsed, vDigits, maxUsed, uDigits);
+        if (ac) {
+          // a -= c
+          if (aIsNegative == cIsNegative) {
+            var a_cmp_c = _compareDigits(aDigits, abcdUsed, cDigits, abcdUsed);
+            if (a_cmp_c > 0) {
+              _absSub(aDigits, abcdUsed, cDigits, abcdUsed, aDigits);
+            } else {
+              _absSub(cDigits, abcdUsed, aDigits, abcdUsed, aDigits);
+              aIsNegative = !aIsNegative && (a_cmp_c != 0);
+            }
+          } else {
+            _absAdd(aDigits, abcdUsed, cDigits, abcdUsed, aDigits);
+          }
+        }
+        // b -= d
+        if (bIsNegative == dIsNegative) {
+          var b_cmp_d = _compareDigits(bDigits, abcdUsed, dDigits, abcdUsed);
+          if (b_cmp_d > 0) {
+            _absSub(bDigits, abcdUsed, dDigits, abcdUsed, bDigits);
+          } else {
+            _absSub(dDigits, abcdUsed, bDigits, abcdUsed, bDigits);
+            bIsNegative = !bIsNegative && (b_cmp_d != 0);
+          }
+        } else {
+          _absAdd(bDigits, abcdUsed, dDigits, abcdUsed, bDigits);
+        }
+      } else {
+        // v -= u
+        _absSub(vDigits, maxUsed, uDigits, maxUsed, vDigits);
+        if (ac) {
+          // c -= a
+          if (cIsNegative == aIsNegative) {
+            var c_cmp_a = _compareDigits(cDigits, abcdUsed, aDigits, abcdUsed);
+            if (c_cmp_a > 0) {
+              _absSub(cDigits, abcdUsed, aDigits, abcdUsed, cDigits);
+            } else {
+              _absSub(aDigits, abcdUsed, cDigits, abcdUsed, cDigits);
+              cIsNegative = !cIsNegative && (c_cmp_a != 0);
+            }
+          } else {
+            _absAdd(cDigits, abcdUsed, aDigits, abcdUsed, cDigits);
+          }
+        }
+        // d -= b
+        if (dIsNegative == bIsNegative) {
+          var d_cmp_b = _compareDigits(dDigits, abcdUsed, bDigits, abcdUsed);
+          if (d_cmp_b > 0) {
+            _absSub(dDigits, abcdUsed, bDigits, abcdUsed, dDigits);
+          } else {
+            _absSub(bDigits, abcdUsed, dDigits, abcdUsed, dDigits);
+            dIsNegative = !dIsNegative && (d_cmp_b != 0);
+          }
+        } else {
+          _absAdd(dDigits, abcdUsed, bDigits, abcdUsed, dDigits);
+        }
+      }
+      // Exit loop if u == 0.
+      var i = maxUsed;
+      while ((i > 0) && (uDigits[i - 1] == 0)) --i;
+      if (i == 0) break;
+    }
+    if (!inv) {
+      if (shiftAmount > 0) {
+        maxUsed = _lShiftDigits(vDigits, maxUsed, shiftAmount, vDigits);
+      }
+      return _BigIntImpl._(false, maxUsed, vDigits);
+    }
+    // No inverse if v != 1.
+    var i = maxUsed - 1;
+    while ((i > 0) && (vDigits[i] == 0)) --i;
+    if ((i != 0) || (vDigits[0] != 1)) {
+      throw Exception("Not coprime");
+    }
+
+    if (dIsNegative) {
+      while ((dDigits[maxUsed] != 0) ||
+          (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+        // d += x, d still negative
+        _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+      }
+      // d += x
+      _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+      dIsNegative = false;
+    } else {
+      while ((dDigits[maxUsed] != 0) ||
+          (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) >= 0)) {
+        // d -= x
+        _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+      }
+    }
+    return _BigIntImpl._(false, maxUsed, dDigits);
+  }
+
+  /**
+   * Returns the modular multiplicative inverse of this big integer
+   * modulo [modulus].
+   *
+   * The [modulus] must be positive.
+   *
+   * It is an error if no modular inverse exists.
+   */
+  // Returns 1/this % modulus, with modulus > 0.
+  _BigIntImpl modInverse(BigInt bigInt) {
+    _BigIntImpl modulus = bigInt;
+    if (modulus <= zero) {
+      throw ArgumentError("Modulus must be strictly positive: $modulus");
+    }
+    if (modulus == one) return zero;
+    var tmp = this;
+    if (tmp._isNegative || (tmp._absCompare(modulus) >= 0)) {
+      tmp %= modulus;
+    }
+    return _binaryGcd(modulus, tmp, true);
+  }
+
+  /**
+   * Returns the greatest common divisor of this big integer and [other].
+   *
+   * If either number is non-zero, the result is the numerically greatest
+   * integer dividing both `this` and `other`.
+   *
+   * The greatest common divisor is independent of the order,
+   * so `x.gcd(y)` is  always the same as `y.gcd(x)`.
+   *
+   * For any integer `x`, `x.gcd(x)` is `x.abs()`.
+   *
+   * If both `this` and `other` is zero, the result is also zero.
+   */
+  _BigIntImpl gcd(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (_isZero) return other.abs();
+    if (other._isZero) return this.abs();
+    return _binaryGcd(this, other, false);
+  }
+
+  /**
+   * Returns the least significant [width] bits of this big integer as a
+   * non-negative number (i.e. unsigned representation).  The returned value has
+   * zeros in all bit positions higher than [width].
+   *
+   * ```
+   * new BigInt.from(-1).toUnsigned(5) == 31   // 11111111  ->  00011111
+   * ```
+   *
+   * This operation can be used to simulate arithmetic from low level languages.
+   * For example, to increment an 8 bit quantity:
+   *
+   * ```
+   * q = (q + 1).toUnsigned(8);
+   * ```
+   *
+   * `q` will count from `0` up to `255` and then wrap around to `0`.
+   *
+   * If the input fits in [width] bits without truncation, the result is the
+   * same as the input.  The minimum width needed to avoid truncation of `x` is
+   * given by `x.bitLength`, i.e.
+   *
+   * ```
+   * x == x.toUnsigned(x.bitLength);
+   * ```
+   */
+  _BigIntImpl toUnsigned(int width) {
+    return this & ((one << width) - one);
+  }
+
+  /**
+   * Returns the least significant [width] bits of this integer, extending the
+   * highest retained bit to the sign.  This is the same as truncating the value
+   * to fit in [width] bits using an signed 2-s complement representation.  The
+   * returned value has the same bit value in all positions higher than [width].
+   *
+   * ```
+   * var big15 = new BigInt.from(15);
+   * var big16 = new BigInt.from(16);
+   * var big239 = new BigInt.from(239);
+   *                                      V--sign bit-V
+   * big16.toSigned(5) == -big16   //  00010000 -> 11110000
+   * big239.toSigned(5) == big15   //  11101111 -> 00001111
+   *                                      ^           ^
+   * ```
+   *
+   * This operation can be used to simulate arithmetic from low level languages.
+   * For example, to increment an 8 bit signed quantity:
+   *
+   * ```
+   * q = (q + 1).toSigned(8);
+   * ```
+   *
+   * `q` will count from `0` up to `127`, wrap to `-128` and count back up to
+   * `127`.
+   *
+   * If the input value fits in [width] bits without truncation, the result is
+   * the same as the input.  The minimum width needed to avoid truncation of `x`
+   * is `x.bitLength + 1`, i.e.
+   *
+   * ```
+   * x == x.toSigned(x.bitLength + 1);
+   * ```
+   */
+  _BigIntImpl toSigned(int width) {
+    // The value of binary number weights each bit by a power of two.  The
+    // twos-complement value weights the sign bit negatively.  We compute the
+    // value of the negative weighting by isolating the sign bit with the
+    // correct power of two weighting and subtracting it from the value of the
+    // lower bits.
+    var signMask = one << (width - 1);
+    return (this & (signMask - one)) - (this & signMask);
+  }
+
+  // Maximum number of digits that always fit in mantissa.
+  static const _simpleValidIntDigits = 53 ~/ _digitBits;
+
+  bool get isValidInt {
+    if (_used <= _simpleValidIntDigits) return true;
+    var asInt = toInt();
+    if (!asInt.toDouble().isFinite) return false;
+    return this == _BigIntImpl._fromInt(asInt);
+  }
+
+  int toInt() {
+    var result = 0;
+    for (int i = _used - 1; i >= 0; i--) {
+      result = result * _digitBase + _digits[i];
+    }
+    return _isNegative ? -result : result;
+  }
+
+  /**
+   * Returns this [_BigIntImpl] as a [double].
+   *
+   * If the number is not representable as a [double], an
+   * approximation is returned. For numerically large integers, the
+   * approximation may be infinite.
+   */
+  double toDouble() {
+    const int exponentBias = 1075;
+    // There are 11 bits for the exponent.
+    // 2047 (all bits set to 1) is reserved for infinity and NaN.
+    // When storing the exponent in the 11 bits, it is biased by exponentBias
+    // to support negative exponents.
+    const int maxDoubleExponent = 2046 - exponentBias;
+    if (_isZero) return 0.0;
+
+    // We fill the 53 bits little-endian.
+    var resultBits = Uint8List(8);
+
+    var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
+    if (length > maxDoubleExponent + 53) {
+      return _isNegative ? double.negativeInfinity : double.infinity;
+    }
+
+    // The most significant bit is for the sign.
+    if (_isNegative) resultBits[7] = 0x80;
+
+    // Write the exponent into bits 1..12:
+    var biasedExponent = length - 53 + exponentBias;
+    resultBits[6] = (biasedExponent & 0xF) << 4;
+    resultBits[7] |= biasedExponent >> 4;
+
+    int cachedBits = 0;
+    int cachedBitsLength = 0;
+    int digitIndex = _used - 1;
+    int readBits(int n) {
+      // Ensure that we have enough bits in [cachedBits].
+      while (cachedBitsLength < n) {
+        int nextDigit;
+        int nextDigitLength = _digitBits; // May get updated.
+        if (digitIndex < 0) {
+          nextDigit = 0;
+          digitIndex--;
+        } else {
+          nextDigit = _digits[digitIndex];
+          if (digitIndex == _used - 1) nextDigitLength = nextDigit.bitLength;
+          digitIndex--;
+        }
+        cachedBits = (cachedBits << nextDigitLength) + nextDigit;
+        cachedBitsLength += nextDigitLength;
+      }
+      // Read the top [n] bits.
+      var result = cachedBits >> (cachedBitsLength - n);
+      // Remove the bits from the cache.
+      cachedBits -= result << (cachedBitsLength - n);
+      cachedBitsLength -= n;
+      return result;
+    }
+
+    // The first leading 1 bit is implicit in the double-representation and can
+    // be discarded.
+    var leadingBits = readBits(5) & 0xF;
+    resultBits[6] |= leadingBits;
+
+    for (int i = 5; i >= 0; i--) {
+      // Get the remaining 48 bits.
+      resultBits[i] = readBits(8);
+    }
+
+    void roundUp() {
+      // Simply consists of adding 1 to the whole 64 bit "number".
+      // It will update the exponent, if necessary.
+      // It might even round up to infinity (which is what we want).
+      var carry = 1;
+      for (int i = 0; i < 8; i++) {
+        if (carry == 0) break;
+        var sum = resultBits[i] + carry;
+        resultBits[i] = sum & 0xFF;
+        carry = sum >> 8;
+      }
+    }
+
+    if (readBits(1) == 1) {
+      if (resultBits[0].isOdd) {
+        // Rounds to even all the time.
+        roundUp();
+      } else {
+        // Round up, if there is at least one other digit that is not 0.
+        if (cachedBits != 0) {
+          // There is already one in the cachedBits.
+          roundUp();
+        } else {
+          for (int i = digitIndex; digitIndex >= 0; i--) {
+            if (_digits[i] != 0) {
+              roundUp();
+              break;
+            }
+          }
+        }
+      }
+    }
+    return resultBits.buffer.asByteData().getFloat64(0, Endian.little);
+  }
+
+  /**
+   * Returns a String-representation of this integer.
+   *
+   * The returned string is parsable by [parse].
+   * For any `_BigIntImpl` `i`, it is guaranteed that
+   * `i == _BigIntImpl.parse(i.toString())`.
+   */
+  String toString() {
+    if (_used == 0) return "0";
+    if (_used == 1) {
+      if (_isNegative) return (-_digits[0]).toString();
+      return _digits[0].toString();
+    }
+
+    // Generate in chunks of 4 digits.
+    // The chunks are in reversed order.
+    var decimalDigitChunks = <String>[];
+    var rest = isNegative ? -this : this;
+    while (rest._used > 1) {
+      var digits4 = rest.remainder(_bigInt10000).toString();
+      decimalDigitChunks.add(digits4);
+      if (digits4.length == 1) decimalDigitChunks.add("000");
+      if (digits4.length == 2) decimalDigitChunks.add("00");
+      if (digits4.length == 3) decimalDigitChunks.add("0");
+      rest = rest ~/ _bigInt10000;
+    }
+    decimalDigitChunks.add(rest._digits[0].toString());
+    if (_isNegative) decimalDigitChunks.add("-");
+    return decimalDigitChunks.reversed.join();
+  }
+
+  int _toRadixCodeUnit(int digit) {
+    const int _0 = 48;
+    const int _a = 97;
+    if (digit < 10) return _0 + digit;
+    return _a + digit - 10;
+  }
+
+  /**
+   * Converts [this] to a string representation in the given [radix].
+   *
+   * In the string representation, lower-case letters are used for digits above
+   * '9', with 'a' being 10 an 'z' being 35.
+   *
+   * The [radix] argument must be an integer in the range 2 to 36.
+   */
+  String toRadixString(int radix) {
+    if (radix > 36) throw RangeError.range(radix, 2, 36);
+
+    if (_used == 0) return "0";
+
+    if (_used == 1) {
+      var digitString = _digits[0].toRadixString(radix);
+      if (_isNegative) return "-" + digitString;
+      return digitString;
+    }
+
+    if (radix == 16) return _toHexString();
+
+    var base = _BigIntImpl._fromInt(radix);
+    var reversedDigitCodeUnits = <int>[];
+    var rest = this.abs();
+    while (!rest._isZero) {
+      var digit = rest.remainder(base).toInt();
+      rest = rest ~/ base;
+      reversedDigitCodeUnits.add(_toRadixCodeUnit(digit));
+    }
+    var digitString = String.fromCharCodes(reversedDigitCodeUnits.reversed);
+    if (_isNegative) return "-" + digitString;
+    return digitString;
+  }
+
+  String _toHexString() {
+    var chars = <int>[];
+    for (int i = 0; i < _used - 1; i++) {
+      int chunk = _digits[i];
+      for (int j = 0; j < (_digitBits ~/ 4); j++) {
+        chars.add(_toRadixCodeUnit(chunk & 0xF));
+        chunk >>= 4;
+      }
+    }
+    var msbChunk = _digits[_used - 1];
+    while (msbChunk != 0) {
+      chars.add(_toRadixCodeUnit(msbChunk & 0xF));
+      msbChunk >>= 4;
+    }
+    if (_isNegative) {
+      const _dash = 45;
+      chars.add(_dash);
+    }
+    return String.fromCharCodes(chars.reversed);
+  }
+}
+
+// Interface for modular reduction.
+abstract class _BigIntReduction {
+  // Return the number of digits used by r_digits.
+  int convert(_BigIntImpl x, Uint16List r_digits);
+  int mul(Uint16List xDigits, int xUsed, Uint16List yDigits, int yUsed,
+      Uint16List resultDigits);
+  int sqr(Uint16List xDigits, int xUsed, Uint16List resultDigits);
+
+  // Return x reverted to _BigIntImpl.
+  _BigIntImpl revert(Uint16List xDigits, int xUsed);
+}
+
+// Modular reduction using "classic" algorithm.
+class _BigIntClassic implements _BigIntReduction {
+  final _BigIntImpl _modulus; // Modulus.
+  final _BigIntImpl _normalizedModulus; // Normalized _modulus.
+
+  _BigIntClassic(this._modulus)
+      : _normalizedModulus = _modulus <<
+            (_BigIntImpl._digitBits -
+                _modulus._digits[_modulus._used - 1].bitLength);
+
+  int convert(_BigIntImpl x, Uint16List resultDigits) {
+    var digits;
+    var used;
+    if (x._isNegative || x._absCompare(_modulus) >= 0) {
+      var remainder = x._rem(_modulus);
+      if (x._isNegative && remainder._used > 0) {
+        assert(remainder._isNegative);
+        remainder += _modulus;
+      }
+      assert(!remainder._isNegative);
+      used = remainder._used;
+      digits = remainder._digits;
+    } else {
+      used = x._used;
+      digits = x._digits;
+    }
+    var i = used; // Copy leading zero if any.
+    while (--i >= 0) {
+      resultDigits[i] = digits[i];
+    }
+    return used;
+  }
+
+  _BigIntImpl revert(Uint16List xDigits, int xUsed) {
+    return _BigIntImpl._(false, xUsed, xDigits);
+  }
+
+  int _reduce(Uint16List xDigits, int xUsed) {
+    if (xUsed < _modulus._used) {
+      return xUsed;
+    }
+    var reverted = revert(xDigits, xUsed);
+    var rem = reverted._rem(_normalizedModulus);
+    return convert(rem, xDigits);
+  }
+
+  int sqr(Uint16List xDigits, int xUsed, Uint16List resultDigits) {
+    var b = _BigIntImpl._(false, xUsed, xDigits);
+    var b2 = b * b;
+    for (int i = 0; i < b2._used; i++) {
+      resultDigits[i] = b2._digits[i];
+    }
+    for (int i = b2._used; i < 2 * xUsed; i++) {
+      resultDigits[i] = 0;
+    }
+    return _reduce(resultDigits, 2 * xUsed);
+  }
+
+  int mul(Uint16List xDigits, int xUsed, Uint16List yDigits, int yUsed,
+      Uint16List resultDigits) {
+    var resultUsed =
+        _BigIntImpl._mulDigits(xDigits, xUsed, yDigits, yUsed, resultDigits);
+    return _reduce(resultDigits, resultUsed);
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/developer_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/developer_patch.dart
new file mode 100644
index 0000000..7f5e4fe
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/developer_patch.dart
@@ -0,0 +1,216 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Patch file for dart:developer library.
+
+import 'dart:_js_helper' show patch, ForceInline, ReifyFunctionTypes;
+import 'dart:_foreign_helper' show JS, JSExportName;
+import 'dart:_runtime' as dart;
+import 'dart:async';
+import 'dart:convert' show json;
+import 'dart:isolate';
+
+@patch
+@ForceInline()
+bool debugger({bool when = true, String message}) {
+  if (when) {
+    JS('', 'debugger');
+  }
+  return when;
+}
+
+@patch
+Object inspect(Object object) {
+  // Note: this log level does not show up by default in Chrome.
+  // This is used for communication with the debugger service.
+  JS('', 'console.debug("dart.developer.inspect", #)', object);
+  return object;
+}
+
+@patch
+void log(String message,
+    {DateTime time,
+    int sequenceNumber,
+    int level = 0,
+    String name = '',
+    Zone zone,
+    Object error,
+    StackTrace stackTrace}) {
+  Object items =
+      JS('!', '{ message: #, name: #, level: # }', message, name, level);
+  if (time != null) JS('', '#.time = #', items, time);
+  if (sequenceNumber != null) {
+    JS('', '#.sequenceNumber = #', items, sequenceNumber);
+  }
+  if (zone != null) JS('', '#.zone = #', items, zone);
+  if (error != null) JS('', '#.error = #', items, error);
+  if (stackTrace != null) JS('', '#.stackTrace = #', items, stackTrace);
+
+  JS('', 'console.debug("dart.developer.log", #)', items);
+}
+
+final _extensions = Map<String, ServiceExtensionHandler>();
+
+@patch
+ServiceExtensionHandler _lookupExtension(String method) {
+  return _extensions[method];
+}
+
+@patch
+_registerExtension(String method, ServiceExtensionHandler handler) {
+  _extensions[method] = handler;
+  JS('', 'console.debug("dart.developer.registerExtension", #)', method);
+}
+
+/// Returns a JS `Promise` that resolves with the result of invoking
+/// [methodName] with an [encodedJson] map as its parameters.
+///
+/// This is used by the VM Service Prototcol to invoke extensions registered
+/// with [registerExtension]. For example, in JS:
+///
+///     await sdk.developer.invokeExtension(
+/// .         "ext.flutter.inspector.getRootWidget", '{"objectGroup":""}');
+///
+@JSExportName('invokeExtension')
+@ReifyFunctionTypes(false)
+_invokeExtension(String methodName, String encodedJson) {
+  // TODO(vsm): We should factor this out as future<->promise.
+  return JS('', 'new #.Promise(#)', dart.global_,
+      (Function(Object) resolve, Function(Object) reject) async {
+    try {
+      var method = _lookupExtension(methodName);
+      var parameters = (json.decode(encodedJson) as Map).cast<String, String>();
+      var result = await method(methodName, parameters);
+      resolve(result._toString());
+    } catch (e) {
+      // TODO(vsm): Reject or encode in result?
+      reject('$e');
+    }
+  });
+}
+
+@patch
+void _postEvent(String eventKind, String eventData) {
+  JS('', 'console.debug("dart.developer.postEvent", #, #)', eventKind,
+      eventData);
+}
+
+@patch
+bool _isDartStreamEnabled() {
+  return false;
+}
+
+@patch
+int _getTraceClock() {
+  // TODO.
+  return _clockValue++;
+}
+
+int _clockValue = 0;
+
+@patch
+int _getThreadCpuClock() {
+  return -1;
+}
+
+@patch
+void _reportCompleteEvent(int start, int startCpu, String category, String name,
+    String argumentsAsJson) {
+  // TODO.
+}
+
+@patch
+void _reportFlowEvent(int start, int startCpu, String category, String name,
+    int type, int id, String argumentsAsJson) {
+  // TODO.
+}
+
+@patch
+void _reportInstantEvent(
+    int start, String category, String name, String argumentsAsJson) {
+  // TODO.
+}
+
+@patch
+int _getNextAsyncId() {
+  return 0;
+}
+
+@patch
+void _reportTaskEvent(int start, int taskId, String phase, String category,
+    String name, String argumentsAsJson) {
+  // TODO.
+}
+
+@patch
+int _getServiceMajorVersion() {
+  return 0;
+}
+
+@patch
+int _getServiceMinorVersion() {
+  return 0;
+}
+
+@patch
+void _getServerInfo(SendPort sendPort) {
+  sendPort.send(null);
+}
+
+@patch
+void _webServerControl(SendPort sendPort, bool enable) {
+  sendPort.send(null);
+}
+
+@patch
+String _getIsolateIDFromSendPort(SendPort sendPort) {
+  return null;
+}
+
+@patch
+class UserTag {
+  @patch
+  factory UserTag(String label) = _FakeUserTag;
+
+  @patch
+  static UserTag get defaultTag => _FakeUserTag._defaultTag;
+}
+
+class _FakeUserTag implements UserTag {
+  static Map _instances = {};
+
+  _FakeUserTag.real(this.label);
+
+  factory _FakeUserTag(String label) {
+    // Canonicalize by name.
+    var existingTag = _instances[label];
+    if (existingTag != null) {
+      return existingTag;
+    }
+    // Throw an exception if we've reached the maximum number of user tags.
+    if (_instances.length == UserTag.MAX_USER_TAGS) {
+      throw UnsupportedError(
+          'UserTag instance limit (${UserTag.MAX_USER_TAGS}) reached.');
+    }
+    // Create a new instance and add it to the instance map.
+    var instance = _FakeUserTag.real(label);
+    _instances[label] = instance;
+    return instance;
+  }
+
+  final String label;
+
+  UserTag makeCurrent() {
+    var old = _currentTag;
+    _currentTag = this;
+    return old;
+  }
+
+  static final UserTag _defaultTag = _FakeUserTag('Default');
+}
+
+var _currentTag = _FakeUserTag._defaultTag;
+
+@patch
+UserTag getCurrentTag() => _currentTag;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart
new file mode 100644
index 0000000..5e850bb
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.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.
+
+import 'dart:core' hide Symbol;
+import 'dart:core' as core show Symbol;
+import 'dart:_js_primitives' show printString;
+import 'dart:_js_helper' show patch;
+import 'dart:_interceptors' show JSArray;
+import 'dart:_foreign_helper' show JS;
+import 'dart:_runtime' as dart;
+
+@patch
+class Symbol implements core.Symbol {
+  @patch
+  const Symbol(String name) : this._name = name;
+
+  @patch
+  int get hashCode {
+    int hash = JS('int|Null', '#._hashCode', this);
+    if (hash != null) return hash;
+    const arbitraryPrime = 664597;
+    hash = 0x1fffffff & (arbitraryPrime * _name.hashCode);
+    JS('', '#._hashCode = #', this, hash);
+    return hash;
+  }
+
+  @patch
+  toString() => 'Symbol("$_name")';
+
+  @patch
+  static String computeUnmangledName(Symbol symbol) => symbol._name;
+}
+
+@patch
+void printToConsole(String line) {
+  printString('$line');
+}
+
+@patch
+List<E> makeListFixedLength<E>(List<E> growableList) {
+  JSArray.markFixedList(growableList);
+  return growableList;
+}
+
+@patch
+List<E> makeFixedListUnmodifiable<E>(List<E> fixedLengthList) {
+  JSArray.markUnmodifiableList(fixedLengthList);
+  return fixedLengthList;
+}
+
+@patch
+Object extractTypeArguments<T>(T instance, Function extract) =>
+    dart.extractTypeArguments<T>(instance, extract);
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart
new file mode 100644
index 0000000..61d031a
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart
@@ -0,0 +1,690 @@
+// 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:_js_helper' show patch;
+import 'dart:async';
+import 'dart:convert';
+import 'dart:isolate' show SendPort;
+import 'dart:typed_data';
+
+@patch
+class _Directory {
+  @patch
+  static _current(_Namespace namespace) {
+    throw UnsupportedError("Directory._current");
+  }
+
+  @patch
+  static _setCurrent(_Namespace namespace, Uint8List rawPath) {
+    throw UnsupportedError("Directory_SetCurrent");
+  }
+
+  @patch
+  static _createTemp(_Namespace namespace, Uint8List rawPath) {
+    throw UnsupportedError("Directory._createTemp");
+  }
+
+  @patch
+  static String _systemTemp(_Namespace namespace) {
+    throw UnsupportedError("Directory._systemTemp");
+  }
+
+  @patch
+  static _exists(_Namespace namespace, Uint8List rawPath) {
+    throw UnsupportedError("Directory._exists");
+  }
+
+  @patch
+  static _create(_Namespace namespace, Uint8List rawPath) {
+    throw UnsupportedError("Directory._create");
+  }
+
+  @patch
+  static _deleteNative(
+      _Namespace namespace, Uint8List rawPath, bool recursive) {
+    throw UnsupportedError("Directory._deleteNative");
+  }
+
+  @patch
+  static _rename(_Namespace namespace, Uint8List rawPath, String newPath) {
+    throw UnsupportedError("Directory._rename");
+  }
+
+  @patch
+  static void _fillWithDirectoryListing(
+      _Namespace namespace,
+      List<FileSystemEntity> list,
+      Uint8List rawPath,
+      bool recursive,
+      bool followLinks) {
+    throw UnsupportedError("Directory._fillWithDirectoryListing");
+  }
+}
+
+@patch
+class _AsyncDirectoryListerOps {
+  @patch
+  factory _AsyncDirectoryListerOps(int pointer) {
+    throw UnsupportedError("Directory._list");
+  }
+}
+
+@patch
+class _EventHandler {
+  @patch
+  static void _sendData(Object sender, SendPort sendPort, int data) {
+    throw UnsupportedError("EventHandler._sendData");
+  }
+}
+
+@patch
+class FileStat {
+  @patch
+  static _statSync(_Namespace namespace, String path) {
+    throw UnsupportedError("FileStat.stat");
+  }
+}
+
+@patch
+class FileSystemEntity {
+  @patch
+  static _getTypeNative(
+      _Namespace namespace, Uint8List rawPath, bool followLinks) {
+    throw UnsupportedError("FileSystemEntity._getType");
+  }
+
+  @patch
+  static _identicalNative(_Namespace namespace, String path1, String path2) {
+    throw UnsupportedError("FileSystemEntity._identical");
+  }
+
+  @patch
+  static _resolveSymbolicLinks(_Namespace namespace, Uint8List rawPath) {
+    throw UnsupportedError("FileSystemEntity._resolveSymbolicLinks");
+  }
+}
+
+@patch
+class _File {
+  @patch
+  static _exists(_Namespace namespace, Uint8List rawPath) {
+    throw UnsupportedError("File._exists");
+  }
+
+  @patch
+  static _create(_Namespace namespace, Uint8List rawPath) {
+    throw UnsupportedError("File._create");
+  }
+
+  @patch
+  static _createLink(_Namespace namespace, Uint8List rawPath, String target) {
+    throw UnsupportedError("File._createLink");
+  }
+
+  @patch
+  static _linkTarget(_Namespace namespace, Uint8List rawPath) {
+    throw UnsupportedError("File._linkTarget");
+  }
+
+  @patch
+  static _deleteNative(_Namespace namespace, Uint8List rawPath) {
+    throw UnsupportedError("File._deleteNative");
+  }
+
+  @patch
+  static _deleteLinkNative(_Namespace namespace, Uint8List rawPath) {
+    throw UnsupportedError("File._deleteLinkNative");
+  }
+
+  @patch
+  static _rename(_Namespace namespace, Uint8List oldPath, String newPath) {
+    throw UnsupportedError("File._rename");
+  }
+
+  @patch
+  static _renameLink(_Namespace namespace, Uint8List oldPath, String newPath) {
+    throw UnsupportedError("File._renameLink");
+  }
+
+  @patch
+  static _copy(_Namespace namespace, Uint8List oldPath, String newPath) {
+    throw UnsupportedError("File._copy");
+  }
+
+  @patch
+  static _lengthFromPath(_Namespace namespace, Uint8List rawPath) {
+    throw UnsupportedError("File._lengthFromPath");
+  }
+
+  @patch
+  static _lastModified(_Namespace namespace, Uint8List rawPath) {
+    throw UnsupportedError("File._lastModified");
+  }
+
+  @patch
+  static _lastAccessed(_Namespace namespace, Uint8List rawPath) {
+    throw UnsupportedError("File._lastAccessed");
+  }
+
+  @patch
+  static _setLastModified(_Namespace namespace, Uint8List rawPath, int millis) {
+    throw UnsupportedError("File._setLastModified");
+  }
+
+  @patch
+  static _setLastAccessed(_Namespace namespace, Uint8List rawPath, int millis) {
+    throw UnsupportedError("File._setLastAccessed");
+  }
+
+  @patch
+  static _open(_Namespace namespace, Uint8List rawPath, int mode) {
+    throw UnsupportedError("File._open");
+  }
+
+  @patch
+  static int _openStdio(int fd) {
+    throw UnsupportedError("File._openStdio");
+  }
+}
+
+@patch
+class _Namespace {
+  @patch
+  static void _setupNamespace(var namespace) {
+    throw UnsupportedError("_Namespace");
+  }
+
+  @patch
+  static _Namespace get _namespace {
+    throw UnsupportedError("_Namespace");
+  }
+
+  @patch
+  static int get _namespacePointer {
+    throw UnsupportedError("_Namespace");
+  }
+}
+
+@patch
+class _RandomAccessFileOps {
+  @patch
+  factory _RandomAccessFileOps(int pointer) {
+    throw UnsupportedError("RandomAccessFile");
+  }
+}
+
+@patch
+class _IOCrypto {
+  @patch
+  static Uint8List getRandomBytes(int count) {
+    throw UnsupportedError("_IOCrypto.getRandomBytes");
+  }
+}
+
+@patch
+class _Platform {
+  @patch
+  static int _numberOfProcessors() {
+    throw UnsupportedError("Platform._numberOfProcessors");
+  }
+
+  @patch
+  static String _pathSeparator() {
+    throw UnsupportedError("Platform._pathSeparator");
+  }
+
+  @patch
+  static String _operatingSystem() {
+    throw UnsupportedError("Platform._operatingSystem");
+  }
+
+  @patch
+  static _operatingSystemVersion() {
+    throw UnsupportedError("Platform._operatingSystemVersion");
+  }
+
+  @patch
+  static _localHostname() {
+    throw UnsupportedError("Platform._localHostname");
+  }
+
+  @patch
+  static _executable() {
+    throw UnsupportedError("Platform._executable");
+  }
+
+  @patch
+  static _resolvedExecutable() {
+    throw UnsupportedError("Platform._resolvedExecutable");
+  }
+
+  @patch
+  static List<String> _executableArguments() {
+    throw UnsupportedError("Platform._executableArguments");
+  }
+
+  @patch
+  static String _packageRoot() {
+    throw UnsupportedError("Platform._packageRoot");
+  }
+
+  @patch
+  static String _packageConfig() {
+    throw UnsupportedError("Platform._packageConfig");
+  }
+
+  @patch
+  static _environment() {
+    throw UnsupportedError("Platform._environment");
+  }
+
+  @patch
+  static String _version() {
+    throw UnsupportedError("Platform._version");
+  }
+
+  @patch
+  static String _localeName() {
+    throw UnsupportedError("Platform._localeName");
+  }
+
+  @patch
+  static Uri _script() {
+    throw UnsupportedError("Platform._script");
+  }
+}
+
+@patch
+class _ProcessUtils {
+  @patch
+  static void _exit(int status) {
+    throw UnsupportedError("ProcessUtils._exit");
+  }
+
+  @patch
+  static void _setExitCode(int status) {
+    throw UnsupportedError("ProcessUtils._setExitCode");
+  }
+
+  @patch
+  static int _getExitCode() {
+    throw UnsupportedError("ProcessUtils._getExitCode");
+  }
+
+  @patch
+  static void _sleep(int millis) {
+    throw UnsupportedError("ProcessUtils._sleep");
+  }
+
+  @patch
+  static int _pid(Process process) {
+    throw UnsupportedError("ProcessUtils._pid");
+  }
+
+  @patch
+  static Stream<ProcessSignal> _watchSignal(ProcessSignal signal) {
+    throw UnsupportedError("ProcessUtils._watchSignal");
+  }
+}
+
+@patch
+class ProcessInfo {
+  @patch
+  static int get currentRss {
+    throw UnsupportedError("ProcessInfo.currentRss");
+  }
+
+  @patch
+  static int get maxRss {
+    throw UnsupportedError("ProcessInfo.maxRss");
+  }
+}
+
+@patch
+class Process {
+  @patch
+  static Future<Process> start(String executable, List<String> arguments,
+      {String workingDirectory,
+      Map<String, String> environment,
+      bool includeParentEnvironment = true,
+      bool runInShell = false,
+      ProcessStartMode mode = ProcessStartMode.normal}) {
+    throw UnsupportedError("Process.start");
+  }
+
+  @patch
+  static Future<ProcessResult> run(String executable, List<String> arguments,
+      {String workingDirectory,
+      Map<String, String> environment,
+      bool includeParentEnvironment = true,
+      bool runInShell = false,
+      Encoding stdoutEncoding = systemEncoding,
+      Encoding stderrEncoding = systemEncoding}) {
+    throw UnsupportedError("Process.run");
+  }
+
+  @patch
+  static ProcessResult runSync(String executable, List<String> arguments,
+      {String workingDirectory,
+      Map<String, String> environment,
+      bool includeParentEnvironment = true,
+      bool runInShell = false,
+      Encoding stdoutEncoding = systemEncoding,
+      Encoding stderrEncoding = systemEncoding}) {
+    throw UnsupportedError("Process.runSync");
+  }
+
+  @patch
+  static bool killPid(int pid, [ProcessSignal signal = ProcessSignal.sigterm]) {
+    throw UnsupportedError("Process.killPid");
+  }
+}
+
+@patch
+class InternetAddress {
+  @patch
+  static InternetAddress get LOOPBACK_IP_V4 {
+    throw UnsupportedError("InternetAddress.LOOPBACK_IP_V4");
+  }
+
+  @patch
+  static InternetAddress get LOOPBACK_IP_V6 {
+    throw UnsupportedError("InternetAddress.LOOPBACK_IP_V6");
+  }
+
+  @patch
+  static InternetAddress get ANY_IP_V4 {
+    throw UnsupportedError("InternetAddress.ANY_IP_V4");
+  }
+
+  @patch
+  static InternetAddress get ANY_IP_V6 {
+    throw UnsupportedError("InternetAddress.ANY_IP_V6");
+  }
+
+  @patch
+  factory InternetAddress(String address) {
+    throw UnsupportedError("InternetAddress");
+  }
+  @patch
+  static Future<List<InternetAddress>> lookup(String host,
+      {InternetAddressType type = InternetAddressType.any}) {
+    throw UnsupportedError("InternetAddress.lookup");
+  }
+
+  @patch
+  static InternetAddress _cloneWithNewHost(
+      InternetAddress address, String host) {
+    throw UnsupportedError("InternetAddress._cloneWithNewHost");
+  }
+}
+
+@patch
+class NetworkInterface {
+  @patch
+  static bool get listSupported {
+    throw UnsupportedError("NetworkInterface.listSupported");
+  }
+
+  @patch
+  static Future<List<NetworkInterface>> list(
+      {bool includeLoopback = false,
+      bool includeLinkLocal = false,
+      InternetAddressType type = InternetAddressType.any}) {
+    throw UnsupportedError("NetworkInterface.list");
+  }
+}
+
+@patch
+class RawServerSocket {
+  @patch
+  static Future<RawServerSocket> bind(address, int port,
+      {int backlog = 0, bool v6Only = false, bool shared = false}) {
+    throw UnsupportedError("RawServerSocket.bind");
+  }
+}
+
+@patch
+class ServerSocket {
+  @patch
+  static Future<ServerSocket> bind(address, int port,
+      {int backlog = 0, bool v6Only = false, bool shared = false}) {
+    throw UnsupportedError("ServerSocket.bind");
+  }
+}
+
+@patch
+class RawSocket {
+  @patch
+  static Future<RawSocket> connect(host, int port,
+      {sourceAddress, Duration timeout}) {
+    throw UnsupportedError("RawSocket constructor");
+  }
+
+  @patch
+  static Future<ConnectionTask<RawSocket>> startConnect(host, int port,
+      {sourceAddress}) {
+    throw UnsupportedError("RawSocket constructor");
+  }
+}
+
+@patch
+class Socket {
+  @patch
+  static Future<Socket> _connect(host, int port,
+      {sourceAddress, Duration timeout}) {
+    throw UnsupportedError("Socket constructor");
+  }
+
+  @patch
+  static Future<ConnectionTask<Socket>> _startConnect(host, int port,
+      {sourceAddress}) {
+    throw UnsupportedError("Socket constructor");
+  }
+}
+
+@patch
+class SecureSocket {
+  @patch
+  factory SecureSocket._(RawSecureSocket rawSocket) {
+    throw UnsupportedError("SecureSocket constructor");
+  }
+}
+
+@patch
+class RawSynchronousSocket {
+  @patch
+  static RawSynchronousSocket connectSync(host, int port) {
+    throw UnsupportedError("RawSynchronousSocket.connectSync");
+  }
+}
+
+@patch
+class RawSocketOption {
+  @patch
+  static int _getOptionValue(int key) {
+    throw UnsupportedError("RawSocketOption._getOptionValue");
+  }
+}
+
+@patch
+class SecurityContext {
+  @patch
+  factory SecurityContext({bool withTrustedRoots = false}) {
+    throw UnsupportedError("SecurityContext constructor");
+  }
+
+  @patch
+  static SecurityContext get defaultContext {
+    throw UnsupportedError("default SecurityContext getter");
+  }
+
+  @patch
+  static bool get alpnSupported {
+    throw UnsupportedError("SecurityContext alpnSupported getter");
+  }
+}
+
+@patch
+class X509Certificate {
+  @patch
+  factory X509Certificate._() {
+    throw UnsupportedError("X509Certificate constructor");
+  }
+}
+
+@patch
+class RawDatagramSocket {
+  @patch
+  static Future<RawDatagramSocket> bind(host, int port,
+      {bool reuseAddress = true, bool reusePort = false, int ttl = 1}) {
+    throw UnsupportedError("RawDatagramSocket.bind");
+  }
+}
+
+@patch
+class _SecureFilter {
+  @patch
+  factory _SecureFilter._() {
+    throw UnsupportedError("_SecureFilter._SecureFilter");
+  }
+}
+
+@patch
+class _StdIOUtils {
+  @patch
+  static Stdin _getStdioInputStream(int fd) {
+    throw UnsupportedError("StdIOUtils._getStdioInputStream");
+  }
+
+  @patch
+  static _getStdioOutputStream(int fd) {
+    throw UnsupportedError("StdIOUtils._getStdioOutputStream");
+  }
+
+  @patch
+  static int _socketType(Socket socket) {
+    throw UnsupportedError("StdIOUtils._socketType");
+  }
+
+  @patch
+  static _getStdioHandleType(int fd) {
+    throw UnsupportedError("StdIOUtils._getStdioHandleType");
+  }
+}
+
+@patch
+class _WindowsCodePageDecoder {
+  @patch
+  static String _decodeBytes(List<int> bytes) {
+    throw UnsupportedError("_WindowsCodePageDecoder._decodeBytes");
+  }
+}
+
+@patch
+class _WindowsCodePageEncoder {
+  @patch
+  static List<int> _encodeString(String string) {
+    throw UnsupportedError("_WindowsCodePageEncoder._encodeString");
+  }
+}
+
+@patch
+class RawZLibFilter {
+  @patch
+  static RawZLibFilter _makeZLibDeflateFilter(
+      bool gzip,
+      int level,
+      int windowBits,
+      int memLevel,
+      int strategy,
+      List<int> dictionary,
+      bool raw) {
+    throw UnsupportedError("_newZLibDeflateFilter");
+  }
+
+  @patch
+  static RawZLibFilter _makeZLibInflateFilter(
+      int windowBits, List<int> dictionary, bool raw) {
+    throw UnsupportedError("_newZLibInflateFilter");
+  }
+}
+
+@patch
+class Stdin {
+  @patch
+  int readByteSync() {
+    throw UnsupportedError("Stdin.readByteSync");
+  }
+
+  @patch
+  bool get echoMode {
+    throw UnsupportedError("Stdin.echoMode");
+  }
+
+  @patch
+  void set echoMode(bool enabled) {
+    throw UnsupportedError("Stdin.echoMode");
+  }
+
+  @patch
+  bool get lineMode {
+    throw UnsupportedError("Stdin.lineMode");
+  }
+
+  @patch
+  void set lineMode(bool enabled) {
+    throw UnsupportedError("Stdin.lineMode");
+  }
+
+  @patch
+  bool get supportsAnsiEscapes {
+    throw UnsupportedError("Stdin.supportsAnsiEscapes");
+  }
+}
+
+@patch
+class Stdout {
+  @patch
+  bool _hasTerminal(int fd) {
+    throw UnsupportedError("Stdout.hasTerminal");
+  }
+
+  @patch
+  int _terminalColumns(int fd) {
+    throw UnsupportedError("Stdout.terminalColumns");
+  }
+
+  @patch
+  int _terminalLines(int fd) {
+    throw UnsupportedError("Stdout.terminalLines");
+  }
+
+  @patch
+  static bool _supportsAnsiEscapes(int fd) {
+    throw UnsupportedError("Stdout.supportsAnsiEscapes");
+  }
+}
+
+@patch
+class _FileSystemWatcher {
+  @patch
+  static Stream<FileSystemEvent> _watch(
+      String path, int events, bool recursive) {
+    throw UnsupportedError("_FileSystemWatcher.watch");
+  }
+
+  @patch
+  static bool get isSupported {
+    throw UnsupportedError("_FileSystemWatcher.isSupported");
+  }
+}
+
+@patch
+class _IOService {
+  @patch
+  static Future _dispatch(int request, List data) {
+    throw UnsupportedError("_IOService._dispatch");
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/isolate_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/isolate_patch.dart
new file mode 100644
index 0000000..f6aa73bb
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/isolate_patch.dart
@@ -0,0 +1,125 @@
+// Copyright (c) 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.
+
+// Patch file for the dart:isolate library.
+
+import 'dart:_js_helper' show patch, NoReifyGeneric;
+import 'dart:async';
+import "dart:typed_data" show TypedData;
+
+@patch
+class Isolate {
+  // `current` must be a getter, not just a final field,
+  // to match the external declaration.
+  @patch
+  static Isolate get current => _unsupported();
+
+  @patch
+  String get debugName => _unsupported();
+
+  @patch
+  static Future<Uri> get packageRoot => _unsupported();
+
+  @patch
+  static Future<Uri> get packageConfig => _unsupported();
+
+  @patch
+  static Future<Uri> resolvePackageUri(Uri packageUri) => _unsupported();
+
+  @patch
+  static Future<Isolate> spawn<T>(void entryPoint(T message), T message,
+          {bool paused = false,
+          bool errorsAreFatal,
+          SendPort onExit,
+          SendPort onError}) =>
+      _unsupported();
+
+  @patch
+  static Future<Isolate> spawnUri(Uri uri, List<String> args, var message,
+          {bool paused = false,
+          SendPort onExit,
+          SendPort onError,
+          bool errorsAreFatal,
+          bool checked,
+          Map<String, String> environment,
+          Uri packageRoot,
+          Uri packageConfig,
+          bool automaticPackageResolution = false}) =>
+      _unsupported();
+
+  @patch
+  void _pause(Capability resumeCapability) => _unsupported();
+
+  @patch
+  void resume(Capability resumeCapability) => _unsupported();
+
+  @patch
+  void addOnExitListener(SendPort responsePort, {Object response}) =>
+      _unsupported();
+
+  @patch
+  void removeOnExitListener(SendPort responsePort) => _unsupported();
+
+  @patch
+  void setErrorsFatal(bool errorsAreFatal) => _unsupported();
+
+  @patch
+  void kill({int priority = beforeNextEvent}) => _unsupported();
+  @patch
+  void ping(SendPort responsePort,
+          {Object response, int priority = immediate}) =>
+      _unsupported();
+
+  @patch
+  void addErrorListener(SendPort port) => _unsupported();
+
+  @patch
+  void removeErrorListener(SendPort port) => _unsupported();
+}
+
+/** Default factory for receive ports. */
+@patch
+class ReceivePort {
+  @patch
+  factory ReceivePort() = _ReceivePort;
+
+  @patch
+  factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) =>
+      _unsupported();
+}
+
+/// ReceivePort is supported by dev_compiler because async test packages
+/// (async_helper, unittest) create a dummy receive port to keep the Dart VM
+/// alive.
+class _ReceivePort extends Stream implements ReceivePort {
+  close() {}
+
+  get sendPort => _unsupported();
+
+  listen(onData, {onError, onDone, cancelOnError}) => _unsupported();
+}
+
+@patch
+class RawReceivePort {
+  @patch
+  factory RawReceivePort([void handler(event)]) => _unsupported();
+}
+
+@patch
+class Capability {
+  @patch
+  factory Capability() => _unsupported();
+}
+
+@patch
+abstract class TransferableTypedData {
+  @patch
+  factory TransferableTypedData.fromList(List<TypedData> list) =>
+      _unsupported();
+}
+
+@NoReifyGeneric()
+T _unsupported<T>() {
+  throw UnsupportedError('dart:isolate is not supported on dart4web');
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/math_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/math_patch.dart
new file mode 100644
index 0000000..2ba4220
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/math_patch.dart
@@ -0,0 +1,348 @@
+// Copyright (c) 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.
+
+// Patch file for dart:math library.
+import 'dart:_foreign_helper' show JS;
+import 'dart:_js_helper' show patch, nullCheck, notNull;
+import 'dart:typed_data' show ByteData;
+
+@patch
+@notNull
+T min<T extends num>(@nullCheck T a, @nullCheck T b) =>
+    JS('-dynamic', r'Math.min(#, #)', a, b);
+
+@patch
+@notNull
+T max<T extends num>(@nullCheck T a, @nullCheck T b) =>
+    JS('-dynamic', r'Math.max(#, #)', a, b);
+
+@patch
+@notNull
+double sqrt(@nullCheck num x) => JS<num>('!', r'Math.sqrt(#)', x);
+
+@patch
+@notNull
+double sin(@nullCheck num radians) => JS<num>('!', r'Math.sin(#)', radians);
+
+@patch
+@notNull
+double cos(@nullCheck num radians) => JS<num>('!', r'Math.cos(#)', radians);
+
+@patch
+@notNull
+double tan(@nullCheck num radians) => JS<num>('!', r'Math.tan(#)', radians);
+
+@patch
+@notNull
+double acos(@nullCheck num x) => JS<num>('!', r'Math.acos(#)', x);
+
+@patch
+@notNull
+double asin(@nullCheck num x) => JS<num>('!', r'Math.asin(#)', x);
+
+@patch
+@notNull
+double atan(@nullCheck num x) => JS<num>('!', r'Math.atan(#)', x);
+
+@patch
+@notNull
+double atan2(@nullCheck num a, @nullCheck num b) =>
+    JS<num>('!', r'Math.atan2(#, #)', a, b);
+
+@patch
+@notNull
+double exp(@nullCheck num x) => JS<num>('!', r'Math.exp(#)', x);
+
+@patch
+@notNull
+double log(@nullCheck num x) => JS<num>('!', r'Math.log(#)', x);
+
+@patch
+@notNull
+num pow(@nullCheck num x, @nullCheck num exponent) =>
+    JS<num>('!', r'Math.pow(#, #)', x, exponent);
+
+const int _POW2_32 = 0x100000000;
+
+@patch
+class Random {
+  static Random _secureRandom;
+
+  @patch
+  factory Random([int seed]) =>
+      (seed == null) ? const _JSRandom() : _Random(seed);
+
+  @patch
+  factory Random.secure() => _secureRandom ??= _JSSecureRandom();
+}
+
+class _JSRandom implements Random {
+  // The Dart2JS implementation of Random doesn't use a seed.
+  const _JSRandom();
+
+  @notNull
+  int nextInt(int max) {
+    if (max <= 0 || max > _POW2_32) {
+      throw RangeError("max must be in range 0 < max ≤ 2^32, was $max");
+    }
+    return JS("int", "(Math.random() * #) >>> 0", max);
+  }
+
+  /**
+   * Generates a positive random floating point value uniformly distributed on
+   * the range from 0.0, inclusive, to 1.0, exclusive.
+   */
+  @notNull
+  double nextDouble() => JS("double", "Math.random()");
+
+  /**
+   * Generates a random boolean value.
+   */
+  @notNull
+  bool nextBool() => JS("bool", "Math.random() < 0.5");
+}
+
+class _Random implements Random {
+  // Constants used by the algorithm or masking.
+  static const double _POW2_53_D = 1.0 * (0x20000000000000);
+  static const double _POW2_27_D = 1.0 * (1 << 27);
+  static const int _MASK32 = 0xFFFFFFFF;
+
+  // State comprised of two unsigned 32 bit integers.
+  @notNull
+  int _lo = 0;
+  @notNull
+  int _hi = 0;
+
+  // Implements:
+  //   uint64_t hash = 0;
+  //   do {
+  //      hash = hash * 1037 ^ mix64((uint64_t)seed);
+  //      seed >>= 64;
+  //   } while (seed != 0 && seed != -1);  // Limits for pos/neg seed.
+  //   if (hash == 0) {
+  //     hash = 0x5A17;
+  //   }
+  //   _lo = hash & _MASK_32;
+  //   _hi = hash >> 32;
+  // and then does four _nextState calls to shuffle bits around.
+  _Random(int seed) {
+    int empty_seed = 0;
+    if (seed < 0) {
+      empty_seed = -1;
+    }
+    do {
+      int low = seed & _MASK32;
+      seed = (seed - low) ~/ _POW2_32;
+      int high = seed & _MASK32;
+      seed = (seed - high) ~/ _POW2_32;
+
+      // Thomas Wang's 64-bit mix function.
+      // http://www.concentric.net/~Ttwang/tech/inthash.htm
+      // via. http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm
+
+      // key = ~key + (key << 21);
+      int tmplow = low << 21;
+      int tmphigh = (high << 21) | (low >> 11);
+      tmplow = (~low & _MASK32) + tmplow;
+      low = tmplow & _MASK32;
+      high = (~high + tmphigh + ((tmplow - low) ~/ 0x100000000)) & _MASK32;
+      // key = key ^ (key >> 24).
+      tmphigh = high >> 24;
+      tmplow = (low >> 24) | (high << 8);
+      low ^= tmplow;
+      high ^= tmphigh;
+      // key = key * 265
+      tmplow = low * 265;
+      low = tmplow & _MASK32;
+      high = (high * 265 + (tmplow - low) ~/ 0x100000000) & _MASK32;
+      // key = key ^ (key >> 14);
+      tmphigh = high >> 14;
+      tmplow = (low >> 14) | (high << 18);
+      low ^= tmplow;
+      high ^= tmphigh;
+      // key = key * 21
+      tmplow = low * 21;
+      low = tmplow & _MASK32;
+      high = (high * 21 + (tmplow - low) ~/ 0x100000000) & _MASK32;
+      // key = key ^ (key >> 28).
+      tmphigh = high >> 28;
+      tmplow = (low >> 28) | (high << 4);
+      low ^= tmplow;
+      high ^= tmphigh;
+      // key = key + (key << 31);
+      tmplow = low << 31;
+      tmphigh = (high << 31) | (low >> 1);
+      tmplow += low;
+      low = tmplow & _MASK32;
+      high = (high + tmphigh + (tmplow - low) ~/ 0x100000000) & _MASK32;
+      // Mix end.
+
+      // seed = seed * 1037 ^ key;
+      tmplow = _lo * 1037;
+      _lo = tmplow & _MASK32;
+      _hi = (_hi * 1037 + (tmplow - _lo) ~/ 0x100000000) & _MASK32;
+      _lo ^= low;
+      _hi ^= high;
+    } while (seed != empty_seed);
+
+    if (_hi == 0 && _lo == 0) {
+      _lo = 0x5A17;
+    }
+    _nextState();
+    _nextState();
+    _nextState();
+    _nextState();
+  }
+
+  // The algorithm used here is Multiply with Carry (MWC) with a Base b = 2^32.
+  // http://en.wikipedia.org/wiki/Multiply-with-carry
+  // The constant A (0xFFFFDA61) is selected from "Numerical Recipes 3rd
+  // Edition" p.348 B1.
+
+  // Implements:
+  //   var state = (A * _lo + _hi) & _MASK_64;
+  //   _lo = state & _MASK_32;
+  //   _hi = state >> 32;
+  void _nextState() {
+    // Simulate (0xFFFFDA61 * lo + hi) without overflowing 53 bits.
+    int tmpHi = 0xFFFF0000 * _lo; // At most 48 bits of significant result.
+    int tmpHiLo = tmpHi & _MASK32; // Get the lower 32 bits.
+    int tmpHiHi = tmpHi - tmpHiLo; // And just the upper 32 bits.
+    int tmpLo = 0xDA61 * _lo;
+    int tmpLoLo = tmpLo & _MASK32;
+    int tmpLoHi = tmpLo - tmpLoLo;
+
+    int newLo = tmpLoLo + tmpHiLo + _hi;
+    _lo = newLo & _MASK32;
+    int newLoHi = newLo - _lo;
+    _hi = ((tmpLoHi + tmpHiHi + newLoHi) ~/ _POW2_32) & _MASK32;
+    assert(_lo < _POW2_32);
+    assert(_hi < _POW2_32);
+  }
+
+  @notNull
+  int nextInt(@nullCheck int max) {
+    if (max <= 0 || max > _POW2_32) {
+      throw RangeError("max must be in range 0 < max ≤ 2^32, was $max");
+    }
+    if ((max & (max - 1)) == 0) {
+      // Fast case for powers of two.
+      _nextState();
+      return _lo & (max - 1);
+    }
+
+    int rnd32;
+    int result;
+    do {
+      _nextState();
+      rnd32 = _lo;
+      result = rnd32.remainder(max); // % max;
+    } while ((rnd32 - result + max) >= _POW2_32);
+    return result;
+  }
+
+  @notNull
+  double nextDouble() {
+    _nextState();
+    int bits26 = _lo & ((1 << 26) - 1);
+    _nextState();
+    int bits27 = _lo & ((1 << 27) - 1);
+    return (bits26 * _POW2_27_D + bits27) / _POW2_53_D;
+  }
+
+  @notNull
+  bool nextBool() {
+    _nextState();
+    return (_lo & 1) == 0;
+  }
+}
+
+class _JSSecureRandom implements Random {
+  // Reused buffer with room enough for a double.
+  final _buffer = ByteData(8);
+
+  _JSSecureRandom() {
+    var crypto = JS("", "self.crypto");
+    if (crypto != null) {
+      var getRandomValues = JS("", "#.getRandomValues", crypto);
+      if (getRandomValues != null) {
+        return;
+      }
+    }
+    throw UnsupportedError(
+        "No source of cryptographically secure random numbers available.");
+  }
+
+  /// Fill _buffer from [start] to `start + length` with random bytes.
+  void _getRandomBytes(int start, int length) {
+    JS("void", "crypto.getRandomValues(#)",
+        _buffer.buffer.asUint8List(start, length));
+  }
+
+  @notNull
+  bool nextBool() {
+    _getRandomBytes(0, 1);
+    return _buffer.getUint8(0).isOdd;
+  }
+
+  @notNull
+  double nextDouble() {
+    _getRandomBytes(1, 7);
+    // Set top bits 12 of double to 0x3FF which is the exponent for numbers
+    // between 1.0 and 2.0.
+    _buffer.setUint8(0, 0x3F);
+    int highByte = _buffer.getUint8(1);
+    _buffer.setUint8(1, highByte | 0xF0);
+
+    // Buffer now contains double in the range [1.0-2.0)
+    // with 52 bits of entropy (not 53).
+    // To get 53 bits, we extract the 53rd bit from higthByte before
+    // overwriting it, and add that as a least significant bit.
+    // The getFloat64 method is big-endian as default.
+    double result = _buffer.getFloat64(0) - 1.0;
+    if (highByte & 0x10 != 0) {
+      result += 1.1102230246251565e-16; // pow(2,-53).
+    }
+    return result;
+  }
+
+  @notNull
+  int nextInt(@nullCheck int max) {
+    if (max <= 0 || max > _POW2_32) {
+      throw RangeError("max must be in range 0 < max ≤ 2^32, was $max");
+    }
+    int byteCount = 1;
+    if (max > 0xFF) {
+      byteCount++;
+      if (max > 0xFFFF) {
+        byteCount++;
+        if (max > 0xFFFFFF) {
+          byteCount++;
+        }
+      }
+    }
+    _buffer.setUint32(0, 0);
+    int start = 4 - byteCount;
+    int randomLimit = pow(256, byteCount);
+    while (true) {
+      _getRandomBytes(start, byteCount);
+      // The getUint32 method is big-endian as default.
+      int random = _buffer.getUint32(0);
+      if (max & (max - 1) == 0) {
+        // Max is power of 2.
+        return random & (max - 1);
+      }
+      int result = random.remainder(max);
+      // Ensure results have equal probability by rejecting values in the
+      // last range of k*max .. 256**byteCount.
+      // TODO: Consider picking a higher byte count if the last range is a
+      // significant portion of the entire range - a 50% chance of having
+      // to use two more bytes is no worse than always using one more.
+      if (random - result + max < randomLimit) {
+        return result;
+      }
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/mirrors_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/mirrors_patch.dart
new file mode 100644
index 0000000..e3b015b
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/mirrors_patch.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 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.
+
+// Patch library for dart:mirrors.
+
+import 'dart:_js_helper' show patch;
+import 'dart:_js_mirrors' as js;
+import 'dart:_runtime' as dart;
+
+@patch
+class MirrorSystem {
+  @patch
+  LibraryMirror findLibrary(Symbol libraryName) {
+    return libraries.values
+        .singleWhere((library) => library.simpleName == libraryName);
+  }
+
+  @patch
+  static String getName(Symbol symbol) => js.getName(symbol);
+
+  @patch
+  static Symbol getSymbol(String name, [LibraryMirror library]) {
+    return js.getSymbol(name, library);
+  }
+}
+
+@patch
+MirrorSystem currentMirrorSystem() => js.currentJsMirrorSystem;
+
+@patch
+InstanceMirror reflect(Object reflectee) => js.reflect(reflectee);
+
+@patch
+ClassMirror reflectClass(Type key) {
+  if (key is! Type || key == dynamic) {
+    throw ArgumentError('$key does not denote a class');
+  }
+  TypeMirror tm = reflectType(key);
+  if (tm is! ClassMirror) {
+    throw ArgumentError("$key does not denote a class");
+  }
+  return (tm as ClassMirror).originalDeclaration;
+}
+
+@patch
+TypeMirror reflectType(Type type, [List<Type> typeArguments]) {
+  if (typeArguments != null) {
+    type = _instantiateClass(type, typeArguments);
+  }
+  return js.reflectType(type);
+}
+
+/// Instantiates the generic class [type] with [typeArguments] and returns the
+/// result.
+///
+/// [type] may be instantiated with type arguments already. In that case, they
+/// are ignored. For example calling this function with `(List<int>, [String])`
+/// and `(List<dynamic>, [String])` will produce `List<String>` in both cases.
+Type _instantiateClass(Type type, List<Type> typeArguments) {
+  var unwrapped = dart.unwrapType(type);
+  var genericClass = dart.getGenericClass(unwrapped);
+  if (genericClass == null) {
+    throw ArgumentError('Type `$type` must be generic to apply '
+        'type arguments: `$typeArguments`.');
+  }
+
+  var typeArgsLenth = typeArguments.length;
+  var unwrappedArgs = List(typeArgsLenth);
+  for (int i = 0; i < typeArgsLenth; i++) {
+    unwrappedArgs[i] = dart.unwrapType(typeArguments[i]);
+  }
+  var typeFormals = dart.getGenericTypeFormals(genericClass);
+  if (typeFormals.length != typeArgsLenth) {
+    throw ArgumentError('Type `$type` has ${typeFormals.length} type '
+        'parameters, but $typeArgsLenth type arguments were '
+        'passed: `$typeArguments`.');
+  }
+  // TODO(jmesserly): this does not validate bounds, as we don't have them
+  // available at runtime. Consider storing them when dart:mirrors is enabled.
+  return dart.wrapType(dart.instantiateClass(genericClass, unwrappedArgs));
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart
new file mode 100644
index 0000000..f1e2dc1
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart
@@ -0,0 +1,191 @@
+// 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:collection';
+import 'dart:_js_helper' show patch;
+import 'dart:_native_typed_data';
+
+@patch
+class ByteData {
+  @patch
+  factory ByteData(int length) = NativeByteData;
+}
+
+@patch
+class Float32List {
+  @patch
+  factory Float32List(int length) = NativeFloat32List;
+
+  @patch
+  factory Float32List.fromList(List<double> elements) =
+      NativeFloat32List.fromList;
+}
+
+@patch
+class Float64List {
+  @patch
+  factory Float64List(int length) = NativeFloat64List;
+
+  @patch
+  factory Float64List.fromList(List<double> elements) =
+      NativeFloat64List.fromList;
+}
+
+@patch
+class Int16List {
+  @patch
+  factory Int16List(int length) = NativeInt16List;
+
+  @patch
+  factory Int16List.fromList(List<int> elements) = NativeInt16List.fromList;
+}
+
+@patch
+class Int32List {
+  @patch
+  factory Int32List(int length) = NativeInt32List;
+
+  @patch
+  factory Int32List.fromList(List<int> elements) = NativeInt32List.fromList;
+}
+
+@patch
+class Int8List {
+  @patch
+  factory Int8List(int length) = NativeInt8List;
+
+  @patch
+  factory Int8List.fromList(List<int> elements) = NativeInt8List.fromList;
+}
+
+@patch
+class Uint32List {
+  @patch
+  factory Uint32List(int length) = NativeUint32List;
+
+  @patch
+  factory Uint32List.fromList(List<int> elements) = NativeUint32List.fromList;
+}
+
+@patch
+class Uint16List {
+  @patch
+  factory Uint16List(int length) = NativeUint16List;
+
+  @patch
+  factory Uint16List.fromList(List<int> elements) = NativeUint16List.fromList;
+}
+
+@patch
+class Uint8ClampedList {
+  @patch
+  factory Uint8ClampedList(int length) = NativeUint8ClampedList;
+
+  @patch
+  factory Uint8ClampedList.fromList(List<int> elements) =
+      NativeUint8ClampedList.fromList;
+}
+
+@patch
+class Uint8List {
+  @patch
+  factory Uint8List(int length) = NativeUint8List;
+
+  @patch
+  factory Uint8List.fromList(List<int> elements) = NativeUint8List.fromList;
+}
+
+@patch
+class Int64List {
+  @patch
+  factory Int64List(int length) {
+    throw UnsupportedError("Int64List not supported by dart2js.");
+  }
+
+  @patch
+  factory Int64List.fromList(List<int> elements) {
+    throw UnsupportedError("Int64List not supported by dart2js.");
+  }
+}
+
+@patch
+class Uint64List {
+  @patch
+  factory Uint64List(int length) {
+    throw UnsupportedError("Uint64List not supported by dart2js.");
+  }
+
+  @patch
+  factory Uint64List.fromList(List<int> elements) {
+    throw UnsupportedError("Uint64List not supported by dart2js.");
+  }
+}
+
+@patch
+class Int32x4List {
+  @patch
+  factory Int32x4List(int length) = NativeInt32x4List;
+
+  @patch
+  factory Int32x4List.fromList(List<Int32x4> elements) =
+      NativeInt32x4List.fromList;
+}
+
+@patch
+class Float32x4List {
+  @patch
+  factory Float32x4List(int length) = NativeFloat32x4List;
+
+  @patch
+  factory Float32x4List.fromList(List<Float32x4> elements) =
+      NativeFloat32x4List.fromList;
+}
+
+@patch
+class Float64x2List {
+  @patch
+  factory Float64x2List(int length) = NativeFloat64x2List;
+
+  @patch
+  factory Float64x2List.fromList(List<Float64x2> elements) =
+      NativeFloat64x2List.fromList;
+}
+
+@patch
+class Float32x4 {
+  @patch
+  factory Float32x4(double x, double y, double z, double w) = NativeFloat32x4;
+  @patch
+  factory Float32x4.splat(double v) = NativeFloat32x4.splat;
+  @patch
+  factory Float32x4.zero() = NativeFloat32x4.zero;
+  @patch
+  factory Float32x4.fromInt32x4Bits(Int32x4 x) =
+      NativeFloat32x4.fromInt32x4Bits;
+  @patch
+  factory Float32x4.fromFloat64x2(Float64x2 v) = NativeFloat32x4.fromFloat64x2;
+}
+
+@patch
+class Int32x4 {
+  @patch
+  factory Int32x4(int x, int y, int z, int w) = NativeInt32x4;
+  @patch
+  factory Int32x4.bool(bool x, bool y, bool z, bool w) = NativeInt32x4.bool;
+  @patch
+  factory Int32x4.fromFloat32x4Bits(Float32x4 x) =
+      NativeInt32x4.fromFloat32x4Bits;
+}
+
+@patch
+class Float64x2 {
+  @patch
+  factory Float64x2(double x, double y) = NativeFloat64x2;
+  @patch
+  factory Float64x2.splat(double v) = NativeFloat64x2.splat;
+  @patch
+  factory Float64x2.zero() = NativeFloat64x2.zero;
+  @patch
+  factory Float64x2.fromFloat32x4(Float32x4 v) = NativeFloat64x2.fromFloat32x4;
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/annotations.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/annotations.dart
new file mode 100644
index 0000000..bc437da
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/annotations.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.
+
+part of dart._js_helper;
+
+/// Tells the optimizing compiler to always inline the annotated method.
+class ForceInline {
+  const ForceInline();
+}
+
+class _NotNull {
+  const _NotNull();
+}
+
+/// Marks a variable or API to be non-nullable.
+/// ****CAUTION******
+/// This is currently unchecked, and hence should never be used
+/// on any public interface where user code could subclass, implement,
+/// or otherwise cause the contract to be violated.
+/// TODO(leafp): Consider adding static checking and exposing
+/// this to user code.
+const notNull = _NotNull();
+
+/// Marks a generic function or static method API to be not reified.
+/// ****CAUTION******
+/// This is currently unchecked, and hence should be used very carefully for
+/// internal SDK APIs only.
+class NoReifyGeneric {
+  const NoReifyGeneric();
+}
+
+/// Enables/disables reification of functions within the body of this function.
+/// ****CAUTION******
+/// This is currently unchecked, and hence should be used very carefully for
+/// internal SDK APIs only.
+class ReifyFunctionTypes {
+  final bool value;
+  const ReifyFunctionTypes(this.value);
+}
+
+class _NullCheck {
+  const _NullCheck();
+}
+
+/// Annotation indicating the parameter should default to the JavaScript
+/// undefined constant.
+const undefined = _Undefined();
+
+class _Undefined {
+  const _Undefined();
+}
+
+/// Tells the development compiler to check a variable for null at its
+/// declaration point, and then to assume that the variable is non-null
+/// from that point forward.
+/// ****CAUTION******
+/// This is currently unchecked, and hence will not catch re-assignments
+/// of a variable with null
+const nullCheck = _NullCheck();
+
+/// Tells the optimizing compiler that the annotated method cannot throw.
+/// Requires @NoInline() to function correctly.
+class NoThrows {
+  const NoThrows();
+}
+
+/// Tells the optimizing compiler to not inline the annotated method.
+class NoInline {
+  const NoInline();
+}
+
+/// Marks a class as native and defines its JavaScript name(s).
+class Native {
+  final String name;
+  const Native(this.name);
+}
+
+class JsPeerInterface {
+  /// The JavaScript type that we should match the API of.
+  /// Used for classes where Dart subclasses should be callable from JavaScript
+  /// matching the JavaScript calling conventions.
+  final String name;
+  const JsPeerInterface({this.name});
+}
+
+/// A Dart interface may only be implemented by a native JavaScript object
+/// if it is marked with this annotation.
+class SupportJsExtensionMethods {
+  const SupportJsExtensionMethods();
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/custom_hash_map.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/custom_hash_map.dart
new file mode 100644
index 0000000..c7c920d
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/custom_hash_map.dart
@@ -0,0 +1,197 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart._js_helper;
+
+class CustomKeyHashMap<K, V> extends CustomHashMap<K, V> {
+  final _Predicate<Object> _validKey;
+  CustomKeyHashMap(_Equality<K> equals, _Hasher<K> hashCode, this._validKey)
+      : super(equals, hashCode);
+
+  @override
+  @notNull
+  bool containsKey(Object key) {
+    if (!_validKey(key)) return false;
+    return super.containsKey(key);
+  }
+
+  @override
+  V operator [](Object key) {
+    if (!_validKey(key)) return null;
+    return super[key];
+  }
+
+  @override
+  V remove(Object key) {
+    if (!_validKey(key)) return null;
+    return super.remove(key);
+  }
+}
+
+class CustomHashMap<K, V> extends InternalMap<K, V> {
+  /// The backing store for this map.
+  @notNull
+  final _map = JS('', 'new Map()');
+
+  /// Our map used to map keys onto the canonical key that is stored in [_map].
+  @notNull
+  final _keyMap = JS('', 'new Map()');
+
+  // We track the number of modifications done to the key set of the
+  // hash map to be able to throw when the map is modified while being
+  // iterated over.
+  //
+  // Value cycles after 2^30 modifications so that modification counts are
+  // always unboxed (Smi) values. Modification detection will be missed if you
+  // make exactly some multiple of 2^30 modifications between advances of an
+  // iterator.
+  @notNull
+  int _modifications = 0;
+
+  final _Equality<K> _equals;
+  final _Hasher<K> _hashCode;
+
+  CustomHashMap(this._equals, this._hashCode);
+
+  @notNull
+  int get length => JS<int>('!', '#.size', _map);
+
+  @notNull
+  bool get isEmpty => JS<bool>('!', '#.size == 0', _map);
+
+  @notNull
+  bool get isNotEmpty => JS<bool>('!', '#.size != 0', _map);
+
+  Iterable<K> get keys => _JSMapIterable<K>(this, true);
+  Iterable<V> get values => _JSMapIterable<V>(this, false);
+
+  @notNull
+  bool containsKey(Object key) {
+    if (key is K) {
+      var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key));
+      if (buckets != null) {
+        var equals = _equals;
+        for (int i = 0, n = JS<int>('!', '#.length', buckets); i < n; i++) {
+          K k = JS('', '#[#]', buckets, i);
+          if (equals(k, key)) return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  bool containsValue(Object value) {
+    for (var v in JS('', '#.values()', _map)) {
+      if (value == v) return true;
+    }
+    return false;
+  }
+
+  void addAll(Map<K, V> other) {
+    other.forEach((K key, V value) {
+      this[key] = value;
+    });
+  }
+
+  V operator [](Object key) {
+    if (key is K) {
+      var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key));
+      if (buckets != null) {
+        var equals = _equals;
+        for (int i = 0, n = JS<int>('!', '#.length', buckets); i < n; i++) {
+          K k = JS('', '#[#]', buckets, i);
+          if (equals(k, key)) {
+            V value = JS('', '#.get(#)', _map, k);
+            return value == null ? null : value; // coerce undefined to null.
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  void operator []=(K key, V value) {
+    var keyMap = _keyMap;
+    int hash = JS('!', '# & 0x3ffffff', _hashCode(key));
+    var buckets = JS('', '#.get(#)', keyMap, hash);
+    if (buckets == null) {
+      JS('', '#.set(#, [#])', keyMap, hash, key);
+    } else {
+      var equals = _equals;
+      for (int i = 0, n = JS<int>('!', '#.length', buckets);;) {
+        K k = JS('', '#[#]', buckets, i);
+        if (equals(k, key)) {
+          key = k;
+          break;
+        }
+        if (++i >= n) {
+          JS('', '#.push(#)', buckets, key);
+          break;
+        }
+      }
+    }
+    JS('', '#.set(#, #)', _map, key, value);
+    _modifications = (_modifications + 1) & 0x3ffffff;
+  }
+
+  V putIfAbsent(K key, V ifAbsent()) {
+    var keyMap = _keyMap;
+    int hash = JS('!', '# & 0x3ffffff', _hashCode(key));
+    var buckets = JS('', '#.get(#)', keyMap, hash);
+    if (buckets == null) {
+      JS('', '#.set(#, [#])', keyMap, hash, key);
+    } else {
+      var equals = _equals;
+      for (int i = 0, n = JS<int>('!', '#.length', buckets); i < n; i++) {
+        K k = JS('', '#[#]', buckets, i);
+        if (equals(k, key)) return JS('', '#.get(#)', _map, k);
+      }
+      JS('', '#.push(#)', buckets, key);
+    }
+    V value = ifAbsent();
+    if (value == null) value = null; // coerce undefined to null.
+    JS('', '#.set(#, #)', _map, key, value);
+    _modifications = (_modifications + 1) & 0x3ffffff;
+    return value;
+  }
+
+  V remove(Object key) {
+    if (key is K) {
+      int hash = JS('!', '# & 0x3ffffff', _hashCode(key));
+      var keyMap = _keyMap;
+      var buckets = JS('', '#.get(#)', keyMap, hash);
+      if (buckets == null) return null; // not found
+      var equals = _equals;
+      for (int i = 0, n = JS<int>('!', '#.length', buckets); i < n; i++) {
+        K k = JS('', '#[#]', buckets, i);
+        if (equals(k, key)) {
+          if (n == 1) {
+            JS('', '#.delete(#)', keyMap, hash);
+          } else {
+            JS('', '#.splice(#, 1)', buckets, i);
+          }
+          var map = _map;
+          V value = JS('', '#.get(#)', map, k);
+          JS('', '#.delete(#)', map, k);
+          _modifications = (_modifications + 1) & 0x3ffffff;
+          return value == null ? null : value; // coerce undefined to null.
+        }
+      }
+    }
+    return null;
+  }
+
+  void clear() {
+    var map = _map;
+    if (JS<int>('!', '#.size', map) > 0) {
+      JS('', '#.clear()', map);
+      JS('', '#.clear()', _keyMap);
+      _modifications = (_modifications + 1) & 0x3ffffff;
+    }
+  }
+}
+
+typedef bool _Equality<K>(K a, K b);
+typedef int _Hasher<K>(K object);
+typedef bool _Predicate<T>(T value);
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart
new file mode 100644
index 0000000..8fe2fa6
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart
@@ -0,0 +1,537 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for 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 defines the operations that define and manipulate Dart
+/// classes.  Included in this are:
+///   - Generics
+///   - Class metadata
+///   - Extension methods
+///
+
+// TODO(leafp): Consider splitting some of this out.
+part of dart._runtime;
+
+/// Returns a new type that mixes members from base and the mixin.
+void applyMixin(to, from) {
+  JS('', '#[#] = #', to, _mixin, from);
+  var toProto = JS('', '#.prototype', to);
+  var fromProto = JS('', '#.prototype', from);
+  _copyMembers(toProto, fromProto);
+  _mixinSignature(to, from, _methodSig);
+  _mixinSignature(to, from, _fieldSig);
+  _mixinSignature(to, from, _getterSig);
+  _mixinSignature(to, from, _setterSig);
+  var mixinOnFn = JS('', '#[#]', from, mixinOn);
+  if (mixinOnFn != null) {
+    var proto = JS('', '#(#.__proto__).prototype', mixinOnFn, to);
+    _copyMembers(toProto, proto);
+  }
+}
+
+void _copyMembers(to, from) {
+  var names = getOwnNamesAndSymbols(from);
+  for (int i = 0, n = JS('!', '#.length', names); i < n; ++i) {
+    String name = JS('', '#[#]', names, i);
+    if (name == 'constructor') continue;
+    _copyMember(to, from, name);
+  }
+  return to;
+}
+
+void _copyMember(to, from, name) {
+  var desc = getOwnPropertyDescriptor(from, name);
+  if (JS('!', '# == Symbol.iterator', name)) {
+    // On native types, Symbol.iterator may already be present.
+    // TODO(jmesserly): investigate if we still need this.
+    // If so, we need to find a better solution.
+    // See https://github.com/dart-lang/sdk/issues/28324
+    var existing = getOwnPropertyDescriptor(to, name);
+    if (existing != null) {
+      if (JS('!', '#.writable', existing)) {
+        JS('', '#[#] = #.value', to, name, desc);
+      }
+      return;
+    }
+  }
+  var getter = JS('', '#.get', desc);
+  var setter = JS('', '#.set', desc);
+  if (getter != null) {
+    if (setter == null) {
+      var obj = JS(
+          '',
+          '#.set = { __proto__: #.__proto__, '
+              'set [#](x) { return super[#] = x; } }',
+          desc,
+          to,
+          name,
+          name);
+      JS('', '#.set = #.set', desc, getOwnPropertyDescriptor(obj, name));
+    }
+  } else if (setter != null) {
+    if (getter == null) {
+      var obj = JS(
+          '',
+          '#.get = { __proto__: #.__proto__, '
+              'get [#]() { return super[#]; } }',
+          desc,
+          to,
+          name,
+          name);
+      JS('', '#.get = #.get', desc, getOwnPropertyDescriptor(obj, name));
+    }
+  }
+  defineProperty(to, name, desc);
+}
+
+void _mixinSignature(to, from, kind) {
+  JS('', '#[#] = #', to, kind, () {
+    var baseMembers = _getMembers(JS('', '#.__proto__', to), kind);
+    var fromMembers = _getMembers(from, kind);
+    if (fromMembers == null) return baseMembers;
+    var toSignature = JS('', '{ __proto__: # }', baseMembers);
+    copyProperties(toSignature, fromMembers);
+    return toSignature;
+  });
+}
+
+final _mixin = JS('', 'Symbol("mixin")');
+
+getMixin(clazz) => JS('', 'Object.hasOwnProperty.call(#, #) ? #[#] : null',
+    clazz, _mixin, clazz, _mixin);
+
+final mixinOn = JS('', 'Symbol("mixinOn")');
+
+@JSExportName('implements')
+final implements_ = JS('', 'Symbol("implements")');
+
+List Function() getImplements(clazz) => JS(
+    '',
+    'Object.hasOwnProperty.call(#, #) ? #[#] : null',
+    clazz,
+    implements_,
+    clazz,
+    implements_);
+
+/// The Symbol for storing type arguments on a specialized generic type.
+final _typeArguments = JS('', 'Symbol("typeArguments")');
+
+final _originalDeclaration = JS('', 'Symbol("originalDeclaration")');
+
+final mixinNew = JS('', 'Symbol("dart.mixinNew")');
+
+/// Memoize a generic type constructor function.
+generic(typeConstructor, setBaseClass) => JS('', '''(() => {
+  let length = $typeConstructor.length;
+  if (length < 1) {
+    $throwInternalError('must have at least one generic type argument');
+  }
+  let resultMap = new Map();
+  // TODO(vsm): Rethink how to clear the resultMap on hot restart.
+  // A simple clear via:
+  //   _cacheMaps.push(resultMap);
+  // will break (a) we hoist type expressions in generated code and
+  // (b) we don't clear those type expressions in the presence of a
+  // hot restart.  Not clearing this map (as we're doing now) should
+  // not affect correctness, but can result in a memory leak across
+  // multiple restarts.
+  function makeGenericType(...args) {
+    if (args.length != length && args.length != 0) {
+      $throwInternalError('requires ' + length + ' or 0 type arguments');
+    }
+    while (args.length < length) args.push($dynamic);
+
+    let value = resultMap;
+    for (let i = 0; i < length; i++) {
+      let arg = args[i];
+      if (arg == null) {
+        $throwInternalError('type arguments should not be null: '
+                          + $typeConstructor);
+      }
+      let map = value;
+      value = map.get(arg);
+      if (value === void 0) {
+        if (i + 1 == length) {
+          value = $typeConstructor.apply(null, args);
+          // Save the type constructor and arguments for reflection.
+          if (value) {
+            value[$_typeArguments] = args;
+            value[$_originalDeclaration] = makeGenericType;
+          }
+          map.set(arg, value);
+          if ($setBaseClass != null) $setBaseClass.apply(null, args);
+        } else {
+          value = new Map();
+          map.set(arg, value);
+        }
+      }
+    }
+    return value;
+  }
+  makeGenericType[$_genericTypeCtor] = $typeConstructor;
+  return makeGenericType;
+})()''');
+
+getGenericClass(type) => safeGetOwnProperty(type, _originalDeclaration);
+
+List getGenericArgs(type) =>
+    JS('List', '#', safeGetOwnProperty(type, _typeArguments));
+
+List<TypeVariable> getGenericTypeFormals(genericClass) {
+  return _typeFormalsFromFunction(getGenericTypeCtor(genericClass));
+}
+
+Object instantiateClass(Object genericClass, List<Object> typeArgs) {
+  return JS('', '#.apply(null, #)', genericClass, typeArgs);
+}
+
+final _constructorSig = JS('', 'Symbol("sigCtor")');
+final _methodSig = JS('', 'Symbol("sigMethod")');
+final _fieldSig = JS('', 'Symbol("sigField")');
+final _getterSig = JS('', 'Symbol("sigGetter")');
+final _setterSig = JS('', 'Symbol("sigSetter")');
+final _staticMethodSig = JS('', 'Symbol("sigStaticMethod")');
+final _staticFieldSig = JS('', 'Symbol("sigStaticField")');
+final _staticGetterSig = JS('', 'Symbol("sigStaticGetter")');
+final _staticSetterSig = JS('', 'Symbol("sigStaticSetter")');
+final _genericTypeCtor = JS('', 'Symbol("genericType")');
+final _libraryUri = JS('', 'Symbol("libraryUri")');
+
+getConstructors(value) => _getMembers(value, _constructorSig);
+getMethods(value) => _getMembers(value, _methodSig);
+getFields(value) => _getMembers(value, _fieldSig);
+getGetters(value) => _getMembers(value, _getterSig);
+getSetters(value) => _getMembers(value, _setterSig);
+getStaticMethods(value) => _getMembers(value, _staticMethodSig);
+getStaticFields(value) => _getMembers(value, _staticFieldSig);
+getStaticGetters(value) => _getMembers(value, _staticGetterSig);
+getStaticSetters(value) => _getMembers(value, _staticSetterSig);
+
+getGenericTypeCtor(value) => JS('', '#[#]', value, _genericTypeCtor);
+
+/// Get the type of a method from an object using the stored signature
+getType(obj) =>
+    JS('', '# == null ? # : #.__proto__.constructor', obj, Object, obj);
+
+getLibraryUri(value) => JS('', '#[#]', value, _libraryUri);
+setLibraryUri(f, uri) => JS('', '#[#] = #', f, _libraryUri, uri);
+
+bool isJsInterop(obj) {
+  if (obj == null) return false;
+  if (JS('!', 'typeof # === "function"', obj)) {
+    // A function is a Dart function if it has runtime type information.
+    return JS('!', '#[#] == null', obj, _runtimeType);
+  }
+  // Primitive types are not JS interop types.
+  if (JS('!', 'typeof # !== "object"', obj)) return false;
+
+  // Extension types are not considered JS interop types.
+  // Note that it is still possible to call typed JS interop methods on
+  // extension types but the calls must be statically typed.
+  if (JS('!', '#[#] != null', obj, _extensionType)) return false;
+  return JS('!', '!($obj instanceof $Object)');
+}
+
+/// Get the type of a method from a type using the stored signature
+getMethodType(type, name) {
+  var m = getMethods(type);
+  return m != null ? JS('', '#[#]', m, name) : null;
+}
+
+/// Gets the type of the corresponding setter (this includes writable fields).
+getSetterType(type, name) {
+  var setters = getSetters(type);
+  if (setters != null) {
+    var type = JS('', '#[#]', setters, name);
+    if (type != null) {
+      if (JS('!', '# instanceof Array', type)) {
+        // The type has metadata attached.  Pull out just the type.
+        // TODO(jmesserly): remove when we remove mirrors
+        return JS('', '#[0]', type);
+      }
+      return type;
+    }
+  }
+  var fields = getFields(type);
+  if (fields != null) {
+    var fieldInfo = JS('', '#[#]', fields, name);
+    if (fieldInfo != null && JS<bool>('!', '!#.isFinal', fieldInfo)) {
+      return JS('', '#.type', fieldInfo);
+    }
+  }
+  return null;
+}
+
+finalFieldType(type, metadata) =>
+    JS('', '{ type: #, isFinal: true, metadata: # }', type, metadata);
+
+fieldType(type, metadata) =>
+    JS('', '{ type: #, isFinal: false, metadata: # }', type, metadata);
+
+/// Get the type of a constructor from a class using the stored signature
+/// If name is undefined, returns the type of the default constructor
+/// Returns undefined if the constructor is not found.
+classGetConstructorType(cls, name) {
+  if (cls == null) return null;
+  if (name == null) name = 'new';
+  var ctors = getConstructors(cls);
+  return ctors != null ? JS('', '#[#]', ctors, name) : null;
+}
+
+void setMethodSignature(f, sigF) => JS('', '#[#] = #', f, _methodSig, sigF);
+void setFieldSignature(f, sigF) => JS('', '#[#] = #', f, _fieldSig, sigF);
+void setGetterSignature(f, sigF) => JS('', '#[#] = #', f, _getterSig, sigF);
+void setSetterSignature(f, sigF) => JS('', '#[#] = #', f, _setterSig, sigF);
+
+// Set up the constructor signature field on the constructor
+void setConstructorSignature(f, sigF) =>
+    JS('', '#[#] = #', f, _constructorSig, sigF);
+
+// Set up the static signature field on the constructor
+void setStaticMethodSignature(f, sigF) =>
+    JS('', '#[#] = #', f, _staticMethodSig, sigF);
+
+void setStaticFieldSignature(f, sigF) =>
+    JS('', '#[#] = #', f, _staticFieldSig, sigF);
+
+void setStaticGetterSignature(f, sigF) =>
+    JS('', '#[#] = #', f, _staticGetterSig, sigF);
+
+void setStaticSetterSignature(f, sigF) =>
+    JS('', '#[#] = #', f, _staticSetterSig, sigF);
+
+_getMembers(type, kind) {
+  var sig = JS('', '#[#]', type, kind);
+  return JS<bool>('!', 'typeof # == "function"', sig)
+      ? JS('', '#[#] = #()', type, kind, sig)
+      : sig;
+}
+
+bool _hasMember(type, kind, name) {
+  var sig = _getMembers(type, kind);
+  return sig != null && JS<bool>('!', '# in #', name, sig);
+}
+
+bool hasMethod(type, name) => _hasMember(type, _methodSig, name);
+bool hasGetter(type, name) => _hasMember(type, _getterSig, name);
+bool hasSetter(type, name) => _hasMember(type, _setterSig, name);
+bool hasField(type, name) => _hasMember(type, _fieldSig, name);
+
+final _extensionType = JS('', 'Symbol("extensionType")');
+
+final dartx = JS('', 'dartx');
+
+/// Install properties in prototype-first order.  Properties / descriptors from
+/// more specific types should overwrite ones from less specific types.
+void _installProperties(jsProto, dartType, installedParent) {
+  if (JS('!', '# === #', dartType, Object)) {
+    _installPropertiesForObject(jsProto);
+    return;
+  }
+  // If the extension methods of the parent have been installed on the parent
+  // of [jsProto], the methods will be available via prototype inheritance.
+  var dartSupertype = JS('', '#.__proto__', dartType);
+  if (JS('!', '# !== #', dartSupertype, installedParent)) {
+    _installProperties(jsProto, dartSupertype, installedParent);
+  }
+
+  var dartProto = JS('', '#.prototype', dartType);
+  copyTheseProperties(jsProto, dartProto, getOwnPropertySymbols(dartProto));
+}
+
+void _installPropertiesForObject(jsProto) {
+  // core.Object members need to be copied from the non-symbol name to the
+  // symbol name.
+  var coreObjProto = JS('', '#.prototype', Object);
+  var names = getOwnPropertyNames(coreObjProto);
+  for (int i = 0, n = JS('!', '#.length', names); i < n; ++i) {
+    var name = JS<String>('!', '#[#]', names, i);
+    if (name == 'constructor') continue;
+    var desc = getOwnPropertyDescriptor(coreObjProto, name);
+    defineProperty(jsProto, JS('', '#.#', dartx, name), desc);
+  }
+}
+
+void _installPropertiesForGlobalObject(jsProto) {
+  _installPropertiesForObject(jsProto);
+  // Use JS toString for JS objects, rather than the Dart one.
+  JS('', '#[dartx.toString] = function() { return this.toString(); }', jsProto);
+  identityEquals ??= JS('', '#[dartx._equals]', jsProto);
+}
+
+final _extensionMap = JS('', 'new Map()');
+
+_applyExtension(jsType, dartExtType) {
+  // TODO(vsm): Not all registered js types are real.
+  if (jsType == null) return;
+  var jsProto = JS('', '#.prototype', jsType);
+  if (jsProto == null) return;
+
+  if (JS('!', '# === #', dartExtType, Object)) {
+    _installPropertiesForGlobalObject(jsProto);
+    return;
+  }
+
+  _installProperties(
+      jsProto, dartExtType, JS('', '#[#]', jsProto, _extensionType));
+
+  // Mark the JS type's instances so we can easily check for extensions.
+  if (JS('!', '# !== #', dartExtType, JSFunction)) {
+    JS('', '#[#] = #', jsProto, _extensionType, dartExtType);
+  }
+  JS('', '#[#] = #[#]', jsType, _methodSig, dartExtType, _methodSig);
+  JS('', '#[#] = #[#]', jsType, _fieldSig, dartExtType, _fieldSig);
+  JS('', '#[#] = #[#]', jsType, _getterSig, dartExtType, _getterSig);
+  JS('', '#[#] = #[#]', jsType, _setterSig, dartExtType, _setterSig);
+}
+
+/// Apply the previously registered extension to the type of [nativeObject].
+/// This is intended for types that are not available to polyfill at startup.
+applyExtension(name, nativeObject) {
+  var dartExtType = JS('', '#.get(#)', _extensionMap, name);
+  var jsType = JS('', '#.constructor', nativeObject);
+  _applyExtension(jsType, dartExtType);
+}
+
+/// Apply all registered extensions to a window.  This is intended for
+/// different frames, where registrations need to be reapplied.
+applyAllExtensions(global) {
+  JS('', '#.forEach((dartExtType, name) => #(#[name], dartExtType))',
+      _extensionMap, _applyExtension, global);
+}
+
+/// Copy symbols from the prototype of the source to destination.
+/// These are the only properties safe to copy onto an existing public
+/// JavaScript class.
+registerExtension(name, dartExtType) {
+  JS('', '#.set(#, #)', _extensionMap, name, dartExtType);
+  var jsType = JS('', '#[#]', global_, name);
+  _applyExtension(jsType, dartExtType);
+}
+
+///
+/// Mark a concrete type as implementing extension methods.
+/// For example: `class MyIter implements Iterable`.
+///
+/// This takes a list of names, which are the extension methods implemented.
+/// It will add a forwarder, so the extension method name redirects to the
+/// normal Dart method name. For example:
+///
+///     defineExtensionMembers(MyType, ['add', 'remove']);
+///
+/// Results in:
+///
+///     MyType.prototype[dartx.add] = MyType.prototype.add;
+///     MyType.prototype[dartx.remove] = MyType.prototype.remove;
+///
+// TODO(jmesserly): essentially this gives two names to the same method.
+// This benefit is roughly equivalent call performance either way, but the
+// cost is we need to call defineExtensionMembers any time a subclass
+// overrides one of these methods.
+defineExtensionMethods(type, Iterable memberNames) {
+  var proto = JS('', '#.prototype', type);
+  for (var name in memberNames) {
+    JS('', '#[dartx.#] = #[#]', proto, name, proto, name);
+  }
+}
+
+/// Like [defineExtensionMethods], but for getter/setter pairs.
+defineExtensionAccessors(type, Iterable memberNames) {
+  var proto = JS('', '#.prototype', type);
+  for (var name in memberNames) {
+    // Find the member. It should always exist (or we have a compiler bug).
+    var member;
+    var p = proto;
+    for (;; p = JS('', '#.__proto__', p)) {
+      member = getOwnPropertyDescriptor(p, name);
+      if (member != null) break;
+    }
+    defineProperty(proto, JS('', 'dartx[#]', name), member);
+  }
+}
+
+definePrimitiveHashCode(proto) {
+  defineProperty(proto, identityHashCode_,
+      getOwnPropertyDescriptor(proto, extensionSymbol('hashCode')));
+}
+
+/// Link the extension to the type it's extending as a base class.
+setBaseClass(derived, base) {
+  JS('', '#.prototype.__proto__ = #.prototype', derived, base);
+  // We use __proto__ to track the superclass hierarchy (see isSubtypeOf).
+  JS('', '#.__proto__ = #', derived, base);
+}
+
+/// Like [setBaseClass], but for generic extension types such as `JSArray<E>`.
+setExtensionBaseClass(dartType, jsType) {
+  // Mark the generic type as an extension type and link the prototype objects.
+  var dartProto = JS('', '#.prototype', dartType);
+  JS('', '#[#] = #', dartProto, _extensionType, dartType);
+  JS('', '#.__proto__ = #.prototype', dartProto, jsType);
+}
+
+/// Adds type test predicates to a class/interface type [ctor], using the
+/// provided [isClass] JS Symbol.
+///
+/// This will operate quickly for non-generic types, native extension types,
+/// as well as matching exact generic type arguments:
+///
+///     class C<T> {}
+///     class D extends C<int> {}
+///     main() { dynamic d = new D(); d as C<int>; }
+///
+addTypeTests(ctor, isClass) {
+  if (isClass == null) isClass = JS('', 'Symbol("_is_" + ctor.name)');
+  // TODO(jmesserly): since we know we're dealing with class/interface types,
+  // we can optimize this rather than go through the generic `dart.is` helpers.
+  JS('', '#.prototype[#] = true', ctor, isClass);
+  JS(
+      '',
+      '''#.is = function is_C(obj) {
+    return obj != null && (obj[#] || #(obj, this));
+  }''',
+      ctor,
+      isClass,
+      instanceOf);
+  JS(
+      '',
+      '''#.as = function as_C(obj) {
+    if (obj == null || obj[#]) return obj;
+    return #(obj, this, false);
+  }''',
+      ctor,
+      isClass,
+      cast);
+  JS(
+      '',
+      '''#._check = function check_C(obj) {
+    if (obj == null || obj[#]) return obj;
+    return #(obj, this, true);
+  }''',
+      ctor,
+      isClass,
+      cast);
+}
+
+// TODO(jmesserly): should we do this for all interfaces?
+
+/// The well known symbol for testing `is Future`
+final isFuture = JS('', 'Symbol("_is_Future")');
+
+/// The well known symbol for testing `is Iterable`
+final isIterable = JS('', 'Symbol("_is_Iterable")');
+
+/// The well known symbol for testing `is List`
+final isList = JS('', 'Symbol("_is_List")');
+
+/// The well known symbol for testing `is Map`
+final isMap = JS('', 'Symbol("_is_Map")');
+
+/// The well known symbol for testing `is Stream`
+final isStream = JS('', 'Symbol("_is_Stream")');
+
+/// The well known symbol for testing `is StreamSubscription`
+final isStreamSubscription = JS('', 'Symbol("_is_StreamSubscription")');
+
+/// The default `operator ==` that calls [identical].
+var identityEquals;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
new file mode 100644
index 0000000..f875336
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
@@ -0,0 +1,271 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart._runtime;
+
+// We need to set these properties while the sdk is only partially initialized
+// so we cannot use regular Dart fields.
+// The default values for these properties are set when the global_ final field
+// in runtime.dart is initialized.
+
+argumentError(value) {
+  throw ArgumentError.value(value);
+}
+
+throwUnimplementedError(String message) {
+  throw UnimplementedError(message);
+}
+
+// TODO(nshahan) Cleanup embeded strings and extract file location at runtime
+// from the stacktrace.
+assertFailed(String message,
+    [String fileUri, int line, int column, String conditionSource]) {
+  throw AssertionErrorImpl(message, fileUri, line, column, conditionSource);
+}
+
+throwCyclicInitializationError([Object field]) {
+  throw CyclicInitializationError(field);
+}
+
+throwNullValueError() {
+  // TODO(vsm): Per spec, we should throw an NSM here.  Technically, we ought
+  // to thread through method info, but that uglifies the code and can't
+  // actually be queried ... it only affects how the error is printed.
+  throw NoSuchMethodError(
+      null, Symbol('<Unexpected Null Value>'), null, null, null);
+}
+
+castError(obj, expectedType, [@notNull bool isImplicit = false]) {
+  var actualType = getReifiedType(obj);
+  var message = _castErrorMessage(actualType, expectedType);
+  var error = isImplicit ? TypeErrorImpl(message) : CastErrorImpl(message);
+  throw error;
+}
+
+String _castErrorMessage(from, to) {
+  // If both types are generic classes, see if we can infer generic type
+  // arguments for `from` that would allow the subtype relation to work.
+  var fromClass = getGenericClass(from);
+  if (fromClass != null) {
+    var fromTypeFormals = getGenericTypeFormals(fromClass);
+    var fromType = instantiateClass(fromClass, fromTypeFormals);
+    var inferrer = _TypeInferrer(fromTypeFormals);
+    if (inferrer.trySubtypeMatch(fromType, to)) {
+      var inferredTypes = inferrer.getInferredTypes();
+      if (inferredTypes != null) {
+        var inferred = instantiateClass(fromClass, inferredTypes);
+        return "Type '${typeName(from)}' should be '${typeName(inferred)}' "
+            "to implement expected type '${typeName(to)}'.";
+      }
+    }
+  }
+  return "Expected a value of type '${typeName(to)}', "
+      "but got one of type '${typeName(from)}'";
+}
+
+/// The symbol that references the thrown Dart Object (typically but not
+/// necessarily an [Error] or [Exception]), used by the [exception] function.
+final Object _thrownValue = JS('', 'Symbol("_thrownValue")');
+
+/// For a Dart [Error], this provides access to the JS Error object that
+/// contains the stack trace if the error was thrown.
+final Object _jsError = JS('', 'Symbol("_jsError")');
+
+/// Gets the thrown Dart Object from an [error] caught by a JS catch.
+///
+/// If the throw originated in Dart, the result will typically be an [Error]
+/// or [Exception], but it could be any Dart object.
+///
+/// If the throw originated in JavaScript, then there is not a corresponding
+/// Dart value, so we just return the error object.
+Object getThrown(Object error) {
+  if (error != null) {
+    // Get the Dart thrown value, if any.
+    var value = JS('', '#[#]', error, _thrownValue);
+    if (value != null) return value;
+  }
+  // Otherwise return the original object.
+  return error;
+}
+
+final _stackTrace = JS('', 'Symbol("_stackTrace")');
+
+/// Returns the stack trace from an [error] caught by a JS catch.
+///
+/// If the throw originated in Dart, we should always have JS Error
+/// (see [throw_]) so we can create a Dart [StackTrace] from that (or return a
+/// previously created instance).
+///
+/// If the throw originated in JavaScript and was an `Error`, then we can get
+/// the corresponding stack trace the same way we do for Dart throws. If the
+/// throw object was not an Error, then we don't have a JS trace, so we create
+/// one here.
+StackTrace stackTrace(Object error) {
+  if (JS<bool>('!', '!(# instanceof Error)', error)) {
+    // We caught something that isn't a JS Error.
+    //
+    // We should only hit this path when a non-Error was thrown from JS. In
+    // case, there is no stack trace available, so create one here.
+    return _StackTrace.missing(error);
+  }
+
+  // If we've already created the Dart stack trace object, return it.
+  StackTrace trace = JS('', '#[#]', error, _stackTrace);
+  if (trace != null) return trace;
+
+  // Otherwise create the Dart stack trace (by parsing the JS stack), and
+  // cache it so we don't repeat the parsing/allocation.
+  return JS('', '#[#] = #', error, _stackTrace, _StackTrace(error));
+}
+
+StackTrace stackTraceForError(Error error) {
+  return stackTrace(JS('', '#[#]', error, _jsError));
+}
+
+/// Implements `rethrow` of [error], allowing rethrow in an expression context.
+///
+/// Note: [error] must be the raw JS error caught in the JS catch, not the
+/// unwrapped value returned by [getThrown].
+@JSExportName('rethrow')
+void rethrow_(Object error) {
+  JS('', 'throw #', error);
+}
+
+/// Subclass of JS `Error` that wraps a thrown Dart object, and evaluates the
+/// message lazily by calling `toString()` on the wrapped Dart object.
+///
+/// Also creates a pointer from the thrown Dart object to the JS Error
+/// (via [_jsError]). This is used to implement [Error.stackTrace], but also
+/// provides a way to recover the stack trace if we lose track of it.
+/// [Error] requires preserving the original stack trace if an error is
+/// rethrown, so we only update the pointer if it wasn't already set.
+///
+/// TODO(jmesserly): Dart Errors should simply be JS Errors.
+final Object DartError = JS(
+    '!',
+    '''class DartError extends Error {
+      constructor(error) {
+        super();
+        if (error == null) error = #;
+        this[#] = error;
+        if (error != null && typeof error == "object" && error[#] == null) {
+          error[#] = this;
+        }
+      }
+      get message() {
+        return #(this[#]);
+      }
+    }''',
+    NullThrownError(),
+    _thrownValue,
+    _jsError,
+    _jsError,
+    _toString,
+    _thrownValue);
+
+/// Subclass of [DartError] for cases where we're rethrowing with a different,
+/// original Dart StackTrace object.
+///
+/// This includes the original stack trace in the JS Error message so it doesn't
+/// get lost if the exception reaches JS.
+final Object RethrownDartError = JS(
+    '!',
+    '''class RethrownDartError extends # {
+      constructor(error, stackTrace) {
+        super(error);
+        this[#] = stackTrace;
+      }
+      get message() {
+        return super.message + "\\n    " + #(this[#]) + "\\n";
+      }
+    }''',
+    DartError,
+    _stackTrace,
+    _toString,
+    _stackTrace);
+
+/// Implements `throw` of [exception], allowing for throw in an expression
+/// context, and capturing the current stack trace.
+@JSExportName('throw')
+void throw_(Object exception) {
+  /// Wrap the object so we capture a new stack trace, and so it will print
+  /// nicely from JS, as if it were a normal JS error.
+  JS('', 'throw new #(#)', DartError, exception);
+}
+
+/// Returns a JS error for throwing the Dart [exception] Object and using the
+/// provided stack [trace].
+///
+/// This is used by dart:async to rethrow unhandled errors in [Zone]s, and by
+/// `async`/`async*` to rethrow errors from Futures/Streams into the generator
+/// (so a try/catch in there can catch it).
+///
+/// If the exception and trace originated from the same Dart throw, then we can
+/// simply return the original JS Error. Otherwise, we have to create a new JS
+/// Error. The new error will have the correct Dart trace, but it will not have
+/// the correct JS stack trace (visible if JavaScript ends up handling it). To
+/// fix that, we use [RethrownDartError] to preserve the Dart trace and make
+/// sure it gets displayed in the JS error message.
+///
+/// If the stack trace is null, this will preserve the original stack trace
+/// on the exception, if available, otherwise it will capture the current stack
+/// trace.
+Object createErrorWithStack(Object exception, StackTrace trace) {
+  if (trace == null) {
+    var error = JS('', '#[#]', exception, _jsError);
+    return error != null ? error : JS('', 'new #(#)', DartError, exception);
+  }
+  if (trace is _StackTrace) {
+    /// Optimization: if this stack trace and exception already have a matching
+    /// Error, we can just rethrow it.
+    var originalError = trace._jsError;
+    if (identical(exception, getThrown(originalError))) {
+      return originalError;
+    }
+  }
+  return JS('', 'new #(#, #)', RethrownDartError, exception, trace);
+}
+
+// This is a utility function: it is only intended to be called from dev
+// tools.
+void stackPrint(Object error) {
+  JS('', 'console.log(#.stack ? #.stack : "No stack trace for: " + #)', error,
+      error, error);
+}
+
+class _StackTrace implements StackTrace {
+  final Object _jsError;
+  final Object _jsObjectMissingTrace;
+  String _trace;
+
+  _StackTrace(this._jsError) : _jsObjectMissingTrace = null;
+
+  _StackTrace.missing(Object caughtObj)
+      : _jsObjectMissingTrace = caughtObj != null ? caughtObj : 'null',
+        _jsError = JS('', 'Error()');
+
+  String toString() {
+    if (_trace != null) return _trace;
+
+    var e = _jsError;
+    String trace = '';
+    if (e != null && JS<bool>('!', 'typeof # === "object"', e)) {
+      trace = e is NativeError ? e.dartStack() : JS<String>('', '#.stack', e);
+      if (trace != null && stackTraceMapper != null) {
+        trace = stackTraceMapper(trace);
+      }
+    }
+    if (trace.isEmpty || _jsObjectMissingTrace != null) {
+      String jsToString;
+      try {
+        jsToString = JS('', '"" + #', _jsObjectMissingTrace);
+      } catch (_) {
+        jsToString = '<error converting JS object to string>';
+      }
+      trace = 'Non-error `$jsToString` thrown by JS does not have stack trace.'
+          '\nCaught in Dart at:\n\n$trace';
+    }
+    return _trace = trace;
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
new file mode 100644
index 0000000..e388cd6
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
@@ -0,0 +1,725 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for 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 defines runtime operations on objects used by the code
+/// generator.
+part of dart._runtime;
+
+// TODO(jmesserly): remove this in favor of _Invocation.
+class InvocationImpl extends Invocation {
+  final Symbol memberName;
+  final List positionalArguments;
+  final Map<Symbol, dynamic> namedArguments;
+  final List<Type> typeArguments;
+  final bool isMethod;
+  final bool isGetter;
+  final bool isSetter;
+  final String failureMessage;
+
+  InvocationImpl(memberName, List<Object> positionalArguments,
+      {namedArguments,
+      List typeArguments,
+      this.isMethod = false,
+      this.isGetter = false,
+      this.isSetter = false,
+      this.failureMessage = 'method not found'})
+      : memberName =
+            isSetter ? _setterSymbol(memberName) : _dartSymbol(memberName),
+        positionalArguments = List.unmodifiable(positionalArguments),
+        namedArguments = _namedArgsToSymbols(namedArguments),
+        typeArguments = typeArguments == null
+            ? const []
+            : List.unmodifiable(typeArguments.map(wrapType));
+
+  static Map<Symbol, dynamic> _namedArgsToSymbols(namedArgs) {
+    if (namedArgs == null) return const {};
+    return Map.unmodifiable(Map.fromIterable(getOwnPropertyNames(namedArgs),
+        key: _dartSymbol, value: (k) => JS('', '#[#]', namedArgs, k)));
+  }
+}
+
+/// Given an object and a method name, tear off the method.
+/// Sets the runtime type of the torn off method appropriately,
+/// and also binds the object.
+///
+/// If the optional `f` argument is passed in, it will be used as the method.
+/// This supports cases like `super.foo` where we need to tear off the method
+/// from the superclass, not from the `obj` directly.
+// TODO(leafp): Consider caching the tearoff on the object?
+bind(obj, name, method) {
+  if (obj == null) obj = jsNull;
+  if (method == null) method = JS('', '#[#]', obj, name);
+  var f = JS('', '#.bind(#)', method, obj);
+  // TODO(jmesserly): canonicalize tearoffs.
+  JS('', '#._boundObject = #', f, obj);
+  JS('', '#._boundMethod = #', f, method);
+  JS('', '#[#] = #', f, _runtimeType, getMethodType(getType(obj), name));
+  return f;
+}
+
+/// Binds the `call` method of an interface type, handling null.
+///
+/// Essentially this works like `obj?.call`. It also handles the needs of
+/// [dsend]/[dcall], returning `null` if no method was found with the given
+/// canonical member [name].
+///
+/// [name] is typically `"call"` but it could be the [extensionSymbol] for
+/// `call`, if we define it on a native type, and [obj] is known statially to be
+/// a native type/interface with `call`.
+bindCall(obj, name) {
+  if (obj == null) return null;
+  var ftype = getMethodType(getType(obj), name);
+  if (ftype == null) return null;
+  var method = JS('', '#[#]', obj, name);
+  var f = JS('', '#.bind(#)', method, obj);
+  // TODO(jmesserly): canonicalize tearoffs.
+  JS('', '#._boundObject = #', f, obj);
+  JS('', '#._boundMethod = #', f, method);
+  JS('', '#[#] = #', f, _runtimeType, ftype);
+  return f;
+}
+
+/// Instantiate a generic method.
+///
+/// We need to apply the type arguments both to the function, as well as its
+/// associated function type.
+gbind(f, @rest List typeArgs) {
+  GenericFunctionType type = JS('!', '#[#]', f, _runtimeType);
+  type.checkBounds(typeArgs);
+  // Create a JS wrapper function that will also pass the type arguments, and
+  // tag it with the instantiated function type.
+  var result =
+      JS('', '(...args) => #.apply(null, #.concat(args))', f, typeArgs);
+  return fn(result, type.instantiate(typeArgs));
+}
+
+dloadRepl(obj, field) => dload(obj, replNameLookup(obj, field), false);
+
+// Warning: dload, dput, and dsend assume they are never called on methods
+// implemented by the Object base class as those methods can always be
+// statically resolved.
+dload(obj, field, [@undefined mirrors]) {
+  if (JS('!', 'typeof # == "function" && # == "call"', obj, field)) {
+    return obj;
+  }
+  var f = _canonicalMember(obj, field);
+
+  trackCall(obj);
+  if (f != null) {
+    var type = getType(obj);
+
+    if (hasField(type, f) || hasGetter(type, f)) return JS('', '#[#]', obj, f);
+    if (hasMethod(type, f)) return bind(obj, f, null);
+
+    // Always allow for JS interop objects.
+    if (!JS<bool>('!', '#', mirrors) && isJsInterop(obj)) {
+      return JS('', '#[#]', obj, f);
+    }
+  }
+  return noSuchMethod(obj, InvocationImpl(field, JS('', '[]'), isGetter: true));
+}
+
+// Version of dload that matches legacy mirrors behavior for JS types.
+dloadMirror(obj, field) => dload(obj, field, true);
+
+_stripGenericArguments(type) {
+  var genericClass = getGenericClass(type);
+  if (genericClass != null) return JS('', '#()', genericClass);
+  return type;
+}
+
+// Version of dput that matches legacy Dart 1 type check rules and mirrors
+// behavior for JS types.
+// TODO(jacobr): remove the type checking rules workaround when mirrors based
+// PageLoader code can generate the correct reified generic types.
+dputMirror(obj, field, value) => dput(obj, field, value, true);
+
+dputRepl(obj, field, value) =>
+    dput(obj, replNameLookup(obj, field), value, false);
+
+dput(obj, field, value, [@undefined mirrors]) {
+  var f = _canonicalMember(obj, field);
+  trackCall(obj);
+  if (f != null) {
+    var setterType = getSetterType(getType(obj), f);
+    if (setterType != null) {
+      if (JS('!', '#', mirrors))
+        setterType = _stripGenericArguments(setterType);
+      return JS('', '#[#] = #._check(#)', obj, f, setterType, value);
+    }
+    // Always allow for JS interop objects.
+    if (!JS<bool>('!', '#', mirrors) && isJsInterop(obj)) {
+      return JS('', '#[#] = #', obj, f, value);
+    }
+  }
+  noSuchMethod(
+      obj, InvocationImpl(field, JS('', '[#]', value), isSetter: true));
+  return value;
+}
+
+/// Returns an error message if function of a given [type] can't be applied to
+/// [actuals] and [namedActuals].
+///
+/// Returns `null` if all checks pass.
+String _argumentErrors(FunctionType type, List actuals, namedActuals) {
+  // Check for too few required arguments.
+  int actualsCount = JS('!', '#.length', actuals);
+  var required = type.args;
+  int requiredCount = JS('!', '#.length', required);
+  if (actualsCount < requiredCount) {
+    return 'Dynamic call with too few arguments. '
+        'Expected: $requiredCount Actual: $actualsCount';
+  }
+
+  // Check for too many postional arguments.
+  var extras = actualsCount - requiredCount;
+  var optionals = type.optionals;
+  if (extras > JS<int>('!', '#.length', optionals)) {
+    return 'Dynamic call with too many arguments. '
+        'Expected: $requiredCount Actual: $actualsCount';
+  }
+
+  // Check if we have invalid named arguments.
+  Iterable names;
+  var named = type.named;
+  if (namedActuals != null) {
+    names = getOwnPropertyNames(namedActuals);
+    for (var name in names) {
+      if (!JS('!', '#.hasOwnProperty(#)', named, name)) {
+        return "Dynamic call with unexpected named argument '$name'.";
+      }
+    }
+  }
+  // Now that we know the signature matches, we can perform type checks.
+  for (var i = 0; i < requiredCount; ++i) {
+    JS('', '#[#]._check(#[#])', required, i, actuals, i);
+  }
+  for (var i = 0; i < extras; ++i) {
+    JS('', '#[#]._check(#[#])', optionals, i, actuals, i + requiredCount);
+  }
+  if (names != null) {
+    for (var name in names) {
+      JS('', '#[#]._check(#[#])', named, name, namedActuals, name);
+    }
+  }
+  return null;
+}
+
+_toSymbolName(symbol) => JS('', '''(() => {
+        let str = $symbol.toString();
+        // Strip leading 'Symbol(' and trailing ')'
+        return str.substring(7, str.length-1);
+    })()''');
+
+_toDisplayName(name) => JS('', '''(() => {
+      // Names starting with _ are escaped names used to disambiguate Dart and
+      // JS names.
+      if ($name[0] === '_') {
+        // Inverse of
+        switch($name) {
+          case '_get':
+            return '[]';
+          case '_set':
+            return '[]=';
+          case '_negate':
+            return 'unary-';
+          case '_constructor':
+          case '_prototype':
+            return $name.substring(1);
+        }
+      }
+      return $name;
+  })()''');
+
+Symbol _dartSymbol(name) {
+  return (JS<bool>('!', 'typeof # === "symbol"', name))
+      ? JS('Symbol', '#(new #.new(#, #))', const_, PrivateSymbol,
+          _toSymbolName(name), name)
+      : JS('Symbol', '#(new #.new(#))', const_, internal.Symbol,
+          _toDisplayName(name));
+}
+
+Symbol _setterSymbol(name) {
+  return (JS<bool>('!', 'typeof # === "symbol"', name))
+      ? JS('Symbol', '#(new #.new(# + "=", #))', const_, PrivateSymbol,
+          _toSymbolName(name), name)
+      : JS('Symbol', '#(new #.new(# + "="))', const_, internal.Symbol,
+          _toDisplayName(name));
+}
+
+_checkAndCall(f, ftype, obj, typeArgs, args, named, displayName) =>
+    JS('', '''(() => {
+  $trackCall($obj);
+
+  let originalTarget = obj === void 0 ? f : obj;
+
+  function callNSM(errorMessage) {
+    return $noSuchMethod(originalTarget, new $InvocationImpl.new(
+        $displayName, $args, {
+          namedArguments: $named,
+          typeArguments: $typeArgs,
+          isMethod: true,
+          failureMessage: errorMessage
+        }));
+  }
+  if ($f == null) return callNSM('Dynamic call of null.');
+  if (!($f instanceof Function)) {
+    // We're not a function (and hence not a method either)
+    // Grab the `call` method if it's not a function.
+    if ($f != null) {
+      // Getting the member succeeded, so update the originalTarget.
+      // (we're now trying `call()` on `f`, so we want to call its nSM rather
+      // than the original target's nSM).
+      originalTarget = f;
+      $f = ${bindCall(f, _canonicalMember(f, 'call'))};
+      $ftype = null;
+      $displayName = "call";
+    }
+    if ($f == null) return callNSM(
+        "Dynamic call of object has no instance method 'call'.");
+  }
+  // If f is a function, but not a method (no method type)
+  // then it should have been a function valued field, so
+  // get the type from the function.
+  if ($ftype == null) $ftype = $f[$_runtimeType];
+
+  if ($ftype == null) {
+    // TODO(leafp): Allow JS objects to go through?
+    if ($typeArgs != null) {
+      // TODO(jmesserly): is there a sensible way to handle these?
+      $throwTypeError('call to JS object `' + $obj +
+          '` with type arguments <' + $typeArgs + '> is not supported.');
+    }
+
+    if ($named != null) $args.push($named);
+    return $f.apply($obj, $args);
+  }
+
+  // TODO(vsm): Remove when we no longer need mirrors metadata.
+  // An array is used to encode annotations attached to the type.
+  if ($ftype instanceof Array) $ftype = $ftype[0];
+
+  // Apply type arguments
+  if ($ftype instanceof $GenericFunctionType) {
+    let formalCount = $ftype.formalCount;
+
+    if ($typeArgs == null) {
+      $typeArgs = $ftype.instantiateDefaultBounds();
+    } else if ($typeArgs.length != formalCount) {
+      return callNSM('Dynamic call with incorrect number of type arguments. ' +
+          'Expected: ' + formalCount + ' Actual: ' + $typeArgs.length);
+    } else {
+      $ftype.checkBounds($typeArgs);
+    }
+    $ftype = $ftype.instantiate($typeArgs);
+  } else if ($typeArgs != null) {
+    return callNSM('Dynamic call with unexpected type arguments. ' +
+        'Expected: 0 Actual: ' + $typeArgs.length);
+  }
+  let errorMessage = $_argumentErrors($ftype, $args, $named);
+  if (errorMessage == null) {
+    if ($typeArgs != null) $args = $typeArgs.concat($args);
+    if ($named != null) $args.push($named);
+    return $f.apply($obj, $args);
+  }
+  return callNSM(errorMessage);
+})()''');
+
+dcall(f, args, [@undefined named]) => _checkAndCall(
+    f, null, JS('', 'void 0'), null, args, named, JS('', 'f.name'));
+
+dgcall(f, typeArgs, args, [@undefined named]) =>
+    _checkAndCall(f, null, JS('', 'void 0'), typeArgs, args, named, 'call');
+
+/// Helper for REPL dynamic invocation variants that make a best effort to
+/// enable accessing private members across library boundaries.
+replNameLookup(object, field) => JS('', '''(() => {
+  let rawField = $field;
+  if (typeof(field) == 'symbol') {
+    // test if the specified field exists in which case it is safe to use it.
+    if ($field in $object) return $field;
+
+    // Symbol is from a different library. Make a best effort to
+    $field = $field.toString();
+    $field = $field.substring('Symbol('.length, field.length - 1);
+
+  } else if ($field.charAt(0) != '_') {
+    // Not a private member so default call path is safe.
+    return $field;
+  }
+
+  // If the exact field name is present, invoke callback with it.
+  if ($field in $object) return $field;
+
+  // TODO(jacobr): warn if there are multiple private members with the same
+  // name which could happen if super classes in different libraries have
+  // the same private member name.
+  let proto = $object;
+  while (proto !== null) {
+    // Private field (indicated with "_").
+    let symbols = Object.getOwnPropertySymbols(proto);
+    let target = 'Symbol(' + $field + ')';
+
+    for (let s = 0; s < symbols.length; s++) {
+      let sym = symbols[s];
+      if (target == sym.toString()) return sym;
+    }
+    proto = proto.__proto__;
+  }
+  // We didn't find a plausible alternate private symbol so just fall back
+  // to the regular field.
+  return rawField;
+})()''');
+
+/// Shared code for dsend, dindex, and dsetindex.
+callMethod(obj, name, typeArgs, args, named, displayName) {
+  if (JS('!', 'typeof # == "function" && # == "call"', obj, name)) {
+    return dgcall(obj, typeArgs, args, named);
+  }
+  var symbol = _canonicalMember(obj, name);
+  if (symbol == null) {
+    return noSuchMethod(obj, InvocationImpl(displayName, args, isMethod: true));
+  }
+  var f = obj != null ? JS('', '#[#]', obj, symbol) : null;
+  var type = getType(obj);
+  var ftype = getMethodType(type, symbol);
+  // No such method if dart object and ftype is missing.
+  return _checkAndCall(f, ftype, obj, typeArgs, args, named, displayName);
+}
+
+dsend(obj, method, args, [@undefined named]) =>
+    callMethod(obj, method, null, args, named, method);
+
+dgsend(obj, typeArgs, method, args, [@undefined named]) =>
+    callMethod(obj, method, typeArgs, args, named, method);
+
+dsendRepl(obj, method, args, [@undefined named]) =>
+    callMethod(obj, replNameLookup(obj, method), null, args, named, method);
+
+dgsendRepl(obj, typeArgs, method, args, [@undefined named]) =>
+    callMethod(obj, replNameLookup(obj, method), typeArgs, args, named, method);
+
+dindex(obj, index) => callMethod(obj, '_get', null, [index], null, '[]');
+
+dsetindex(obj, index, value) =>
+    callMethod(obj, '_set', null, [index, value], null, '[]=');
+
+@notNull
+@JSExportName('is')
+bool instanceOf(obj, type) {
+  if (obj == null) {
+    return identical(type, unwrapType(Null)) || _isTop(type);
+  }
+  return isSubtypeOf(getReifiedType(obj), type);
+}
+
+@JSExportName('as')
+cast(obj, type, @notNull bool isImplicit) {
+  if (obj == null) return obj;
+  var actual = getReifiedType(obj);
+  if (isSubtypeOf(actual, type)) {
+    return obj;
+  }
+  return castError(obj, type, isImplicit);
+}
+
+bool test(bool obj) {
+  if (obj == null) _throwBooleanConversionError();
+  return obj;
+}
+
+bool dtest(obj) {
+  if (obj is! bool) booleanConversionFailed(obj);
+  return obj;
+}
+
+void _throwBooleanConversionError() => throw BooleanConversionAssertionError();
+
+void booleanConversionFailed(obj) {
+  var actual = typeName(getReifiedType(test(obj)));
+  throw TypeErrorImpl("type '$actual' is not a 'bool' in boolean expression");
+}
+
+asInt(obj) {
+  if (obj == null) return null;
+
+  if (JS('!', 'Math.floor(#) != #', obj, obj)) {
+    castError(obj, JS('', '#', int), false);
+  }
+  return obj;
+}
+
+/// Checks that `x` is not null or undefined.
+//
+// TODO(jmesserly): inline this, either by generating it as a function into
+// the module, or via some other pattern such as:
+//
+//     <expr> || nullErr()
+//     (t0 = <expr>) != null ? t0 : nullErr()
+@JSExportName('notNull')
+_notNull(x) {
+  if (x == null) throwNullValueError();
+  return x;
+}
+
+/// The global constant map table.
+final constantMaps = JS('', 'new Map()');
+
+// TODO(leafp): This table gets quite large in apps.
+// Keeping the paths is probably expensive.  It would probably
+// be more space efficient to just use a direct hash table with
+// an appropriately defined structural equality function.
+Object _lookupNonTerminal(Object map, Object key) {
+  var result = JS('', '#.get(#)', map, key);
+  if (result != null) return result;
+  JS('', '#.set(#, # = new Map())', map, key, result);
+  return result;
+}
+
+Map<K, V> constMap<K, V>(JSArray elements) {
+  var count = elements.length;
+  var map = _lookupNonTerminal(constantMaps, count);
+  for (var i = 0; i < count; i++) {
+    map = _lookupNonTerminal(map, JS('', '#[#]', elements, i));
+  }
+  map = _lookupNonTerminal(map, K);
+  var result = JS('', '#.get(#)', map, V);
+  if (result != null) return result;
+  result = ImmutableMap<K, V>.from(elements);
+  JS('', '#.set(#, #)', map, V, result);
+  return result;
+}
+
+final constantSets = JS('', 'new Map()');
+var _immutableSetConstructor;
+
+// We cannot invoke private class constructors directly in Dart.
+Set<E> _createImmutableSet<E>(JSArray<E> elements) {
+  _immutableSetConstructor ??=
+      JS('', '#.#', getLibrary('dart:collection'), '_ImmutableSet\$');
+  return JS('', 'new (#(#)).from(#)', _immutableSetConstructor, E, elements);
+}
+
+Set<E> constSet<E>(JSArray<E> elements) {
+  var count = elements.length;
+  var map = _lookupNonTerminal(constantSets, count);
+  for (var i = 0; i < count; i++) {
+    map = _lookupNonTerminal(map, JS('', '#[#]', elements, i));
+  }
+  var result = JS('', '#.get(#)', map, E);
+  if (result != null) return result;
+  result = _createImmutableSet<E>(elements);
+  JS('', '#.set(#, #)', map, E, result);
+  return result;
+}
+
+bool dassert(value) {
+  if (JS('!', '# != null && #[#] instanceof #', value, value, _runtimeType,
+      AbstractFunctionType)) {
+    value = dcall(value, []);
+  }
+  return dtest(value);
+}
+
+final _value = JS('', 'Symbol("_value")');
+
+///
+/// Looks up a sequence of [keys] in [map], recursively, and
+/// returns the result. If the value is not found, [valueFn] will be called to
+/// add it. For example:
+///
+///     let map = new Map();
+///     putIfAbsent(map, [1, 2, 'hi ', 'there '], () => 'world');
+///
+/// ... will create a Map with a structure like:
+///
+///     { 1: { 2: { 'hi ': { 'there ': 'world' } } } }
+///
+multiKeyPutIfAbsent(map, keys, valueFn) => JS('', '''(() => {
+  for (let k of $keys) {
+    let value = $map.get(k);
+    if (!value) {
+      // TODO(jmesserly): most of these maps are very small (e.g. 1 item),
+      // so it may be worth optimizing for that.
+      $map.set(k, value = new Map());
+    }
+    $map = value;
+  }
+  if ($map.has($_value)) return $map.get($_value);
+  let value = $valueFn();
+  $map.set($_value, value);
+  return value;
+})()''');
+
+/// The global constant table.
+/// This maps the number of names in the object (n)
+/// to a path of length 2*n of maps indexed by the name and
+/// and value of the field.  The final map is
+/// indexed by runtime type, and contains the canonical
+/// version of the object.
+final constants = JS('', 'new Map()');
+
+///
+/// Canonicalize a constant object.
+///
+/// Preconditions:
+/// - `obj` is an objects or array, not a primitive.
+/// - nested values of the object are themselves already canonicalized.
+///
+@JSExportName('const')
+const_(obj) => JS('', '''(() => {
+  let names = $getOwnNamesAndSymbols($obj);
+  let count = names.length;
+  // Index by count.  All of the paths through this map
+  // will have 2*count length.
+  let map = $_lookupNonTerminal($constants, count);
+  // TODO(jmesserly): there's no guarantee in JS that names/symbols are
+  // returned in the same order.
+  //
+  // We could probably get the same order if we're judicious about
+  // initializing fields in a consistent order across all const constructors.
+  // Alternatively we need a way to sort them to make consistent.
+  //
+  // Right now we use the (name,value) pairs in sequence, which prevents
+  // an object with incorrect field values being returned, but won't
+  // canonicalize correctly if key order is different.
+  //
+  // See issue https://github.com/dart-lang/sdk/issues/30876
+  for (let i = 0; i < count; i++) {
+    let name = names[i];
+    map = $_lookupNonTerminal(map, name);
+    map = $_lookupNonTerminal(map, $obj[name]);
+  }
+  // TODO(leafp): It may be the case that the reified type
+  // is always one of the keys already used above?
+  let type = $getReifiedType($obj);
+  let value = map.get(type);
+  if (value) return value;
+  map.set(type, $obj);
+  return $obj;
+})()''');
+
+/// The global constant list table.
+/// This maps the number of elements in the list (n)
+/// to a path of length n of maps indexed by the value
+/// of the field.  The final map is indexed by the element
+/// type and contains the canonical version of the list.
+final constantLists = JS('', 'new Map()');
+
+/// Canonicalize a constant list
+constList(elements, elementType) => JS('', '''(() => {
+  let count = $elements.length;
+  let map = $_lookupNonTerminal($constantLists, count);
+  for (let i = 0; i < count; i++) {
+    map = $_lookupNonTerminal(map, elements[i]);
+  }
+  let value = map.get($elementType);
+  if (value) return value;
+
+  ${getGenericClass(JSArray)}($elementType).unmodifiable($elements);
+  map.set($elementType, elements);
+  return elements;
+})()''');
+
+constFn(x) => JS('', '() => x');
+
+/// Gets the extension symbol given a member [name].
+///
+/// This is inlined by the compiler when used with a literal string.
+extensionSymbol(String name) => JS('', 'dartx[#]', name);
+
+// The following are helpers for Object methods when the receiver
+// may be null. These should only be generated by the compiler.
+bool equals(x, y) {
+  // We handle `y == null` inside our generated operator methods, to keep this
+  // function minimal.
+  // This pattern resulted from performance testing; it found that dispatching
+  // was the fastest solution, even for primitive types.
+  return JS('!', '# == null ? # == null : #[#](#)', x, y, x,
+      extensionSymbol('_equals'), y);
+}
+
+int hashCode(obj) {
+  return obj == null ? 0 : JS('!', '#[#]', obj, extensionSymbol('hashCode'));
+}
+
+@JSExportName('toString')
+String _toString(obj) {
+  if (obj == null) return "null";
+  if (obj is String) return obj;
+  return JS('!', '#[#]()', obj, extensionSymbol('toString'));
+}
+
+/// Converts to a non-null [String], equivalent to
+/// `dart.notNull(dart.toString(obj))`.
+///
+/// This is commonly used in string interpolation.
+@notNull
+String str(obj) {
+  if (obj == null) return "null";
+  if (obj is String) return obj;
+  return _notNull(JS('!', '#[#]()', obj, extensionSymbol('toString')));
+}
+
+// TODO(jmesserly): is the argument type verified statically?
+noSuchMethod(obj, Invocation invocation) {
+  if (obj == null) defaultNoSuchMethod(obj, invocation);
+  return JS('', '#[#](#)', obj, extensionSymbol('noSuchMethod'), invocation);
+}
+
+/// The default implementation of `noSuchMethod` to match `Object.noSuchMethod`.
+defaultNoSuchMethod(obj, Invocation i) {
+  throw NoSuchMethodError.withInvocation(obj, i);
+}
+
+runtimeType(obj) {
+  return obj == null ? Null : JS('', '#[dartx.runtimeType]', obj);
+}
+
+final identityHashCode_ = JS('', 'Symbol("_identityHashCode")');
+
+/// Adapts a Dart `get iterator` into a JS `[Symbol.iterator]`.
+// TODO(jmesserly): instead of an adaptor, we could compile Dart iterators
+// natively implementing the JS iterator protocol. This would allow us to
+// optimize them a bit.
+final JsIterator = JS('', '''
+  class JsIterator {
+    constructor(dartIterator) {
+      this.dartIterator = dartIterator;
+    }
+    next() {
+      let i = this.dartIterator;
+      let done = !i.moveNext();
+      return { done: done, value: done ? void 0 : i.current };
+    }
+  }
+''');
+
+_canonicalMember(obj, name) {
+  // Private names are symbols and are already canonical.
+  if (JS('!', 'typeof # === "symbol"', name)) return name;
+
+  if (obj != null && JS<bool>('!', '#[#] != null', obj, _extensionType)) {
+    return JS('', 'dartx.#', name);
+  }
+
+  // Check for certain names that we can't use in JS
+  if (JS('!', '# == "constructor" || # == "prototype"', name, name)) {
+    JS('', '# = "+" + #', name, name);
+  }
+  return name;
+}
+
+/// Emulates the implicit "loadLibrary" function provided by a deferred library.
+///
+/// Libraries are not actually deferred in DDC, so this just returns a future
+/// that completes immediately.
+Future loadLibrary() => Future.value();
+
+/// Defines lazy statics.
+void defineLazy(to, from) {
+  for (var name in getOwnNamesAndSymbols(from)) {
+    defineLazyField(to, name, getOwnPropertyDescriptor(from, name));
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart
new file mode 100644
index 0000000..11ea1ae
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart
@@ -0,0 +1,222 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for 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 defines the association between runtime objects and
+/// runtime types.
+part of dart._runtime;
+
+/// Runtime type information.  This module defines the mapping from
+/// runtime objects to their runtime type information.  See the types
+/// module for the definition of how type information is represented.
+///
+/// There are two kinds of objects that represent "types" at runtime. A
+/// "runtime type" contains all of the data needed to implement the runtime
+/// type checking inserted by the compiler. These objects fall into four
+/// categories:
+///
+///   - Things represented by javascript primitives, such as
+///     null, numbers, booleans, strings, and symbols.  For these
+///     we map directly from the javascript type (given by typeof)
+///     to the appropriate class type from core, which serves as their
+///     rtti.
+///
+///   - Functions, which are represented by javascript functions.
+///     Representations of Dart functions always have a
+///     _runtimeType property attached to them with the appropriate
+///     rtti.
+///
+///   - Objects (instances) which are represented by instances of
+///     javascript (ES6) classes.  Their types are given by their
+///     classes, and the rtti is accessed by projecting out their
+///     constructor field.
+///
+///   - Types objects, which are represented as described in the types
+///     module.  Types always have a _runtimeType property attached to
+///     them with the appropriate rtti.  The rtti for these is always
+///     core.Type.  TODO(leafp): consider the possibility that we can
+///     reliably recognize type objects and map directly to core.Type
+///     rather than attaching this property everywhere.
+///
+/// The other kind of object representing a "type" is the instances of the
+/// dart:core Type class. These are the user visible objects you get by calling
+/// "runtimeType" on an object or using a class literal expression. These are
+/// different from the above objects, and are created by calling `wrapType()`
+/// on a runtime type.
+
+/// Tag a closure with a type.
+///
+/// `dart.fn(closure, type)` marks [closure] with the provided runtime [type].
+fn(closure, type) {
+  JS('', '#[#] = #', closure, _runtimeType, type);
+  return closure;
+}
+
+/// Tag a closure with a type that's computed lazily.
+///
+/// `dart.fn(closure, type)` marks [closure] with a getter that uses
+/// [computeType] to return the runtime type.
+///
+/// The getter/setter replaces the property with a value property, so the
+/// resulting function is compatible with [fn] and the type can be set again
+/// safely.
+lazyFn(closure, Object Function() computeType) {
+  defineAccessor(closure, _runtimeType,
+      get: () => defineValue(closure, _runtimeType, computeType()),
+      set: (value) => defineValue(closure, _runtimeType, value),
+      configurable: true);
+  return closure;
+}
+
+// TODO(vsm): How should we encode the runtime type?
+final _runtimeType = JS('', 'Symbol("_runtimeType")');
+
+final _moduleName = JS('', 'Symbol("_moduleName")');
+
+getFunctionType(obj) {
+  // TODO(vsm): Encode this properly on the function for Dart-generated code.
+  var args = JS<List>('!', 'Array(#.length).fill(#)', obj, dynamic);
+  return fnType(bottom, args, JS('', 'void 0'));
+}
+
+/// Returns the runtime representation of the type of obj.
+///
+/// The resulting object is used internally for runtime type checking. This is
+/// different from the user-visible Type object returned by calling
+/// `runtimeType` on some Dart object.
+getReifiedType(obj) {
+  switch (JS<String>('!', 'typeof #', obj)) {
+    case "object":
+      if (obj == null) return JS('', '#', Null);
+      if (JS('!', '# instanceof #', obj, Object)) {
+        return JS('', '#.constructor', obj);
+      }
+      var result = JS('', '#[#]', obj, _extensionType);
+      if (result == null) return JS('', '#', jsobject);
+      return result;
+    case "function":
+      // All Dart functions and callable classes must set _runtimeType
+      var result = JS('', '#[#]', obj, _runtimeType);
+      if (result != null) return result;
+      return JS('', '#', jsobject);
+    case "undefined":
+      return JS('', '#', Null);
+    case "number":
+      return JS('', 'Math.floor(#) == # ? # : #', obj, obj, int, double);
+    case "boolean":
+      return JS('', '#', bool);
+    case "string":
+      return JS('', '#', String);
+    case "symbol":
+    default:
+      return JS('', '#', jsobject);
+  }
+}
+
+/// Return the module name for a raw library object.
+String getModuleName(Object module) => JS('', '#[#]', module, _moduleName);
+
+final _loadedModules = JS('', 'new Map()');
+final _loadedPartMaps = JS('', 'new Map()');
+final _loadedSourceMaps = JS('', 'new Map()');
+
+List<String> getModuleNames() {
+  return JSArray<String>.of(JS('', 'Array.from(#.keys())', _loadedModules));
+}
+
+String getSourceMap(String moduleName) {
+  return JS('!', '#.get(#)', _loadedSourceMaps, moduleName);
+}
+
+/// Return all library objects in the specified module.
+getModuleLibraries(String name) {
+  var module = JS('', '#.get(#)', _loadedModules, name);
+  if (module == null) return null;
+  JS('', '#[#] = #', module, _moduleName, name);
+  return module;
+}
+
+/// Return the part map for a specific module.
+getModulePartMap(String name) => JS('', '#.get(#)', _loadedPartMaps, name);
+
+/// Track all libraries
+void trackLibraries(
+    String moduleName, Object libraries, Object parts, String sourceMap) {
+  if (parts is String) {
+    // Added for backwards compatibility.
+    // package:build_web_compilers currently invokes this without [parts]
+    // in its bootstrap code.
+    sourceMap = parts as String;
+    parts = JS('', '{}');
+  }
+  JS('', '#.set(#, #)', _loadedSourceMaps, moduleName, sourceMap);
+  JS('', '#.set(#, #)', _loadedModules, moduleName, libraries);
+  JS('', '#.set(#, #)', _loadedPartMaps, moduleName, parts);
+}
+
+List<String> _libraries;
+Map<String, Object> _libraryObjects;
+Map<String, List<String>> _parts;
+
+_computeLibraryMetadata() {
+  _libraries = [];
+  _libraryObjects = {};
+  _parts = {};
+  var modules = getModuleNames();
+  for (var name in modules) {
+    // Add libraries from each module.
+    var module = getModuleLibraries(name);
+    var libraries = getOwnPropertyNames(module).cast<String>();
+    _libraries.addAll(libraries);
+    for (var library in libraries) {
+      _libraryObjects[library] = JS('', '#.#', module, library);
+    }
+
+    // Add parts from each module.
+    var partMap = getModulePartMap(name);
+    libraries = getOwnPropertyNames(partMap).cast<String>();
+    for (var library in libraries) {
+      _parts[library] = List.from(JS('List', '#.#', partMap, library));
+    }
+  }
+}
+
+/// Returns the JS library object for a given library [uri] or
+/// undefined / null if it isn't loaded.  Top-level types and
+/// methods are available on this object.
+Object getLibrary(String uri) {
+  if (_libraryObjects == null) {
+    _computeLibraryMetadata();
+  }
+  return _libraryObjects[uri];
+}
+
+/// Returns a JSArray of library uris (e.g,
+/// ['dart:core', 'dart:_internal', ..., 'package:foo/bar.dart', ... 'main.dart'])
+/// loaded in this application.
+List<String> getLibraries() {
+  if (_libraries == null) {
+    _computeLibraryMetadata();
+  }
+  return _libraries;
+}
+
+/// Returns a JSArray of part uris for a given [libraryUri].
+/// The part uris will be relative to the [libraryUri].
+///
+/// E.g., invoking `getParts('package:intl/intl.dart')` returns (as of this
+/// writing): ```
+/// ["src/intl/bidi_formatter.dart", "src/intl/bidi_utils.dart",
+///  "src/intl/compact_number_format.dart", "src/intl/date_format.dart",
+///  "src/intl/date_format_field.dart", "src/intl/date_format_helpers.dart",
+///  "src/intl/number_format.dart"]
+/// ```
+///
+/// If [libraryUri] doesn't map to a library or maps to a library with no
+/// parts, an empty list is returned.
+List<String> getParts(String libraryUri) {
+  if (_parts == null) {
+    _computeLibraryMetadata();
+  }
+  return _parts[libraryUri] ?? [];
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
new file mode 100644
index 0000000..99e1ab9
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
@@ -0,0 +1,210 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@ReifyFunctionTypes(false)
+library dart._runtime;
+
+import 'dart:async';
+import 'dart:collection';
+
+import 'dart:_debugger' show stackTraceMapper, trackCall;
+import 'dart:_foreign_helper' show JS, JSExportName, rest, spread;
+import 'dart:_interceptors' show JSArray, jsNull, JSFunction, NativeError;
+import 'dart:_internal' as internal show Symbol;
+import 'dart:_js_helper'
+    show
+        AssertionErrorImpl,
+        BooleanConversionAssertionError,
+        CastErrorImpl,
+        DartIterator,
+        TypeErrorImpl,
+        JsLinkedHashMap,
+        ImmutableMap,
+        PrivateSymbol,
+        ReifyFunctionTypes,
+        NoReifyGeneric,
+        notNull,
+        undefined;
+
+export 'dart:_debugger' show getDynamicStats, clearDynamicStats, trackCall;
+
+part 'utils.dart';
+part 'classes.dart';
+part 'rtti.dart';
+part 'types.dart';
+part 'errors.dart';
+part 'operations.dart';
+
+// TODO(vsm): Move polyfill code to dart:html.
+// Note, native extensions are registered onto types in dart.global.
+// This polyfill needs to run before the corresponding dart:html code is run.
+final _polyfilled = JS('', 'Symbol("_polyfilled")');
+
+bool polyfill(window) => JS('', '''(() => {
+  if ($window[$_polyfilled]) return false;
+  $window[$_polyfilled] = true;
+
+  if (typeof $window.NodeList !== "undefined") {
+    // TODO(vsm): Do we still need these?
+    $window.NodeList.prototype.get = function(i) { return this[i]; };
+    $window.NamedNodeMap.prototype.get = function(i) { return this[i]; };
+    $window.DOMTokenList.prototype.get = function(i) { return this[i]; };
+    $window.HTMLCollection.prototype.get = function(i) { return this[i]; };
+
+    // Expose constructors for DOM types dart:html needs to assume are
+    // available on window.
+    if (typeof $window.PannerNode == "undefined") {
+      let audioContext;
+      if (typeof $window.AudioContext == "undefined" &&
+          (typeof $window.webkitAudioContext != "undefined")) {
+        audioContext = new $window.webkitAudioContext();
+      } else {
+        audioContext = new $window.AudioContext();
+        $window.StereoPannerNode =
+            audioContext.createStereoPanner().constructor;
+      }
+      $window.PannerNode = audioContext.createPanner().constructor;
+    }
+    if (typeof $window.AudioSourceNode == "undefined") {
+      $window.AudioSourceNode = MediaElementAudioSourceNode.__proto__;
+    }
+    if (typeof $window.FontFaceSet == "undefined") {
+      // CSS Font Loading is not supported on Edge.
+      if (typeof $window.document.fonts != "undefined") {
+        $window.FontFaceSet = $window.document.fonts.__proto__.constructor;
+      }
+    }
+    if (typeof $window.MemoryInfo == "undefined") {
+      if (typeof $window.performance.memory != "undefined") {
+        $window.MemoryInfo = $window.performance.memory.constructor;
+      }
+    }
+    if (typeof $window.Geolocation == "undefined") {
+      $window.Geolocation == $window.navigator.geolocation.constructor;
+    }
+    if (typeof $window.Animation == "undefined") {
+      let d = $window.document.createElement('div');
+      if (typeof d.animate != "undefined") {
+        $window.Animation = d.animate(d).constructor;
+      }
+    }
+    if (typeof $window.SourceBufferList == "undefined") {
+      if ('MediaSource' in $window) {
+        $window.SourceBufferList =
+          new $window.MediaSource().sourceBuffers.constructor;
+      }
+    }
+    if (typeof $window.SpeechRecognition == "undefined") {
+      $window.SpeechRecognition = $window.webkitSpeechRecognition;
+      $window.SpeechRecognitionError = $window.webkitSpeechRecognitionError;
+      $window.SpeechRecognitionEvent = $window.webkitSpeechRecognitionEvent;
+    }
+  }
+  return true;
+})()''');
+
+@JSExportName('global')
+final global_ = JS('', '''
+  function () {
+    // Find global object.
+    var globalState = (typeof window != "undefined") ? window
+      : (typeof global != "undefined") ? global
+      : (typeof self != "undefined") ? self : null;
+    if (!globalState) {
+      // Some platforms (e.g., d8) do not define any of the above.  The
+      // following is a non-CSP safe way to access the global object:
+      globalState = new Function('return this;')();
+    }
+
+    $polyfill(globalState);
+
+    // By default, stack traces cutoff at 10.  Set the limit to Infinity for
+    // better debugging.
+    if (globalState.Error) {
+      globalState.Error.stackTraceLimit = Infinity;
+    }
+
+    // These settings must be configured before the application starts so that
+    // user code runs with the correct configuration.
+    let settings = 'ddcSettings' in globalState ? globalState.ddcSettings : {};
+
+    $trackProfile(
+        'trackProfile' in settings ? settings.trackProfile : false);
+
+    return globalState;
+  }()
+''');
+
+void trackProfile(bool flag) {
+  JS('', 'dart.__trackProfile = #', flag);
+}
+
+final JsSymbol = JS('', 'Symbol');
+
+/// The prototype used for all Dart libraries.
+///
+/// This makes it easy to identify Dart library objects, and also improves
+/// performance (JS engines such as V8 tend to assume `Object.create(null)` is
+/// used for a Map, so they don't optimize it as they normally would for
+/// class-like objects).
+///
+/// The `dart.library` field is set by the compiler during SDK bootstrapping
+/// (because it is needed for dart:_runtime itself), so we don't need to
+/// initialize it here. The name `dart.library` is used because it reads nicely,
+/// for example:
+///
+///     const my_library = Object.create(dart.library);
+///
+Object libraryPrototype = JS('', 'dart.library');
+
+// TODO(vsm): Remove once this flag we've removed the ability to
+// whitelist / fallback on the old behavior.
+bool startAsyncSynchronously = true;
+void setStartAsyncSynchronously([bool value = true]) {
+  startAsyncSynchronously = value;
+}
+
+/// A list of all JS Maps used for caching results, such as by [isSubtypeOf] and
+/// [generic].
+///
+/// This is used by [hotRestart] to ensure we don't leak types from previous
+/// libraries.
+@notNull
+final List<Object> _cacheMaps = JS('!', '[]');
+
+/// A list of functions to reset static fields back to their uninitialized
+/// state.
+///
+/// This is populated by [defineLazyField], and only contains the list of fields
+/// that have actually been initialized.
+@notNull
+final List<void Function()> _resetFields = JS('', '[]');
+
+/// Clears out runtime state in `dartdevc` so we can hot-restart.
+///
+/// This should be called when the user requests a hot-restart, when the UI is
+/// handling that user action.
+void hotRestart() {
+  // TODO(jmesserly): we need to prevent all pending callbacks from firing.
+  for (var f in _resetFields) f();
+  _resetFields.clear();
+  for (var m in _cacheMaps) JS('', '#.clear()', m);
+  _cacheMaps.clear();
+  JS('', '#.clear()', constantMaps);
+}
+
+/// Marks enqueuing an async operation.
+///
+/// This will be called by library code when enqueuing an async operation
+/// controlled by the JavaScript event handler.
+///
+/// It will also call [removeAsyncCallback] when Dart callback is about to be
+/// executed (note this is called *before* the callback executes, so more
+/// async operations could be added from that).
+void Function() addAsyncCallback = JS('', 'function() {}');
+
+/// Marks leaving a javascript async operation.
+///
+/// See [addAsyncCallback].
+void Function() removeAsyncCallback = JS('', 'function() {}');
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
new file mode 100644
index 0000000..3175eeb
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -0,0 +1,1438 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for 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 defines the representation of runtime types.
+part of dart._runtime;
+
+final metadata = JS('', 'Symbol("metadata")');
+
+/// Types in dart are represented internally at runtime as follows.
+///
+///   - Normal nominal types, produced from classes, are represented
+///     at runtime by the JS class of which they are an instance.
+///     If the type is the result of instantiating a generic class,
+///     then the "classes" module manages the association between the
+///     instantiated class and the original class declaration
+///     and the type arguments with which it was instantiated.  This
+///     association can be queried via the "classes" module".
+///
+///   - All other types are represented as instances of class [DartType],
+///     defined in this module.
+///     - Dynamic, Void, and Bottom are singleton instances of sentinal
+///       classes.
+///     - Function types are instances of subclasses of AbstractFunctionType.
+///
+/// Function types are represented in one of two ways:
+///   - As an instance of FunctionType.  These are eagerly computed.
+///   - As an instance of TypeDef.  The TypeDef representation lazily
+///     computes an instance of FunctionType, and delegates to that instance.
+///
+/// These above "runtime types" are what is used for implementing DDC's
+/// internal type checks. These objects are distinct from the objects exposed
+/// to user code by class literals and calling `Object.runtimeType`. In DDC,
+/// the latter are represented by instances of WrappedType which contain a
+/// real runtime type internally. This ensures that the returned object only
+/// exposes the API that Type defines:
+///
+///     get String name;
+///     String toString();
+///
+/// These "runtime types" have methods for performing type checks. The methods
+/// have the following JavaScript names which are designed to not collide with
+/// static methods, which are also placed 'on' the class constructor function.
+///
+///     T.is(o): Implements 'o is T'.
+///     T.as(o): Implements 'o as T'.
+///     T._check(o): Implements the type assertion of 'T x = o;'
+///
+/// By convention, we used named JavaScript functions for these methods with the
+/// name 'is_X', 'as_X' and 'check_X' for various X to indicate the type or the
+/// implementation strategy for the test (e.g 'is_String', 'is_G' for generic
+/// types, etc.)
+// TODO(jmesserly): we shouldn't implement Type here. It should be moved down
+// to AbstractFunctionType.
+class DartType implements Type {
+  String get name => this.toString();
+
+  // TODO(jmesserly): these should never be reached, can be make them abstract?
+  @notNull
+  @JSExportName('is')
+  bool is_T(object) => instanceOf(object, this);
+
+  @JSExportName('as')
+  as_T(object) => cast(object, this, false);
+
+  @JSExportName('_check')
+  check_T(object) => cast(object, this, true);
+}
+
+class DynamicType extends DartType {
+  toString() => 'dynamic';
+
+  @JSExportName('is')
+  bool is_T(object) => true;
+
+  @JSExportName('as')
+  as_T(object) => object;
+
+  @JSExportName('_check')
+  check_T(object) => object;
+}
+
+@notNull
+bool _isJsObject(obj) => JS('!', '# === #', getReifiedType(obj), jsobject);
+
+/// Asserts that [f] is a native JS functions and returns it if so.
+/// This function should be used to ensure that a function is a native
+/// JS functions in contexts that expect that.
+F assertInterop<F extends Function>(F f) {
+  // TODO(vsm): Throw a more specific error if this fails.
+  assert(_isJsObject(f));
+  return f;
+}
+
+/// The Dart type that represents a JavaScript class(/constructor) type.
+///
+/// The JavaScript type may not exist, either because it's not loaded yet, or
+/// because it's not available (such as with mocks). To handle this gracefully,
+/// we disable type checks for in these cases, and allow any JS object to work
+/// as if it were an instance of this JS type.
+class LazyJSType extends DartType {
+  Function() _getRawJSTypeFn;
+  @notNull
+  final String _dartName;
+  Object _rawJSType;
+
+  LazyJSType(this._getRawJSTypeFn, this._dartName);
+
+  toString() {
+    var raw = _getRawJSType();
+    return raw != null ? typeName(raw) : "JSObject<$_dartName>";
+  }
+
+  Object _getRawJSType() {
+    var raw = _rawJSType;
+    if (raw != null) return raw;
+
+    // Try to evaluate the JS type. If this fails for any reason, we'll try
+    // again next time.
+    // TODO(jmesserly): is it worth trying again? It may create unnecessary
+    // overhead, especially if exceptions are being thrown. Also it means the
+    // behavior of a given type check can change later on.
+    try {
+      raw = _getRawJSTypeFn();
+    } catch (e) {}
+
+    if (raw == null) {
+      _warn('Cannot find native JavaScript type ($_dartName) for type check');
+    } else {
+      _rawJSType = raw;
+      _getRawJSTypeFn = null; // Free the function that computes the JS type.
+    }
+    return raw;
+  }
+
+  Object rawJSTypeForCheck() => _getRawJSType() ?? jsobject;
+
+  @notNull
+  bool isRawJSType(obj) {
+    var raw = _getRawJSType();
+    if (raw != null) return JS('!', '# instanceof #', obj, raw);
+    return _isJsObject(obj);
+  }
+
+  @notNull
+  @JSExportName('is')
+  bool is_T(obj) => isRawJSType(obj) || instanceOf(obj, this);
+
+  @JSExportName('as')
+  as_T(obj) => obj == null || is_T(obj) ? obj : castError(obj, this, false);
+
+  @JSExportName('_check')
+  check_T(obj) => obj == null || is_T(obj) ? obj : castError(obj, this, true);
+}
+
+/// An anonymous JS type
+///
+/// For the purposes of subtype checks, these match any JS type.
+class AnonymousJSType extends DartType {
+  final String _dartName;
+  AnonymousJSType(this._dartName);
+  toString() => _dartName;
+
+  @JSExportName('is')
+  bool is_T(obj) => _isJsObject(obj) || instanceOf(obj, this);
+
+  @JSExportName('as')
+  as_T(obj) => obj == null || _isJsObject(obj) ? obj : cast(obj, this, false);
+
+  @JSExportName('_check')
+  check_T(obj) => obj == null || _isJsObject(obj) ? obj : cast(obj, this, true);
+}
+
+void _warn(arg) {
+  JS('void', 'console.warn(#)', arg);
+}
+
+var _lazyJSTypes = JS('', 'new Map()');
+var _anonymousJSTypes = JS('', 'new Map()');
+
+lazyJSType(Function() getJSTypeCallback, String name) {
+  var ret = JS('', '#.get(#)', _lazyJSTypes, name);
+  if (ret == null) {
+    ret = LazyJSType(getJSTypeCallback, name);
+    JS('', '#.set(#, #)', _lazyJSTypes, name, ret);
+  }
+  return ret;
+}
+
+anonymousJSType(String name) {
+  var ret = JS('', '#.get(#)', _anonymousJSTypes, name);
+  if (ret == null) {
+    ret = AnonymousJSType(name);
+    JS('', '#.set(#, #)', _anonymousJSTypes, name, ret);
+  }
+  return ret;
+}
+
+@JSExportName('dynamic')
+final _dynamic = DynamicType();
+
+class VoidType extends DartType {
+  toString() => 'void';
+}
+
+@JSExportName('void')
+final void_ = VoidType();
+
+class BottomType extends DartType {
+  toString() => 'bottom';
+}
+
+// TODO(vsm): We reify bottom as Null.  We will revisit this with
+// non-nullable types.
+final bottom = unwrapType(Null);
+
+class JSObjectType extends DartType {
+  toString() => 'NativeJavaScriptObject';
+}
+
+final jsobject = JSObjectType();
+
+/// Dev Compiler's implementation of Type, wrapping its internal [_type].
+class _Type extends Type {
+  /// The internal type representation, either a [DartType] or class constructor
+  /// function.
+  // TODO(jmesserly): introduce InterfaceType so we don't have to special case
+  // classes
+  @notNull
+  final Object _type;
+
+  _Type(this._type);
+
+  toString() => typeName(_type);
+
+  Type get runtimeType => Type;
+}
+
+/// Given an internal runtime type object, wraps it in a `_Type` object
+/// that implements the dart:core Type interface.
+Type wrapType(type) {
+  // If we've already wrapped this type once, use the previous wrapper. This
+  // way, multiple references to the same type return an identical Type.
+  if (JS('!', '#.hasOwnProperty(#)', type, _typeObject)) {
+    return JS('', '#[#]', type, _typeObject);
+  }
+  var result = _Type(type);
+  JS('', '#[#] = #', type, _typeObject, result);
+  return result;
+}
+
+/// The symbol used to store the cached `Type` object associated with a class.
+final _typeObject = JS('', 'Symbol("typeObject")');
+
+/// Given a WrappedType, return the internal runtime type object.
+Object unwrapType(Type obj) => JS<_Type>('', '#', obj)._type;
+
+// Marker class for generic functions, typedefs, and non-generic functions.
+abstract class AbstractFunctionType extends DartType {}
+
+/// Memo table for named argument groups. A named argument packet
+/// {name1 : type1, ..., namen : typen} corresponds to the path
+/// n, name1, type1, ...., namen, typen.  The element of the map
+/// reached via this path (if any) is the canonical representative
+/// for this packet.
+final _fnTypeNamedArgMap = JS('', 'new Map()');
+
+/// Memo table for positional argument groups. A positional argument
+/// packet [type1, ..., typen] (required or optional) corresponds to
+/// the path n, type1, ...., typen.  The element reached via
+/// this path (if any) is the canonical representative for this
+/// packet. Note that required and optional parameters packages
+/// may have the same canonical representation.
+final _fnTypeArrayArgMap = JS('', 'new Map()');
+
+/// Memo table for function types. The index path consists of the
+/// path length - 1, the returnType, the canonical positional argument
+/// packet, and if present, the canonical optional or named argument
+/// packet.  A level of indirection could be avoided here if desired.
+final _fnTypeTypeMap = JS('', 'new Map()');
+
+/// Memo table for small function types with no optional or named
+/// arguments and less than a fixed n (currently 3) number of
+/// required arguments.  Indexing into this table by the number
+/// of required arguments yields a map which is indexed by the
+/// argument types themselves.  The element reached via this
+/// index path (if present) is the canonical function type.
+final List _fnTypeSmallMap = JS('', '[new Map(), new Map(), new Map()]');
+
+@NoReifyGeneric()
+T _memoizeArray<T>(map, arr, T create()) => JS('', '''(() => {
+  let len = $arr.length;
+  $map = $_lookupNonTerminal($map, len);
+  for (var i = 0; i < len-1; ++i) {
+    $map = $_lookupNonTerminal($map, $arr[i]);
+  }
+  let result = $map.get($arr[len-1]);
+  if (result !== void 0) return result;
+  $map.set($arr[len-1], result = $create());
+  return result;
+})()''');
+
+List _canonicalizeArray(List array, map) =>
+    _memoizeArray(map, array, () => array);
+
+// TODO(leafp): This only canonicalizes of the names are
+// emitted in a consistent order.
+_canonicalizeNamed(named, map) => JS('', '''(() => {
+  let key = [];
+  let names = $getOwnPropertyNames($named);
+  for (var i = 0; i < names.length; ++i) {
+    let name = names[i];
+    let type = $named[name];
+    key.push(name);
+    key.push(type);
+  }
+  return $_memoizeArray($map, key, () => $named);
+})()''');
+
+// TODO(leafp): This handles some low hanging fruit, but
+// really we should make all of this faster, and also
+// handle more cases here.
+FunctionType _createSmall(returnType, List required) => JS('', '''(() => {
+  let count = $required.length;
+  let map = $_fnTypeSmallMap[count];
+  for (var i = 0; i < count; ++i) {
+    map = $_lookupNonTerminal(map, $required[i]);
+ }
+ let result = map.get($returnType);
+ if (result !== void 0) return result;
+ result = ${new FunctionType(returnType, required, [], JS('', '{}'))};
+ map.set($returnType, result);
+ return result;
+})()''');
+
+class FunctionType extends AbstractFunctionType {
+  final Type returnType;
+  List args;
+  List optionals;
+  // Named arguments native JS Object of the form { namedArgName: namedArgType }
+  final named;
+  // TODO(vsm): This is just parameter metadata for now.
+  // Suspected but not confirmed: Only used by mirrors for pageloader2 support.
+  // The metadata is represented as a list of JS arrays, one for each argument
+  // that contains the annotations for that argument or an empty array if there
+  // are no annotations.
+  List metadata = [];
+  String _stringValue;
+
+  /// Construct a function type.
+  ///
+  /// We eagerly normalize the argument types to avoid having to deal with this
+  /// logic in multiple places.
+  ///
+  /// This code does best effort canonicalization.  It does not guarantee that
+  /// all instances will share.
+  ///
+  /// Note: Generic function subtype checks assume types have been canonicalized
+  /// when testing if type bounds are equal.
+  static FunctionType create(returnType, List args, extra) {
+    // Note that if extra is ever passed as an empty array
+    // or an empty map, we can end up with semantically
+    // identical function types that don't canonicalize
+    // to the same object since we won't fall into this
+    // fast path.
+    if (extra == null && JS<bool>('!', '#.length < 3', args)) {
+      return _createSmall(returnType, args);
+    }
+    args = _canonicalizeArray(args, _fnTypeArrayArgMap);
+    var keys;
+    FunctionType Function() create;
+    if (extra == null) {
+      keys = [returnType, args];
+      create = () => FunctionType(returnType, args, [], JS('', '{}'));
+    } else if (JS('!', '# instanceof Array', extra)) {
+      var optionals =
+          _canonicalizeArray(JS('', '#', extra), _fnTypeArrayArgMap);
+      keys = [returnType, args, optionals];
+      create = () => FunctionType(returnType, args, optionals, JS('', '{}'));
+    } else {
+      var named = _canonicalizeNamed(extra, _fnTypeNamedArgMap);
+      keys = [returnType, args, named];
+      create = () => FunctionType(returnType, args, [], named);
+    }
+    return _memoizeArray(_fnTypeTypeMap, keys, create);
+  }
+
+  /// Returns the function arguments.
+  ///
+  /// If an argument is provided with annotations (encoded as a JS array where
+  /// the first element is the argument, and the rest are annotations) the
+  /// annotations are extracted and saved in [metadata].
+  List _process(List array) {
+    var result = [];
+    for (var i = 0; JS<bool>('!', '# < #.length', i, array); ++i) {
+      var arg = JS('', '#[#]', array, i);
+      if (JS('!', '# instanceof Array', arg)) {
+        JS('', '#.push(#.slice(1))', metadata, arg);
+        JS('', '#.push(#[0])', result, arg);
+      } else {
+        JS('', '#.push([])', metadata);
+        JS('', '#.push(#)', result, arg);
+      }
+    }
+    return result;
+  }
+
+  FunctionType(this.returnType, this.args, this.optionals, this.named) {
+    this.args = _process(this.args);
+    this.optionals = _process(this.optionals);
+    // TODO(vsm): Named arguments were never used by pageloader2 so they were
+    // never processed here.
+  }
+
+  toString() => name;
+
+  int get requiredParameterCount => args.length;
+  int get positionalParameterCount => args.length + optionals.length;
+
+  getPositionalParameter(int i) {
+    int n = args.length;
+    return i < n ? args[i] : optionals[i + n];
+  }
+
+  Map<String, Object> getNamedParameters() {
+    var result = <String, Object>{};
+    var names = getOwnPropertyNames(named);
+    JS('', '#.sort()', names);
+    for (var i = 0; JS<bool>('!', '# < #.length', i, names); ++i) {
+      String name = JS('!', '#[#]', names, i);
+      result[name] = JS('', '#[#]', named, name);
+    }
+    return result;
+  }
+
+  get name {
+    if (_stringValue != null) return _stringValue;
+
+    var buffer = '(';
+    for (var i = 0; JS<bool>('!', '# < #.length', i, args); ++i) {
+      if (i > 0) {
+        buffer += ', ';
+      }
+      buffer += typeName(JS('', '#[#]', args, i));
+    }
+    if (JS('!', '#.length > 0', optionals)) {
+      if (JS('!', '#.length > 0', args)) buffer += ', ';
+      buffer += '[';
+      for (var i = 0; JS<bool>('!', '# < #.length', i, optionals); ++i) {
+        if (i > 0) {
+          buffer += ', ';
+        }
+        buffer += typeName(JS('', '#[#]', optionals, i));
+      }
+      buffer += ']';
+    } else if (JS('!', 'Object.keys(#).length > 0', named)) {
+      if (JS('!', '#.length > 0', args)) buffer += ', ';
+      buffer += '{';
+      var names = getOwnPropertyNames(named);
+      JS('', '#.sort()', names);
+      for (var i = 0; JS<bool>('!', '# < #.length', i, names); ++i) {
+        if (i > 0) {
+          buffer += ', ';
+        }
+        var typeNameString = typeName(JS('', '#[#[#]]', named, names, i));
+        buffer += '$typeNameString ${JS('', '#[#]', names, i)}';
+      }
+      buffer += '}';
+    }
+
+    var returnTypeName = typeName(returnType);
+    buffer += ') => $returnTypeName';
+    _stringValue = buffer;
+    return buffer;
+  }
+
+  @JSExportName('is')
+  bool is_T(obj) {
+    if (JS('!', 'typeof # == "function"', obj)) {
+      var actual = JS('', '#[#]', obj, _runtimeType);
+      // If there's no actual type, it's a JS function.
+      // Allow them to subtype all Dart function types.
+      return actual == null || isSubtypeOf(actual, this);
+    }
+    return false;
+  }
+
+  @JSExportName('as')
+  as_T(obj, [@notNull bool isImplicit = false]) {
+    if (obj == null) return obj;
+    if (JS('!', 'typeof # == "function"', obj)) {
+      var actual = JS('', '#[#]', obj, _runtimeType);
+      // If there's no actual type, it's a JS function.
+      // Allow them to subtype all Dart function types.
+      if (actual == null || isSubtypeOf(actual, this)) {
+        return obj;
+      }
+    }
+    return castError(obj, this, isImplicit);
+  }
+
+  @JSExportName('_check')
+  check_T(obj) => as_T(obj, true);
+}
+
+/// A type variable, used by [GenericFunctionType] to represent a type formal.
+class TypeVariable extends DartType {
+  final String name;
+
+  TypeVariable(this.name);
+
+  toString() => name;
+}
+
+class GenericFunctionType extends AbstractFunctionType {
+  final _instantiateTypeParts;
+  final int formalCount;
+  final _instantiateTypeBounds;
+  List<TypeVariable> _typeFormals;
+
+  GenericFunctionType(instantiateTypeParts, this._instantiateTypeBounds)
+      : _instantiateTypeParts = instantiateTypeParts,
+        formalCount = JS('!', '#.length', instantiateTypeParts);
+
+  List<TypeVariable> get typeFormals {
+    if (_typeFormals != null) return _typeFormals;
+    return _typeFormals = _typeFormalsFromFunction(_instantiateTypeParts);
+  }
+
+  /// `true` if there are bounds on any of the generic type parameters.
+  get hasTypeBounds => _instantiateTypeBounds != null;
+
+  /// Checks that [typeArgs] satisfies the upper bounds of the [typeFormals],
+  /// and throws a [TypeError] if they do not.
+  void checkBounds(List typeArgs) {
+    // If we don't have explicit type parameter bounds, the bounds default to
+    // a top type, so there's nothing to check here.
+    if (!hasTypeBounds) return;
+
+    var bounds = instantiateTypeBounds(typeArgs);
+    var typeFormals = this.typeFormals;
+    for (var i = 0; i < typeArgs.length; i++) {
+      checkTypeBound(typeArgs[i], bounds[i], typeFormals[i].name);
+    }
+  }
+
+  FunctionType instantiate(typeArgs) {
+    var parts = JS('', '#.apply(null, #)', _instantiateTypeParts, typeArgs);
+    return FunctionType.create(
+        JS('', '#[0]', parts), JS('', '#[1]', parts), JS('', '#[2]', parts));
+  }
+
+  List instantiateTypeBounds(List typeArgs) {
+    if (!hasTypeBounds) {
+      // The Dart 1 spec says omitted type parameters have an upper bound of
+      // Object. However Dart 2 uses `dynamic` for the purpose of instantiate to
+      // bounds, so we use that here.
+      return List.filled(formalCount, _dynamic);
+    }
+    // Bounds can be recursive or depend on other type parameters, so we need to
+    // apply type arguments and return the resulting bounds.
+    return JS('List', '#.apply(null, #)', _instantiateTypeBounds, typeArgs);
+  }
+
+  toString() {
+    String s = "<";
+    var typeFormals = this.typeFormals;
+    var typeBounds = instantiateTypeBounds(typeFormals);
+    for (int i = 0, n = typeFormals.length; i < n; i++) {
+      if (i != 0) s += ", ";
+      s += JS<String>('!', '#[#].name', typeFormals, i);
+      var bound = typeBounds[i];
+      if (JS('!', '# !== # && # !== #', bound, dynamic, bound, Object)) {
+        s += " extends $bound";
+      }
+    }
+    s += ">" + instantiate(typeFormals).toString();
+    return s;
+  }
+
+  /// Given a [DartType] [type], if [type] is an uninstantiated
+  /// parameterized type then instantiate the parameters to their
+  /// bounds and return those type arguments.
+  ///
+  /// See the issue for the algorithm description:
+  /// <https://github.com/dart-lang/sdk/issues/27526#issuecomment-260021397>
+  List instantiateDefaultBounds() {
+    var typeFormals = this.typeFormals;
+
+    // All type formals
+    var all = HashMap<Object, int>.identity();
+    // ground types, by index.
+    //
+    // For each index, this will be a ground type for the corresponding type
+    // formal if known, or it will be the original TypeVariable if we are still
+    // solving for it. This array is passed to `instantiateToBounds` as we are
+    // progressively solving for type variables.
+    var defaults = List<Object>(typeFormals.length);
+    // not ground
+    var partials = Map<TypeVariable, Object>.identity();
+
+    var typeBounds = this.instantiateTypeBounds(typeFormals);
+    for (var i = 0; i < typeFormals.length; i++) {
+      var typeFormal = typeFormals[i];
+      var bound = typeBounds[i];
+      all[typeFormal] = i;
+      if (identical(bound, _dynamic)) {
+        defaults[i] = bound;
+      } else {
+        defaults[i] = typeFormal;
+        partials[typeFormal] = bound;
+      }
+    }
+
+    bool hasFreeFormal(Object t) {
+      if (partials.containsKey(t)) return true;
+
+      // Generic classes and typedefs.
+      var typeArgs = getGenericArgs(t);
+      if (typeArgs != null) return typeArgs.any(hasFreeFormal);
+
+      if (t is GenericFunctionType) {
+        return hasFreeFormal(t.instantiate(t.typeFormals));
+      }
+
+      if (t is FunctionType) {
+        return hasFreeFormal(t.returnType) || t.args.any(hasFreeFormal);
+      }
+
+      return false;
+    }
+
+    var hasProgress = true;
+    while (hasProgress) {
+      hasProgress = false;
+      for (var typeFormal in partials.keys) {
+        var partialBound = partials[typeFormal];
+        if (!hasFreeFormal(partialBound)) {
+          int index = all[typeFormal];
+          defaults[index] = instantiateTypeBounds(defaults)[index];
+          partials.remove(typeFormal);
+          hasProgress = true;
+          break;
+        }
+      }
+    }
+
+    // If we stopped making progress, and not all types are ground,
+    // then the whole type is malbounded and an error should be reported
+    // if errors are requested, and a partially completed type should
+    // be returned.
+    if (partials.isNotEmpty) {
+      throwTypeError('Instantiate to bounds failed for type with '
+          'recursive generic bounds: ${typeName(this)}. '
+          'Try passing explicit type arguments.');
+    }
+    return defaults;
+  }
+
+  @notNull
+  @JSExportName('is')
+  bool is_T(obj) {
+    if (JS('!', 'typeof # == "function"', obj)) {
+      var actual = JS('', '#[#]', obj, _runtimeType);
+      return actual != null && isSubtypeOf(actual, this);
+    }
+    return false;
+  }
+
+  @JSExportName('as')
+  as_T(obj) {
+    if (obj == null || is_T(obj)) return obj;
+    return castError(obj, this, false);
+  }
+
+  @JSExportName('_check')
+  check_T(obj) {
+    if (obj == null || is_T(obj)) return obj;
+    return castError(obj, this, true);
+  }
+}
+
+List<TypeVariable> _typeFormalsFromFunction(Object typeConstructor) {
+  // Extract parameter names from the function parameters.
+  //
+  // This is not robust in general for user-defined JS functions, but it
+  // should handle the functions generated by our compiler.
+  //
+  // TODO(jmesserly): names of TypeVariables are only used for display
+  // purposes, such as when an error happens or if someone calls
+  // `Type.toString()`. So we could recover them lazily rather than eagerly.
+  // Alternatively we could synthesize new names.
+  String str = JS('!', '#.toString()', typeConstructor);
+  var hasParens = str[0] == '(';
+  var end = str.indexOf(hasParens ? ')' : '=>');
+  if (hasParens) {
+    return str
+        .substring(1, end)
+        .split(',')
+        .map((n) => TypeVariable(n.trim()))
+        .toList();
+  } else {
+    return [TypeVariable(str.substring(0, end).trim())];
+  }
+}
+
+/// Create a function type.
+FunctionType fnType(returnType, List args, [@undefined extra]) =>
+    FunctionType.create(returnType, args, extra);
+
+/// Creates a generic function type from [instantiateFn] and [typeBounds].
+///
+/// A function type consists of two things:
+/// * An instantiate function that takes type arguments and returns the
+///   function signature in the form of a two element list. The first element
+///   is the return type. The second element is a list of the argument types.
+/// * A function that returns a list of upper bound constraints for each of
+///   the type formals.
+///
+/// Both functions accept the type parameters, allowing us to substitute values.
+/// The upper bound constraints can be omitted if all of the type parameters use
+/// the default upper bound.
+///
+/// For example given the type <T extends Iterable<T>>(T) -> T, we can declare
+/// this type with `gFnType(T => [T, [T]], T => [Iterable$(T)])`.
+gFnType(instantiateFn, typeBounds) =>
+    GenericFunctionType(instantiateFn, typeBounds);
+
+/// TODO(vsm): Remove when mirrors is deprecated.
+/// This is a temporary workaround to support dart:mirrors, which doesn't
+/// understand generic methods.
+getFunctionTypeMirror(AbstractFunctionType type) {
+  if (type is GenericFunctionType) {
+    var typeArgs = List.filled(type.formalCount, dynamic);
+    return type.instantiate(typeArgs);
+  }
+  return type;
+}
+
+/// Whether the given JS constructor [obj] is a Dart class type.
+@notNull
+bool isType(obj) => JS('', '#[#] === #', obj, _runtimeType, Type);
+
+void checkTypeBound(
+    @notNull Object type, @notNull Object bound, @notNull String name) {
+  if (!isSubtypeOf(type, bound)) {
+    throwTypeError('type `$type` does not extend `$bound` of `$name`.');
+  }
+}
+
+@notNull
+String typeName(type) => JS('', '''(() => {
+  if ($type === void 0) return "undefined type";
+  if ($type === null) return "null type";
+  // Non-instance types
+  if ($type instanceof $DartType) {
+    return $type.toString();
+  }
+
+  // Instance types
+  let tag = $type[$_runtimeType];
+  if (tag === $Type) {
+    let name = $type.name;
+    let args = ${getGenericArgs(type)};
+    if (args == null) return name;
+
+    if (${getGenericClass(type)} == ${getGenericClass(JSArray)}) name = 'List';
+
+    let result = name;
+    result += '<';
+    for (let i = 0; i < args.length; ++i) {
+      if (i > 0) result += ', ';
+      result += $typeName(args[i]);
+    }
+    result += '>';
+    return result;
+  }
+  if (tag) return "Not a type: " + tag.name;
+  return "JSObject<" + $type.name + ">";
+})()''');
+
+/// Returns true if [ft1] <: [ft2].
+_isFunctionSubtype(ft1, ft2) => JS('', '''(() => {
+  let ret1 = $ft1.returnType;
+  let ret2 = $ft2.returnType;
+
+  let args1 = $ft1.args;
+  let args2 = $ft2.args;
+
+  if (args1.length > args2.length) {
+    return false;
+  }
+
+  for (let i = 0; i < args1.length; ++i) {
+    if (!$_isSubtype(args2[i], args1[i])) {
+      return false;
+    }
+  }
+
+  let optionals1 = $ft1.optionals;
+  let optionals2 = $ft2.optionals;
+
+  if (args1.length + optionals1.length < args2.length + optionals2.length) {
+    return false;
+  }
+
+  let j = 0;
+  for (let i = args1.length; i < args2.length; ++i, ++j) {
+    if (!$_isSubtype(args2[i], optionals1[j])) {
+      return false;
+    }
+  }
+
+  for (let i = 0; i < optionals2.length; ++i, ++j) {
+    if (!$_isSubtype(optionals2[i], optionals1[j])) {
+      return false;
+    }
+  }
+
+  let named1 = $ft1.named;
+  let named2 = $ft2.named;
+
+  let names = $getOwnPropertyNames(named2);
+  for (let i = 0; i < names.length; ++i) {
+    let name = names[i];
+    let n1 = named1[name];
+    let n2 = named2[name];
+    if (n1 === void 0) {
+      return false;
+    }
+    if (!$_isSubtype(n2, n1)) {
+      return false;
+    }
+  }
+
+  return $_isSubtype(ret1, ret2);
+})()''');
+
+/// Returns true if [t1] <: [t2].
+@notNull
+bool isSubtypeOf(Object t1, Object t2) {
+  // TODO(jmesserly): we've optimized `is`/`as`/implicit type checks, so they're
+  // dispatched on the type. Can we optimize the subtype relation too?
+  Object map;
+  if (JS('!', '!#.hasOwnProperty(#)', t1, _subtypeCache)) {
+    JS('', '#[#] = # = new Map()', t1, _subtypeCache, map);
+    _cacheMaps.add(map);
+  } else {
+    map = JS('', '#[#]', t1, _subtypeCache);
+    bool result = JS('', '#.get(#)', map, t2);
+    if (JS('!', '# !== void 0', result)) return result;
+  }
+  var result = _isSubtype(t1, t2);
+  JS('', '#.set(#, #)', map, t2, result);
+  return result;
+}
+
+final _subtypeCache = JS('', 'Symbol("_subtypeCache")');
+
+@notNull
+bool _isBottom(type) => JS('!', '# == # || # == #', type, bottom, type, Null);
+
+@notNull
+bool _isTop(type) {
+  if (_isFutureOr(type)) {
+    return _isTop(JS('', '#[0]', getGenericArgs(type)));
+  }
+  return JS('!', '# == # || # == # || # == #', type, Object, type, dynamic,
+      type, void_);
+}
+
+@notNull
+bool _isFutureOr(type) =>
+    identical(getGenericClass(type), getGenericClass(FutureOr));
+
+bool _isSubtype(t1, t2) => JS('', '''(() => {
+  if ($t1 === $t2) {
+    return true;
+  }
+
+  // Trivially true.
+  if (${_isTop(t2)} || ${_isBottom(t1)}) {
+    return true;
+  }
+
+  // Trivially false.
+  if (${_isTop(t1)} || ${_isBottom(t2)}) {
+    return false;
+  }
+
+  // Handle FutureOr<T> union type.
+  if (${_isFutureOr(t1)}) {
+    let t1TypeArg = ${getGenericArgs(t1)}[0];
+    if (${_isFutureOr(t2)}) {
+      let t2TypeArg = ${getGenericArgs(t2)}[0];
+      // FutureOr<A> <: FutureOr<B> iff A <: B
+      return $_isSubtype(t1TypeArg, t2TypeArg);
+    }
+
+    // given t1 is Future<A> | A, then:
+    // (Future<A> | A) <: t2 iff Future<A> <: t2 and A <: t2.
+    let t1Future = ${getGenericClass(Future)}(t1TypeArg);
+    // Known to handle the case FutureOr<Null> <: Future<Null>.
+    return $_isSubtype(t1Future, $t2) && $_isSubtype(t1TypeArg, $t2);
+  }
+
+  if ($_isFutureOr($t2)) {
+    // given t2 is Future<A> | A, then:
+    // t1 <: (Future<A> | A) iff t1 <: Future<A> or t1 <: A
+    let t2TypeArg = ${getGenericArgs(t2)}[0];
+    let t2Future = ${getGenericClass(Future)}(t2TypeArg);
+    return $_isSubtype($t1, t2Future) || $_isSubtype($t1, t2TypeArg);
+  }
+
+  // "Traditional" name-based subtype check.  Avoid passing
+  // function types to the class subtype checks, since we don't
+  // currently distinguish between generic typedefs and classes.
+  if (!($t2 instanceof $AbstractFunctionType)) {
+    // t2 is an interface type.
+
+    if ($t1 instanceof $AbstractFunctionType) {
+      // Function types are only subtypes of interface types `Function` (and top
+      // types, handled already above).
+      return $t2 === $Function;
+    }
+
+    // All JS types are subtypes of anonymous JS types.
+    if ($t1 === $jsobject && $t2 instanceof $AnonymousJSType) {
+      return true;
+    }
+
+    // Compare two interface types.
+    return ${_isInterfaceSubtype(t1, t2)};
+  }
+
+  // Function subtyping.
+  if (!($t1 instanceof $AbstractFunctionType)) {
+    return false;
+  }
+
+  // Handle generic functions.
+  if ($t1 instanceof $GenericFunctionType) {
+    if (!($t2 instanceof $GenericFunctionType)) {
+      return false;
+    }
+
+    // Given generic functions g1 and g2, g1 <: g2 iff:
+    //
+    //     g1<TFresh> <: g2<TFresh>
+    //
+    // where TFresh is a list of fresh type variables that both g1 and g2 will
+    // be instantiated with.
+    let formalCount = $t1.formalCount;
+    if (formalCount !== $t2.formalCount) {
+      return false;
+    }
+
+    // Using either function's type formals will work as long as they're both
+    // instantiated with the same ones. The instantiate operation is guaranteed
+    // to avoid capture because it does not depend on its TypeVariable objects,
+    // rather it uses JS function parameters to ensure correct binding.
+    let fresh = $t2.typeFormals;
+
+    // Without type bounds all will instantiate to dynamic. Only need to check
+    // further if at least one of the functions has type bounds.
+    if ($t1.hasTypeBounds || $t2.hasTypeBounds) {
+      // Check the bounds of the type parameters of g1 and g2.
+      // given a type parameter `T1 extends U1` from g1, and a type parameter
+      // `T2 extends U2` from g2, we must ensure that:
+      //
+      //      U2 == U1
+      //
+      // (Note there is no variance in the type bounds of type parameters of
+      // generic functions).
+      let t1Bounds = $t1.instantiateTypeBounds(fresh);
+      let t2Bounds = $t2.instantiateTypeBounds(fresh);
+      for (let i = 0; i < formalCount; i++) {
+        if (t2Bounds[i] != t1Bounds[i]) {
+          return false;
+        }
+      }
+    }
+
+    $t1 = $t1.instantiate(fresh);
+    $t2 = $t2.instantiate(fresh);
+  } else if ($t2 instanceof $GenericFunctionType) {
+    return false;
+  }
+
+  // Handle non-generic functions.
+  return ${_isFunctionSubtype(t1, t2)};
+})()''');
+
+bool _isInterfaceSubtype(t1, t2) => JS('', '''(() => {
+  // If we have lazy JS types, unwrap them.  This will effectively
+  // reduce to a prototype check below.
+  if ($t1 instanceof $LazyJSType) $t1 = $t1.rawJSTypeForCheck();
+  if ($t2 instanceof $LazyJSType) $t2 = $t2.rawJSTypeForCheck();
+
+  if ($t1 === $t2) {
+    return true;
+  }
+  if ($t1 === $Object) {
+    return false;
+  }
+
+  // Classes cannot subtype `Function` or vice versa.
+  if ($t1 === $Function || $t2 === $Function) {
+    return false;
+  }
+
+  // If t1 is a JS Object, we may not hit core.Object.
+  if ($t1 == null) {
+    return $t2 == $Object || $t2 == $dynamic;
+  }
+
+  // Check if t1 and t2 have the same raw type.  If so, check covariance on
+  // type parameters.
+  let raw1 = $getGenericClass($t1);
+  let raw2 = $getGenericClass($t2);
+  if (raw1 != null && raw1 == raw2) {
+    let typeArguments1 = $getGenericArgs($t1);
+    let typeArguments2 = $getGenericArgs($t2);
+    if (typeArguments1.length != typeArguments2.length) {
+      $assertFailed();
+    }
+    for (let i = 0; i < typeArguments1.length; ++i) {
+      if (!$_isSubtype(typeArguments1[i], typeArguments2[i])) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  if ($_isInterfaceSubtype(t1.__proto__, $t2)) {
+    return true;
+  }
+
+  // Check mixin.
+  let m1 = $getMixin($t1);
+  if (m1 != null && $_isInterfaceSubtype(m1, $t2)) {
+    return true;
+  }
+
+  // Check interfaces.
+  let getInterfaces = $getImplements($t1);
+  if (getInterfaces) {
+    for (let i1 of getInterfaces()) {
+      if ($_isInterfaceSubtype(i1, $t2)) {
+        return true;
+      }
+    }
+  }
+  return false;
+})()''');
+
+Object extractTypeArguments<T>(T instance, Function f) {
+  if (instance == null) {
+    throw ArgumentError('Cannot extract type of null instance.');
+  }
+  var type = unwrapType(T);
+  if (type is AbstractFunctionType || _isFutureOr(type)) {
+    throw ArgumentError('Cannot extract from non-class type ($type).');
+  }
+  var typeArguments = getGenericArgs(type);
+  if (typeArguments.isEmpty) {
+    throw ArgumentError('Cannot extract from non-generic type ($type).');
+  }
+  var supertype = _getMatchingSupertype(getReifiedType(instance), type);
+  // The signature of this method guarantees that instance is a T, so we
+  // should have a valid non-empty list at this point.
+  assert(supertype != null);
+  var typeArgs = getGenericArgs(supertype);
+  assert(typeArgs != null && typeArgs.isNotEmpty);
+  return dgcall(f, typeArgs, []);
+}
+
+/// Infers type variables based on a series of [trySubtypeMatch] calls, followed
+/// by [getInferredTypes] to return the type.
+class _TypeInferrer {
+  final Map<TypeVariable, TypeConstraint> _typeVariables;
+
+  /// Creates a [TypeConstraintGatherer] which is prepared to gather type
+  /// constraints for the given type parameters.
+  _TypeInferrer(Iterable<TypeVariable> typeVariables)
+      : _typeVariables = Map.fromIterables(
+            typeVariables, typeVariables.map((_) => TypeConstraint()));
+
+  /// Returns the inferred types based on the current constraints.
+  List<Object> getInferredTypes() {
+    var result = List<Object>();
+    for (var constraint in _typeVariables.values) {
+      // Prefer the known bound, if any.
+      if (constraint.lower != null) {
+        result.add(constraint.lower);
+      } else if (constraint.upper != null) {
+        result.add(constraint.upper);
+      } else {
+        return null;
+      }
+    }
+    return result;
+  }
+
+  /// Tries to match [subtype] against [supertype].
+  ///
+  /// If the match succeeds, the resulting type constraints are recorded for
+  /// later use by [computeConstraints].  If the match fails, the set of type
+  /// constraints is unchanged.
+  bool trySubtypeMatch(Object subtype, Object supertype) =>
+      _isSubtypeMatch(subtype, supertype);
+
+  void _constrainLower(TypeVariable parameter, Object lower) {
+    _typeVariables[parameter]._constrainLower(lower);
+  }
+
+  void _constrainUpper(TypeVariable parameter, Object upper) {
+    _typeVariables[parameter]._constrainUpper(upper);
+  }
+
+  bool _isFunctionSubtypeMatch(FunctionType subtype, FunctionType supertype) {
+    // A function type `(M0,..., Mn, [M{n+1}, ..., Mm]) -> R0` is a subtype
+    // match for a function type `(N0,..., Nk, [N{k+1}, ..., Nr]) -> R1` with
+    // respect to `L` under constraints `C0 + ... + Cr + C`
+    // - If `R0` is a subtype match for a type `R1` with respect to `L` under
+    //   constraints `C`:
+    // - If `n <= k` and `r <= m`.
+    // - And for `i` in `0...r`, `Ni` is a subtype match for `Mi` with respect
+    //   to `L` under constraints `Ci`.
+    // Function types with named parameters are treated analogously to the
+    // positional parameter case above.
+    // A generic function type `<T0 extends B0, ..., Tn extends Bn>F0` is a
+    // subtype match for a generic function type `<S0 extends B0, ..., Sn
+    // extends Bn>F1` with respect to `L` under constraints `Cl`:
+    // - If `F0[Z0/T0, ..., Zn/Tn]` is a subtype match for `F0[Z0/S0, ...,
+    //   Zn/Sn]` with respect to `L` under constraints `C`, where each `Zi` is a
+    //   fresh type variable with bound `Bi`.
+    // - And `Cl` is `C` with each constraint replaced with its closure with
+    //   respect to `[Z0, ..., Zn]`.
+    if (subtype.requiredParameterCount > supertype.requiredParameterCount) {
+      return false;
+    }
+    if (subtype.positionalParameterCount < supertype.positionalParameterCount) {
+      return false;
+    }
+    // Test the return types.
+    if (supertype.returnType is! VoidType &&
+        !_isSubtypeMatch(subtype.returnType, supertype.returnType)) {
+      return false;
+    }
+
+    // Test the parameter types.
+    for (int i = 0, n = supertype.positionalParameterCount; i < n; ++i) {
+      if (!_isSubtypeMatch(supertype.getPositionalParameter(i),
+          subtype.getPositionalParameter(i))) {
+        return false;
+      }
+    }
+    var supertypeNamed = supertype.getNamedParameters();
+    var subtypeNamed = supertype.getNamedParameters();
+    for (var name in supertypeNamed.keys) {
+      var subtypeParamType = subtypeNamed[name];
+      if (subtypeParamType == null) return false;
+      if (!_isSubtypeMatch(supertypeNamed[name], subtypeParamType)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  bool _isInterfaceSubtypeMatch(Object subtype, Object supertype) {
+    // A type `P<M0, ..., Mk>` is a subtype match for `P<N0, ..., Nk>` with
+    // respect to `L` under constraints `C0 + ... + Ck`:
+    // - If `Mi` is a subtype match for `Ni` with respect to `L` under
+    //   constraints `Ci`.
+    // A type `P<M0, ..., Mk>` is a subtype match for `Q<N0, ..., Nj>` with
+    // respect to `L` under constraints `C`:
+    // - If `R<B0, ..., Bj>` is the superclass of `P<M0, ..., Mk>` and `R<B0,
+    //   ..., Bj>` is a subtype match for `Q<N0, ..., Nj>` with respect to `L`
+    //   under constraints `C`.
+    // - Or `R<B0, ..., Bj>` is one of the interfaces implemented by `P<M0, ...,
+    //   Mk>` (considered in lexical order) and `R<B0, ..., Bj>` is a subtype
+    //   match for `Q<N0, ..., Nj>` with respect to `L` under constraints `C`.
+    // - Or `R<B0, ..., Bj>` is a mixin into `P<M0, ..., Mk>` (considered in
+    //   lexical order) and `R<B0, ..., Bj>` is a subtype match for `Q<N0, ...,
+    //   Nj>` with respect to `L` under constraints `C`.
+
+    // Note that since kernel requires that no class may only appear in the set
+    // of supertypes of a given type more than once, the order of the checks
+    // above is irrelevant; we just need to find the matched superclass,
+    // substitute, and then iterate through type variables.
+    var matchingSupertype = _getMatchingSupertype(subtype, supertype);
+    if (matchingSupertype == null) return false;
+
+    var matchingTypeArgs = getGenericArgs(matchingSupertype);
+    var supertypeTypeArgs = getGenericArgs(supertype);
+    for (int i = 0; i < supertypeTypeArgs.length; i++) {
+      if (!_isSubtypeMatch(matchingTypeArgs[i], supertypeTypeArgs[i])) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  bool _isNull(Object type) => identical(type, unwrapType(Null));
+
+  /// Attempts to match [subtype] as a subtype of [supertype], gathering any
+  /// constraints discovered in the process.
+  ///
+  /// If a set of constraints was found, `true` is returned and the caller
+  /// may proceed to call [computeConstraints].  Otherwise, `false` is returned.
+  ///
+  /// In the case where `false` is returned, some bogus constraints may have
+  /// been added to [_protoConstraints].  It is the caller's responsibility to
+  /// discard them if necessary.
+  bool _isSubtypeMatch(Object subtype, Object supertype) {
+    // A type variable `T` in `L` is a subtype match for any type schema `Q`:
+    // - Under constraint `T <: Q`.
+    if (subtype is TypeVariable && _typeVariables.containsKey(subtype)) {
+      _constrainUpper(subtype, supertype);
+      return true;
+    }
+    // A type schema `Q` is a subtype match for a type variable `T` in `L`:
+    // - Under constraint `Q <: T`.
+    if (supertype is TypeVariable && _typeVariables.containsKey(supertype)) {
+      _constrainLower(supertype, subtype);
+      return true;
+    }
+    // Any two equal types `P` and `Q` are subtype matches under no constraints.
+    // Note: to avoid making the algorithm quadratic, we just check for
+    // identical().  If P and Q are equal but not identical, recursing through
+    // the types will give the proper result.
+    if (identical(subtype, supertype)) return true;
+    // Any type `P` is a subtype match for `dynamic`, `Object`, or `void` under
+    // no constraints.
+    if (_isTop(supertype)) return true;
+    // `Null` is a subtype match for any type `Q` under no constraints.
+    // Note that nullable types will change this.
+    if (_isNull(subtype)) return true;
+
+    // Handle FutureOr<T> union type.
+    if (_isFutureOr(subtype)) {
+      var subtypeArg = getGenericArgs(subtype)[0];
+      if (_isFutureOr(supertype)) {
+        // `FutureOr<P>` is a subtype match for `FutureOr<Q>` with respect to `L`
+        // under constraints `C`:
+        // - If `P` is a subtype match for `Q` with respect to `L` under constraints
+        //   `C`.
+        var supertypeArg = getGenericArgs(supertype)[0];
+        return _isSubtypeMatch(subtypeArg, supertypeArg);
+      }
+
+      // `FutureOr<P>` is a subtype match for `Q` with respect to `L` under
+      // constraints `C0 + C1`:
+      // - If `Future<P>` is a subtype match for `Q` with respect to `L` under
+      //   constraints `C0`.
+      // - And `P` is a subtype match for `Q` with respect to `L` under
+      //   constraints `C1`.
+      var subtypeFuture = JS('!', '#(#)', getGenericClass(Future), subtypeArg);
+      return _isSubtypeMatch(subtypeFuture, supertype) &&
+          _isSubtypeMatch(subtypeArg, supertype);
+    }
+
+    if (_isFutureOr(supertype)) {
+      // `P` is a subtype match for `FutureOr<Q>` with respect to `L` under
+      // constraints `C`:
+      // - If `P` is a subtype match for `Future<Q>` with respect to `L` under
+      //   constraints `C`.
+      // - Or `P` is not a subtype match for `Future<Q>` with respect to `L` under
+      //   constraints `C`
+      //   - And `P` is a subtype match for `Q` with respect to `L` under
+      //     constraints `C`
+      var supertypeArg = getGenericArgs(supertype)[0];
+      var supertypeFuture =
+          JS('!', '#(#)', getGenericClass(Future), supertypeArg);
+      return _isSubtypeMatch(subtype, supertypeFuture) ||
+          _isSubtypeMatch(subtype, supertypeArg);
+    }
+
+    // A type variable `T` not in `L` with bound `P` is a subtype match for the
+    // same type variable `T` with bound `Q` with respect to `L` under
+    // constraints `C`:
+    // - If `P` is a subtype match for `Q` with respect to `L` under constraints
+    //   `C`.
+    if (subtype is TypeVariable) {
+      return supertype is TypeVariable && identical(subtype, supertype);
+    }
+    if (subtype is GenericFunctionType) {
+      if (supertype is GenericFunctionType) {
+        // Given generic functions g1 and g2, g1 <: g2 iff:
+        //
+        //     g1<TFresh> <: g2<TFresh>
+        //
+        // where TFresh is a list of fresh type variables that both g1 and g2 will
+        // be instantiated with.
+        var formalCount = subtype.formalCount;
+        if (formalCount != supertype.formalCount) return false;
+
+        // Using either function's type formals will work as long as they're
+        // both instantiated with the same ones. The instantiate operation is
+        // guaranteed to avoid capture because it does not depend on its
+        // TypeVariable objects, rather it uses JS function parameters to ensure
+        // correct binding.
+        var fresh = supertype.typeFormals;
+
+        // Check the bounds of the type parameters of g1 and g2.
+        // given a type parameter `T1 extends U1` from g1, and a type parameter
+        // `T2 extends U2` from g2, we must ensure that:
+        //
+        //      U2 <: U1
+        //
+        // (Note the reversal of direction -- type formal bounds are
+        // contravariant, similar to the function's formal parameter types).
+        //
+        var t1Bounds = subtype.instantiateTypeBounds(fresh);
+        var t2Bounds = supertype.instantiateTypeBounds(fresh);
+        // TODO(jmesserly): we could optimize for the common case of no bounds.
+        for (var i = 0; i < formalCount; i++) {
+          if (!_isSubtypeMatch(t2Bounds[i], t1Bounds[i])) {
+            return false;
+          }
+        }
+        return _isFunctionSubtypeMatch(
+            subtype.instantiate(fresh), supertype.instantiate(fresh));
+      } else {
+        return false;
+      }
+    } else if (supertype is GenericFunctionType) {
+      return false;
+    }
+
+    // A type `P` is a subtype match for `Function` with respect to `L` under no
+    // constraints:
+    // - If `P` implements a call method.
+    // - Or if `P` is a function type.
+    // TODO(paulberry): implement this case.
+    // A type `P` is a subtype match for a type `Q` with respect to `L` under
+    // constraints `C`:
+    // - If `P` is an interface type which implements a call method of type `F`,
+    //   and `F` is a subtype match for a type `Q` with respect to `L` under
+    //   constraints `C`.
+    // TODO(paulberry): implement this case.
+    if (subtype is FunctionType) {
+      if (supertype is! FunctionType) {
+        if (identical(supertype, unwrapType(Function)) ||
+            identical(supertype, unwrapType(Object))) {
+          return true;
+        } else {
+          return false;
+        }
+      }
+      if (supertype is FunctionType) {
+        return _isFunctionSubtypeMatch(subtype, supertype);
+      }
+    }
+    return _isInterfaceSubtypeMatch(subtype, supertype);
+  }
+
+  bool _isTop(Object type) =>
+      identical(type, _dynamic) ||
+      identical(type, void_) ||
+      identical(type, unwrapType(Object));
+}
+
+/// A constraint on a type parameter that we're inferring.
+class TypeConstraint {
+  /// The lower bound of the type being constrained.  This bound must be a
+  /// subtype of the type being constrained.
+  Object lower;
+
+  /// The upper bound of the type being constrained.  The type being constrained
+  /// must be a subtype of this bound.
+  Object upper;
+
+  void _constrainLower(Object type) {
+    if (lower != null) {
+      if (isSubtypeOf(lower, type)) {
+        // nothing to do, existing lower bound is lower than the new one.
+        return;
+      }
+      if (!isSubtypeOf(type, lower)) {
+        // Neither bound is lower and we don't have GLB, so use bottom type.
+        type = unwrapType(Null);
+      }
+    }
+    lower = type;
+  }
+
+  void _constrainUpper(Object type) {
+    if (upper != null) {
+      if (isSubtypeOf(type, upper)) {
+        // nothing to do, existing upper bound is higher than the new one.
+        return;
+      }
+      if (!isSubtypeOf(upper, type)) {
+        // Neither bound is higher and we don't have LUB, so use top type.
+        type = unwrapType(Object);
+      }
+    }
+    upper = type;
+  }
+
+  String toString() => '${typeName(lower)} <: <type> <: ${typeName(upper)}';
+}
+
+/// Finds a supertype of [subtype] that matches the class [supertype], but may
+/// contain different generic type arguments.
+Object _getMatchingSupertype(Object subtype, Object supertype) {
+  if (identical(subtype, supertype)) return supertype;
+  if (subtype == null || subtype == unwrapType(Object)) return null;
+
+  var subclass = getGenericClass(subtype);
+  var superclass = getGenericClass(supertype);
+  if (subclass != null && identical(subclass, superclass)) {
+    return subtype; // matching supertype found!
+  }
+
+  var result = _getMatchingSupertype(JS('', '#.__proto__', subtype), supertype);
+  if (result != null) return result;
+
+  // Check mixin.
+  var mixin = getMixin(subtype);
+  if (mixin != null) {
+    result = _getMatchingSupertype(mixin, supertype);
+    if (result != null) return result;
+  }
+
+  // Check interfaces.
+  var getInterfaces = getImplements(subtype);
+  if (getInterfaces != null) {
+    for (var iface in getInterfaces()) {
+      result = _getMatchingSupertype(iface, supertype);
+      if (result != null) return result;
+    }
+  }
+
+  return null;
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart
new file mode 100644
index 0000000..2c06179
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart
@@ -0,0 +1,136 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart._runtime;
+
+/// This library defines a set of general javascript utilities for us
+/// by the Dart runtime.
+// TODO(ochafik): Rewrite some of these in Dart when possible.
+
+final Function(Object, Object, Object) defineProperty =
+    JS('', 'Object.defineProperty');
+
+defineValue(obj, name, value) {
+  defineAccessor(obj, name, value: value, configurable: true, writable: true);
+  return value;
+}
+
+final Function(Object, Object,
+    {Object get,
+    Object set,
+    Object value,
+    bool configurable,
+    bool writable}) defineAccessor = JS('', 'Object.defineProperty');
+
+final Function(Object, Object) getOwnPropertyDescriptor =
+    JS('', 'Object.getOwnPropertyDescriptor');
+
+final Iterable Function(Object) getOwnPropertyNames =
+    JS('', 'Object.getOwnPropertyNames');
+
+final Function(Object) getOwnPropertySymbols =
+    JS('', 'Object.getOwnPropertySymbols');
+
+final Function(Object) getPrototypeOf = JS('', 'Object.getPrototypeOf');
+
+/// This error indicates a strong mode specific failure, other than a type
+/// assertion failure (TypeError) or CastError.
+void throwTypeError(String message) {
+  throw TypeErrorImpl(message);
+}
+
+/// This error indicates a bug in the runtime or the compiler.
+void throwInternalError(String message) {
+  JS('', 'throw Error(#)', message);
+}
+
+Iterable getOwnNamesAndSymbols(obj) {
+  var names = getOwnPropertyNames(obj);
+  var symbols = getOwnPropertySymbols(obj);
+  return JS('', '#.concat(#)', names, symbols);
+}
+
+safeGetOwnProperty(obj, name) {
+  var desc = getOwnPropertyDescriptor(obj, name);
+  if (desc != null) return JS('', '#.value', desc);
+}
+
+/// Defines a lazy static field.
+/// After initial get or set, it will replace itself with a value property.
+// TODO(jmesserly): reusing descriptor objects has been shown to improve
+// performance in other projects (e.g. webcomponents.js ShadowDOM polyfill).
+defineLazyField(to, name, desc) => JS('', '''(() => {
+  const initializer = $desc.get;
+  let init = initializer;
+  let value = null;
+  $desc.get = function() {
+    if (init == null) return value;
+    let f = init;
+    init = $throwCyclicInitializationError;
+    if (f === init) f($name); // throw cycle error
+
+    // On the first (non-cyclic) execution, record the field so we can reset it
+    // later if needed (hot restart).
+    $_resetFields.push(() => {
+      init = initializer;
+      value = null;
+    });
+
+    // Try to evaluate the field, using try+catch to ensure we implement the
+    // correct Dart error semantics.
+    try {
+      value = f();
+      init = null;
+      return value;
+    } catch (e) {
+      init = null;
+      value = null;
+      throw e;
+    }
+  };
+  $desc.configurable = true;
+  if ($desc.set != null) {
+    $desc.set = function(x) {
+      init = null;
+      value = x;
+    };
+  }
+  return ${defineProperty(to, name, desc)};
+})()''');
+
+copyTheseProperties(to, from, names) {
+  for (int i = 0, n = JS('!', '#.length', names); i < n; ++i) {
+    var name = JS('', '#[#]', names, i);
+    if (name == 'constructor') continue;
+    copyProperty(to, from, name);
+  }
+  return to;
+}
+
+copyProperty(to, from, name) {
+  var desc = getOwnPropertyDescriptor(from, name);
+  if (JS('!', '# == Symbol.iterator', name)) {
+    // On native types, Symbol.iterator may already be present.
+    // TODO(jmesserly): investigate if we still need this.
+    // If so, we need to find a better solution.
+    // See https://github.com/dart-lang/sdk/issues/28324
+    var existing = getOwnPropertyDescriptor(to, name);
+    if (existing != null) {
+      if (JS('!', '#.writable', existing)) {
+        JS('', '#[#] = #.value', to, name, desc);
+      }
+      return;
+    }
+  }
+  defineProperty(to, name, desc);
+}
+
+@JSExportName('export')
+exportProperty(to, from, name) => copyProperty(to, from, name);
+
+/// Copy properties from source to destination object.
+/// This operation is commonly called `mixin` in JS.
+copyProperties(to, from) {
+  return copyTheseProperties(to, from, getOwnNamesAndSymbols(from));
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/debugger.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/debugger.dart
new file mode 100644
index 0000000..4618317
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/debugger.dart
@@ -0,0 +1,1016 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart._debugger;
+
+import 'dart:_foreign_helper' show JS;
+import 'dart:_interceptors' show JSArray;
+import 'dart:_js_helper' show InternalMap;
+import 'dart:_runtime' as dart;
+import 'dart:core';
+import 'dart:collection';
+import 'dart:html' as html;
+import 'dart:math';
+
+part 'profile.dart';
+
+/// JsonMLConfig object to pass to devtools to specify how an Object should
+/// be displayed. skipDart signals that an object should not be formatted
+/// by the Dart formatter. This is used to specify that an Object
+/// should just be displayed using the regular JavaScript view instead of a
+/// custom Dart view. For example, this is used to display the JavaScript view
+/// of a Dart Function as a child of the regular Function object. keyToString
+/// signals that a map key object should have its toString() displayed by
+/// the Dart formatter.
+///
+/// We'd like this to be an enum, but we can't because it's a dev_compiler bug.
+class JsonMLConfig {
+  const JsonMLConfig(this.name);
+
+  final String name;
+  static const none = JsonMLConfig("none");
+  static const skipDart = JsonMLConfig("skipDart");
+  static const keyToString = JsonMLConfig("keyToString");
+  static const asClass = JsonMLConfig("asClass");
+  static const asObject = JsonMLConfig("asObject");
+  static const asMap = JsonMLConfig("asMap");
+  toString() => "JsonMLConfig($name)";
+}
+
+int _maxSpanLength = 100;
+var _devtoolsFormatter = JsonMLFormatter(DartFormatter());
+
+/// We truncate a toString() longer than [maxStringLength].
+int maxFormatterStringLength = 100;
+
+String _typeof(object) => JS<String>('!', 'typeof #', object);
+
+List<String> getOwnPropertyNames(object) =>
+    JSArray<String>.of(dart.getOwnPropertyNames(object));
+
+List getOwnPropertySymbols(object) =>
+    JS('List', 'Object.getOwnPropertySymbols(#)', object);
+
+// TODO(jacobr): move this to dart:js and fully implement.
+class JSNative {
+  // Name may be a String or a Symbol.
+  static getProperty(object, name) => JS('', '#[#]', object, name);
+  // Name may be a String or a Symbol.
+  static setProperty(object, name, value) =>
+      JS('', '#[#]=#', object, name, value);
+}
+
+void addMetadataChildren(object, Set<NameValuePair> ret) {
+  ret.add(NameValuePair(
+      name: "[[class]]",
+      value: dart.getReifiedType(object),
+      config: JsonMLConfig.asClass));
+}
+
+/// Add properties from a signature definition [sig] for [object].
+/// Walk the prototype chain if [walkProtypeChain] is set.
+/// Tag types on function typed properties of [object] if [tagTypes] is set.
+///
+void addPropertiesFromSignature(
+    sig, Set<NameValuePair> properties, object, bool walkPrototypeChain,
+    {tagTypes = false}) {
+  // Including these property names doesn't add any value and just clutters
+  // the debugger output.
+  // TODO(jacobr): consider adding runtimeType to this list.
+  var skippedNames = Set()..add('hashCode');
+  var objectPrototype = JS('', 'Object.prototype');
+  while (sig != null && !identical(sig, objectPrototype)) {
+    for (var symbol in getOwnPropertySymbols(sig)) {
+      var dartName = symbolName(symbol);
+      String dartXPrefix = 'dartx.';
+      if (dartName.startsWith(dartXPrefix)) {
+        dartName = dartName.substring(dartXPrefix.length);
+      }
+      if (skippedNames.contains(dartName)) continue;
+      var value = safeGetProperty(object, symbol);
+      // Tag the function with its runtime type.
+      if (tagTypes && _typeof(value) == 'function') {
+        dart.fn(value, JS('', '#[#]', sig, symbol));
+      }
+      properties.add(NameValuePair(name: dartName, value: value));
+    }
+
+    for (var name in getOwnPropertyNames(sig)) {
+      var value = safeGetProperty(object, name);
+      if (skippedNames.contains(name)) continue;
+      // Tag the function with its runtime type.
+      if (tagTypes && _typeof(value) == 'function') {
+        dart.fn(value, JS('', '#[#]', sig, name));
+      }
+      properties.add(NameValuePair(name: name, value: value));
+    }
+
+    if (!walkPrototypeChain) break;
+
+    sig = dart.getPrototypeOf(sig);
+  }
+}
+
+/// Sort properties sorting public names before private names.
+List<NameValuePair> sortProperties(Iterable<NameValuePair> properties) {
+  var sortedProperties = properties.toList();
+
+  sortedProperties.sort((a, b) {
+    var aPrivate = a.name.startsWith('_');
+    var bPrivate = b.name.startsWith('_');
+    if (aPrivate != bPrivate) return aPrivate ? 1 : -1;
+    return a.name.compareTo(b.name);
+  });
+  return sortedProperties;
+}
+
+String getObjectTypeName(object) {
+  var reifiedType = dart.getReifiedType(object);
+  if (reifiedType == null) {
+    if (_typeof(object) == 'function') {
+      return '[[Raw JavaScript Function]]';
+    }
+    return '<Error getting type name>';
+  }
+  return getTypeName(reifiedType);
+}
+
+String getTypeName(type) {
+  // TODO(jacobr): it would be nice if there was a way we could distinguish
+  // between a List<dynamic> created from Dart and an Array passed in from
+  // JavaScript.
+  return dart.typeName(type);
+}
+
+String safePreview(object, config) {
+  try {
+    var preview = _devtoolsFormatter._simpleFormatter.preview(object, config);
+    if (preview != null) return preview;
+    return object.toString();
+  } catch (e) {
+    return '<Exception thrown> $e';
+  }
+}
+
+String symbolName(symbol) {
+  var name = symbol.toString();
+  assert(name.startsWith('Symbol('));
+  return name.substring('Symbol('.length, name.length - 1);
+}
+
+bool hasMethod(object, String name) {
+  try {
+    return dart.hasMethod(object, name);
+  } catch (e) {
+    return false;
+  }
+}
+
+/// [JsonMLFormatter] consumes [NameValuePair] objects and
+class NameValuePair {
+  NameValuePair(
+      {this.name,
+      this.value,
+      this.config = JsonMLConfig.none,
+      this.hideName = false});
+
+  // Define equality and hashCode so that NameValuePair can be used
+  // in a Set to dedupe entries with duplicate names.
+  bool operator ==(other) {
+    if (other is! NameValuePair) return false;
+    if (this.hideName || other.hideName) return identical(this, other);
+    return other.name == name;
+  }
+
+  int get hashCode => name.hashCode;
+
+  final String name;
+  final Object value;
+  final JsonMLConfig config;
+  final bool hideName;
+
+  String get displayName => hideName ? '' : name;
+}
+
+class MapEntry {
+  MapEntry({this.key, this.value});
+
+  final Object key;
+  final Object value;
+}
+
+class IterableSpan {
+  IterableSpan(this.start, this.end, this.iterable);
+
+  final int start;
+  final int end;
+  final Iterable iterable;
+  int get length => end - start;
+
+  /// Using length - .5, a list of length 10000 results in a
+  /// maxPowerOfSubsetSize of 1, so the list will be broken up into 100,
+  /// 100-length subsets. A list of length 10001 results in a
+  /// maxPowerOfSubsetSize of 2, so the list will be broken up into 1
+  /// 10000-length subset and 1 1-length subset.
+  int get maxPowerOfSubsetSize =>
+      (log(length - .5) / log(_maxSpanLength)).truncate();
+  int get subsetSize => pow(_maxSpanLength, maxPowerOfSubsetSize);
+
+  Map<int, dynamic> asMap() =>
+      iterable.skip(start).take(length).toList().asMap();
+
+  List<NameValuePair> children() {
+    var children = <NameValuePair>[];
+    if (length <= _maxSpanLength) {
+      asMap().forEach((i, element) {
+        children
+            .add(NameValuePair(name: (i + start).toString(), value: element));
+      });
+    } else {
+      for (var i = start; i < end; i += subsetSize) {
+        var subSpan = IterableSpan(i, min(end, subsetSize + i), iterable);
+        if (subSpan.length == 1) {
+          children.add(
+              NameValuePair(name: i.toString(), value: iterable.elementAt(i)));
+        } else {
+          children.add(NameValuePair(
+              name: '[${i}...${subSpan.end - 1}]',
+              value: subSpan,
+              hideName: true));
+        }
+      }
+    }
+    return children;
+  }
+}
+
+class Library {
+  Library(this.name, this.object);
+
+  final String name;
+  final Object object;
+}
+
+class NamedConstructor {
+  NamedConstructor(this.object);
+
+  final Object object;
+}
+
+class HeritageClause {
+  HeritageClause(this.name, this.types);
+
+  final String name;
+  final List types;
+}
+
+Object safeGetProperty(Object protoChain, Object name) {
+  try {
+    return JSNative.getProperty(protoChain, name);
+  } catch (e) {
+    return '<Exception thrown> $e';
+  }
+}
+
+safeProperties(object) => Map.fromIterable(
+    getOwnPropertyNames(object)
+        .where((each) => safeGetProperty(object, each) != null),
+    key: (name) => name,
+    value: (name) => safeGetProperty(object, name));
+
+/// Class to simplify building the JsonML objects expected by the
+/// Devtools Formatter API.
+class JsonMLElement {
+  dynamic _attributes;
+  List _jsonML;
+
+  JsonMLElement(tagName) {
+    _attributes = JS('', '{}');
+    _jsonML = [tagName, _attributes];
+  }
+
+  appendChild(element) {
+    _jsonML.add(element.toJsonML());
+  }
+
+  JsonMLElement createChild(String tagName) {
+    var c = JsonMLElement(tagName);
+    _jsonML.add(c.toJsonML());
+    return c;
+  }
+
+  JsonMLElement createObjectTag(object) =>
+      createChild('object')..addAttribute('object', object);
+
+  void setStyle(String style) {
+    _attributes.style = style;
+  }
+
+  addStyle(String style) {
+    if (_attributes.style == null) {
+      _attributes.style = style;
+    } else {
+      _attributes.style += style;
+    }
+  }
+
+  addAttribute(key, value) {
+    JSNative.setProperty(_attributes, key, value);
+  }
+
+  createTextChild(String text) {
+    _jsonML.add(text);
+  }
+
+  toJsonML() => _jsonML;
+}
+
+/// Whether an object is a native JavaScript type where we should display the
+/// JavaScript view of the object instead of the custom Dart specific render
+/// of properties.
+bool isNativeJavaScriptObject(object) {
+  var type = _typeof(object);
+  if (type != 'object' && type != 'function') return true;
+
+  // Consider all regular JS objects that do not represent Dart modules native
+  // JavaScript objects.
+  if (dart.isJsInterop(object) && dart.getModuleName(object) == null) {
+    return true;
+  }
+
+  // Treat Node objects as a native JavaScript type as the regular DOM render
+  // in devtools is superior to the dart specific view.
+  return object is html.Node;
+}
+
+/// Class implementing the Devtools Formatter API described by:
+/// https://docs.google.com/document/d/1FTascZXT9cxfetuPRT2eXPQKXui4nWFivUnS_335T3U
+/// Specifically, a formatter implements a header, hasBody, and body method.
+/// This class renders the simple structured format objects [_simpleFormatter]
+/// provides as JsonML.
+class JsonMLFormatter {
+  // TODO(jacobr): define a SimpleFormatter base class that DartFormatter
+  // implements if we decide to use this class elsewhere. We specify that the
+  // type is DartFormatter here purely to get type checking benefits not because
+  // this class is really intended to only support instances of type
+  // DartFormatter.
+  DartFormatter _simpleFormatter;
+
+  bool customFormattersOn = false;
+
+  JsonMLFormatter(this._simpleFormatter);
+
+  void setMaxSpanLengthForTestingOnly(int spanLength) {
+    _maxSpanLength = spanLength;
+  }
+
+  header(object, config) {
+    customFormattersOn = true;
+    if (config == JsonMLConfig.skipDart || isNativeJavaScriptObject(object)) {
+      return null;
+    }
+    var c = _simpleFormatter.preview(object, config);
+    if (c == null) return null;
+
+    if (config == JsonMLConfig.keyToString) {
+      c = object.toString();
+    }
+
+    // Indicate this is a Dart Object by using a Dart background color.
+    // This is stylistically a bit ugly but it eases distinguishing Dart and
+    // JS objects.
+    var element = JsonMLElement('span')
+      ..setStyle('background-color: #d9edf7;color: black')
+      ..createTextChild(c);
+    return element.toJsonML();
+  }
+
+  bool hasBody(object, config) => _simpleFormatter.hasChildren(object, config);
+
+  body(object, config) {
+    var body = JsonMLElement('ol')
+      ..setStyle('list-style-type: none;'
+          'padding-left: 0px;'
+          'margin-top: 0px;'
+          'margin-bottom: 0px;'
+          'margin-left: 12px;');
+    if (object is StackTrace) {
+      body.addStyle('background-color: thistle;color: rgb(196, 26, 22);');
+    }
+    var children = _simpleFormatter.children(object, config);
+    if (children == null) return body.toJsonML();
+    for (NameValuePair child in children) {
+      var li = body.createChild('li');
+      li.setStyle("padding-left: 13px;");
+
+      // The value is indented when it is on a different line from the name
+      // by setting right padding of the name to -13px and the padding of the
+      // value to 13px.
+      JsonMLElement nameSpan;
+      var valueStyle = '';
+      if (!child.hideName) {
+        nameSpan = JsonMLElement('span')
+          ..createTextChild(
+              child.displayName.isNotEmpty ? '${child.displayName}: ' : '')
+          ..setStyle(
+              'background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px');
+        valueStyle = 'margin-left: 13px';
+      }
+
+      if (_typeof(child.value) == 'object' ||
+          _typeof(child.value) == 'function') {
+        var valueSpan = JsonMLElement('span')..setStyle(valueStyle);
+        valueSpan.createObjectTag(child.value)
+          ..addAttribute('config', child.config);
+        if (nameSpan != null) {
+          li.appendChild(nameSpan);
+        }
+        li.appendChild(valueSpan);
+      } else {
+        var line = li.createChild('span');
+        if (nameSpan != null) {
+          line.appendChild(nameSpan);
+        }
+        line.appendChild(JsonMLElement('span')
+          ..createTextChild(safePreview(child.value, child.config))
+          ..setStyle(valueStyle));
+      }
+    }
+    return body.toJsonML();
+  }
+}
+
+abstract class Formatter {
+  bool accept(object, config);
+  String preview(object);
+  bool hasChildren(object);
+  List<NameValuePair> children(object);
+}
+
+class DartFormatter {
+  List<Formatter> _formatters;
+
+  DartFormatter() {
+    // The order of formatters matters as formatters earlier in the list take
+    // precedence.
+    _formatters = [
+      ObjectInternalsFormatter(),
+      ClassFormatter(),
+      TypeFormatter(),
+      NamedConstructorFormatter(),
+      MapFormatter(),
+      MapOverviewFormatter(),
+      IterableFormatter(),
+      IterableSpanFormatter(),
+      MapEntryFormatter(),
+      StackTraceFormatter(),
+      ErrorAndExceptionFormatter(),
+      FunctionFormatter(),
+      HeritageClauseFormatter(),
+      LibraryModuleFormatter(),
+      LibraryFormatter(),
+      ObjectFormatter(),
+    ];
+  }
+
+  String preview(object, config) {
+    try {
+      if (object == null ||
+          object is num ||
+          object is String ||
+          isNativeJavaScriptObject(object)) {
+        return object.toString();
+      }
+      for (var formatter in _formatters) {
+        if (formatter.accept(object, config)) return formatter.preview(object);
+      }
+    } catch (e, trace) {
+      // Log formatter internal errors as unfortunately the devtools cannot
+      // be used to debug formatter errors.
+      html.window.console.error("Caught exception $e\n trace:\n$trace");
+    }
+
+    return null;
+  }
+
+  bool hasChildren(object, config) {
+    if (object == null) return false;
+    try {
+      for (var formatter in _formatters) {
+        if (formatter.accept(object, config))
+          return formatter.hasChildren(object);
+      }
+    } catch (e, trace) {
+      // See comment for preview.
+      html.window.console
+          .error("[hasChildren] Caught exception $e\n trace:\n$trace");
+    }
+    return false;
+  }
+
+  List<NameValuePair> children(object, config) {
+    try {
+      if (object != null) {
+        for (var formatter in _formatters) {
+          if (formatter.accept(object, config))
+            return formatter.children(object);
+        }
+      }
+    } catch (e, trace) {
+      // See comment for preview.
+      html.window.console.error("Caught exception $e\n trace:\n$trace");
+    }
+    return <NameValuePair>[];
+  }
+}
+
+/// Default formatter for Dart Objects.
+class ObjectFormatter extends Formatter {
+  bool accept(object, config) => !isNativeJavaScriptObject(object);
+
+  String preview(object) {
+    var typeName = getObjectTypeName(object);
+    try {
+      // An explicit toString() call might not actually be a string. This way
+      // we're sure.
+      var toString = "$object";
+      if (toString.length > maxFormatterStringLength) {
+        toString = toString.substring(0, maxFormatterStringLength - 3) + "...";
+      }
+      // The default toString() will be "Instance of 'Foo'", in which case we
+      // don't need any further indication of the class.
+      if (toString.contains(typeName)) {
+        return toString;
+      } else {
+        // If there's no class indication, e.g. an Int64 that just prints as a
+        // number, then add the class name.
+        return "$toString ($typeName)";
+      }
+    } catch (e) {}
+    // We will only get here if there was an error getting the toString, in
+    // which case we just use the type name.
+    return typeName;
+  }
+
+  bool hasChildren(object) => true;
+
+  List<NameValuePair> children(object) {
+    var type = dart.getType(object);
+    var ret = LinkedHashSet<NameValuePair>();
+    // We use a Set rather than a List to avoid duplicates.
+    var fields = Set<NameValuePair>();
+    addPropertiesFromSignature(dart.getFields(type), fields, object, true);
+    var getters = Set<NameValuePair>();
+    addPropertiesFromSignature(dart.getGetters(type), getters, object, true);
+    ret.addAll(sortProperties(fields));
+    ret.addAll(sortProperties(getters));
+    addMetadataChildren(object, ret);
+    return ret.toList();
+  }
+}
+
+/// Show the object instance members and a reduced preview.
+///
+/// Used as a sub-entry to show the internals of objects that have a different
+/// primary format. For example, a Map shows the key-value pairs, but this makes
+/// the internals of the map visible for debugging.
+class ObjectInternalsFormatter extends ObjectFormatter {
+  bool accept(object, config) =>
+      super.accept(object, config) && config == JsonMLConfig.asObject;
+
+  // A minimal preview because we expect a full preview is already shown in a
+  // parent formatter.
+  String preview(object) {
+    return getObjectTypeName(object);
+  }
+}
+
+/// Formatter for module Dart Library objects.
+class LibraryModuleFormatter implements Formatter {
+  accept(object, config) => dart.getModuleName(object) != null;
+
+  bool hasChildren(object) => true;
+
+  String preview(object) {
+    var libraryNames = dart.getModuleName(object).split('/');
+    // Library names are received with a repeat directory name, so strip the
+    // last directory entry here to make the path cleaner. For example, the
+    // library "third_party/dart/utf/utf" shoud display as
+    // "third_party/dart/utf/".
+    if (libraryNames.length > 1 &&
+        libraryNames.last == libraryNames[libraryNames.length - 2]) {
+      libraryNames[libraryNames.length - 1] = '';
+    }
+    return 'Library Module: ${libraryNames.join('/')}';
+  }
+
+  List<NameValuePair> children(object) {
+    var children = LinkedHashSet<NameValuePair>();
+    for (var name in getOwnPropertyNames(object)) {
+      var value = safeGetProperty(object, name);
+      children.add(NameValuePair(
+          name: name, value: Library(name, value), hideName: true));
+    }
+    return children.toList();
+  }
+}
+
+class LibraryFormatter implements Formatter {
+  var genericParameters = HashMap<String, String>();
+
+  accept(object, config) => object is Library;
+
+  bool hasChildren(object) => true;
+
+  String preview(object) => object.name;
+
+  List<NameValuePair> children(object) {
+    // Maintain library member order rather than sorting members as is the
+    // case for class members.
+    var children = LinkedHashSet<NameValuePair>();
+    var objectProperties = safeProperties(object.object);
+    objectProperties.forEach((name, value) {
+      // Skip the generic constructors for each class as users are only
+      // interested in seeing the actual classes.
+      if (dart.getGenericTypeCtor(value) != null) return;
+
+      children.add(dart.isType(value)
+          ? classChild(name, value)
+          : NameValuePair(name: name, value: value));
+    });
+    return children.toList();
+  }
+
+  classChild(String name, Object child) {
+    var typeName = getTypeName(child);
+    return NameValuePair(
+        name: typeName, value: child, config: JsonMLConfig.asClass);
+  }
+}
+
+/// Formatter for Dart Function objects.
+/// Dart functions happen to be regular JavaScript Function objects but
+/// we can distinguish them based on whether they have been tagged with
+/// runtime type information.
+class FunctionFormatter implements Formatter {
+  accept(object, config) {
+    if (_typeof(object) != 'function') return false;
+    return dart.getReifiedType(object) != null;
+  }
+
+  bool hasChildren(object) => true;
+
+  String preview(object) {
+    // The debugger can createa a preview of a FunctionType while it's being
+    // constructed (before argument types exist), so we need to catch errors.
+    try {
+      return dart.typeName(dart.getReifiedType(object));
+    } catch (e) {
+      return safePreview(object, JsonMLConfig.none);
+    }
+  }
+
+  List<NameValuePair> children(object) => <NameValuePair>[
+        NameValuePair(name: 'signature', value: preview(object)),
+        NameValuePair(
+            name: 'JavaScript Function',
+            value: object,
+            config: JsonMLConfig.skipDart)
+      ];
+}
+
+/// Formatter for Objects that implement Map but are not system Maps.
+///
+/// This shows two sub-views, one for instance fields and one for
+/// Map key/value pairs.
+class MapOverviewFormatter implements Formatter {
+  // Because this comes after MapFormatter in the list, internal
+  // maps will be picked up by that formatter.
+  accept(object, config) => object is Map;
+
+  bool hasChildren(object) => true;
+
+  String preview(object) {
+    Map map = object;
+    try {
+      return '${getObjectTypeName(map)}';
+    } catch (e) {
+      return safePreview(object, JsonMLConfig.none);
+    }
+  }
+
+  List<NameValuePair> children(object) => [
+        NameValuePair(
+            name: "[[instance view]]",
+            value: object,
+            config: JsonMLConfig.asObject),
+        NameValuePair(
+            name: "[[entries]]", value: object, config: JsonMLConfig.asMap)
+      ];
+}
+
+/// Formatter for Dart Map objects.
+///
+/// This is only used for internal maps, or when shown as [[entries]]
+/// from MapOverViewFormatter.
+class MapFormatter implements Formatter {
+  accept(object, config) =>
+      object is InternalMap || config == JsonMLConfig.asMap;
+
+  bool hasChildren(object) => true;
+
+  String preview(object) {
+    Map map = object;
+    try {
+      return '${getObjectTypeName(map)} length ${map.length}';
+    } catch (e) {
+      return safePreview(object, JsonMLConfig.none);
+    }
+  }
+
+  List<NameValuePair> children(object) {
+    // TODO(jacobr): be lazier about enumerating contents of Maps that are not
+    // the build in LinkedHashMap class.
+    // TODO(jacobr): handle large Maps better.
+    Map map = object;
+    var entries = LinkedHashSet<NameValuePair>();
+    map.forEach((key, value) {
+      var entryWrapper = MapEntry(key: key, value: value);
+      entries.add(
+          NameValuePair(name: entries.length.toString(), value: entryWrapper));
+    });
+    addMetadataChildren(object, entries);
+    return entries.toList();
+  }
+}
+
+/// Formatter for Dart Iterable objects including List and Set.
+class IterableFormatter implements Formatter {
+  bool accept(object, config) => object is Iterable;
+
+  String preview(object) {
+    Iterable iterable = object;
+    try {
+      var length = iterable.length;
+      return '${getObjectTypeName(iterable)} length $length';
+    } catch (_) {
+      return '${getObjectTypeName(iterable)}';
+    }
+  }
+
+  bool hasChildren(object) => true;
+
+  List<NameValuePair> children(object) {
+    // TODO(jacobr): be lazier about enumerating contents of Iterables that
+    // are not the built in Set or List types.
+    // TODO(jacobr): handle large Iterables better.
+    // TODO(jacobr): consider only using numeric indices
+    var children = LinkedHashSet<NameValuePair>();
+    children.addAll(IterableSpan(0, object.length, object).children());
+    // TODO(jacobr): provide a link to show regular class properties here.
+    // required for subclasses of iterable, etc.
+    addMetadataChildren(object, children);
+    return children.toList();
+  }
+}
+
+class NamedConstructorFormatter implements Formatter {
+  accept(object, config) => object is NamedConstructor;
+
+  // TODO(bmilligan): Display the signature of the named constructor as the
+  // preview.
+  String preview(object) => 'Named Constructor';
+
+  bool hasChildren(object) => true;
+
+  List<NameValuePair> children(object) => <NameValuePair>[
+        NameValuePair(
+            name: 'JavaScript Function',
+            value: object,
+            config: JsonMLConfig.skipDart)
+      ];
+}
+
+/// Formatter for synthetic MapEntry objects used to display contents of a Map
+/// cleanly.
+class MapEntryFormatter implements Formatter {
+  accept(object, config) => object is MapEntry;
+
+  String preview(object) {
+    MapEntry entry = object;
+    return '${safePreview(entry.key, JsonMLConfig.none)} => ${safePreview(entry.value, JsonMLConfig.none)}';
+  }
+
+  bool hasChildren(object) => true;
+
+  List<NameValuePair> children(object) => <NameValuePair>[
+        NameValuePair(
+            name: 'key', value: object.key, config: JsonMLConfig.keyToString),
+        NameValuePair(name: 'value', value: object.value)
+      ];
+}
+
+/// Formatter for Dart Iterable objects including List and Set.
+class HeritageClauseFormatter implements Formatter {
+  bool accept(object, config) => object is HeritageClause;
+
+  String preview(object) {
+    HeritageClause clause = object;
+    var typeNames = clause.types.map(getTypeName);
+    return '${clause.name} ${typeNames.join(", ")}';
+  }
+
+  bool hasChildren(object) => true;
+
+  List<NameValuePair> children(object) {
+    HeritageClause clause = object;
+    var children = <NameValuePair>[];
+    for (var type in clause.types) {
+      children.add(NameValuePair(value: type, config: JsonMLConfig.asClass));
+    }
+    return children;
+  }
+}
+
+/// Formatter for synthetic IterableSpan objects used to display contents of
+/// an Iterable cleanly.
+class IterableSpanFormatter implements Formatter {
+  accept(object, config) => object is IterableSpan;
+
+  String preview(object) {
+    return '[${object.start}...${object.end - 1}]';
+  }
+
+  bool hasChildren(object) => true;
+
+  List<NameValuePair> children(object) => object.children();
+}
+
+/// Formatter for Dart Errors and Exceptions.
+class ErrorAndExceptionFormatter extends ObjectFormatter {
+  static final RegExp _pattern = RegExp(r'\d+\:\d+');
+
+  accept(object, config) => object is Error || object is Exception;
+
+  bool hasChildren(object) => true;
+
+  String preview(object) {
+    var trace = dart.stackTrace(object);
+    // TODO(vsm): Pull our stack mapping logic here.  We should aim to
+    // provide the first meaningful stack frame.
+    var line = '$trace'.split('\n').firstWhere(
+        (l) =>
+            l.contains(_pattern) &&
+            !l.contains('dart:sdk') &&
+            !l.contains('dart_sdk'),
+        orElse: () => null);
+    return line != null ? '${object} at ${line}' : '${object}';
+  }
+
+  List<NameValuePair> children(object) {
+    var trace = dart.stackTrace(object);
+    var entries = LinkedHashSet<NameValuePair>();
+    entries.add(NameValuePair(name: 'stackTrace', value: trace));
+    addInstanceMembers(object, entries);
+    addMetadataChildren(object, entries);
+    return entries.toList();
+  }
+
+  // Add an ObjectFormatter view underneath.
+  void addInstanceMembers(object, Set<NameValuePair> ret) {
+    ret.add(NameValuePair(
+        name: "[[instance members]]",
+        value: object,
+        config: JsonMLConfig.asObject));
+  }
+}
+
+class StackTraceFormatter implements Formatter {
+  accept(object, config) => object is StackTrace;
+
+  String preview(object) => 'StackTrace';
+
+  bool hasChildren(object) => true;
+
+  // Using the stack_trace formatting would be ideal, but adding the
+  // dependency or re-writing the code is too messy, so each line of the
+  // StackTrace will be added as its own child.
+  List<NameValuePair> children(object) => object
+      .toString()
+      .split('\n')
+      .map((line) => NameValuePair(
+          value: line.replaceFirst(RegExp(r'^\s+at\s'), ''), hideName: true))
+      .toList();
+}
+
+class ClassFormatter implements Formatter {
+  accept(object, config) => config == JsonMLConfig.asClass;
+
+  String preview(type) {
+    var implements = dart.getImplements(type);
+    var typeName = getTypeName(type);
+    if (implements != null) {
+      var typeNames = implements().map(getTypeName);
+      return '${typeName} implements ${typeNames.join(", ")}';
+    } else {
+      return typeName;
+    }
+  }
+
+  bool hasChildren(object) => true;
+
+  List<NameValuePair> children(type) {
+    // TODO(jacobr): add other entries describing the class such as
+    // implemented interfaces, and methods.
+    var ret = LinkedHashSet<NameValuePair>();
+
+    var staticProperties = Set<NameValuePair>();
+    var staticMethods = Set<NameValuePair>();
+    // Static fields and properties.
+    addPropertiesFromSignature(
+        dart.getStaticFields(type), staticProperties, type, false);
+    addPropertiesFromSignature(
+        dart.getStaticGetters(type), staticProperties, type, false);
+    // static methods.
+    addPropertiesFromSignature(
+        dart.getStaticMethods(type), staticMethods, type, false);
+
+    if (staticProperties.isNotEmpty || staticMethods.isNotEmpty) {
+      ret
+        ..add(NameValuePair(value: '[[Static members]]', hideName: true))
+        ..addAll(sortProperties(staticProperties))
+        ..addAll(sortProperties(staticMethods));
+    }
+
+    // instance methods.
+    var instanceMethods = Set<NameValuePair>();
+    // Instance methods are defined on the prototype not the constructor object.
+    addPropertiesFromSignature(dart.getMethods(type), instanceMethods,
+        JS('', '#.prototype', type), false,
+        tagTypes: true);
+    if (instanceMethods.isNotEmpty) {
+      ret
+        ..add(NameValuePair(value: '[[Instance Methods]]', hideName: true))
+        ..addAll(sortProperties(instanceMethods));
+    }
+
+    var mixin = dart.getMixin(type);
+    if (mixin != null) {
+      // TODO(jmesserly): this can only be one value.
+      ret.add(NameValuePair(
+          name: '[[Mixins]]', value: HeritageClause('mixins', [mixin])));
+    }
+
+    var baseProto = JS('', '#.__proto__', type);
+    if (baseProto != null && !dart.isJsInterop(baseProto)) {
+      ret.add(NameValuePair(
+          name: "[[base class]]",
+          value: baseProto,
+          config: JsonMLConfig.asClass));
+    }
+
+    // TODO(jacobr): add back fields for named constructors.
+    return ret.toList();
+  }
+}
+
+class TypeFormatter implements Formatter {
+  accept(object, config) => object is Type;
+
+  String preview(object) => object.toString();
+
+  bool hasChildren(object) => false;
+
+  List<NameValuePair> children(object) => [];
+}
+
+typedef String StackTraceMapper(String stackTrace);
+
+/// Hook for other parts of the SDK To use to map JS stack traces to Dart
+/// stack traces.
+///
+/// Raw JS stack traces are used if $dartStackTraceUtility has not been
+/// specified.
+StackTraceMapper get stackTraceMapper {
+  var _util = JS('', r'#.$dartStackTraceUtility', dart.global_);
+  return _util != null ? JS('!', '#.mapper', _util) : null;
+}
+
+/// This entry point is automatically invoked by the code generated by
+/// Dart Dev Compiler
+registerDevtoolsFormatter() {
+  JS('', '#.devtoolsFormatters = [#]', dart.global_, _devtoolsFormatter);
+}
+
+// These methods are exposed here for debugger tests.
+//
+// TODO(jmesserly): these are not exports because there is existing code that
+// calls into them from JS. Currently `dartdevc` always resolves exports at
+// compile time, so there is no need to make exports available at runtime by
+// copying properties. For that reason we cannot use re-export.
+//
+// If these methods are only for tests, we should move them here, or change the
+// tests to call the methods directly on dart:_runtime.
+List<String> getModuleNames() => dart.getModuleNames();
+getModuleLibraries(String name) => dart.getModuleLibraries(name);
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/foreign_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/foreign_helper.dart
new file mode 100644
index 0000000..588d789
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/foreign_helper.dart
@@ -0,0 +1,285 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart._foreign_helper;
+
+/**
+ * Emits a JavaScript code fragment parameterized by arguments.
+ *
+ * Hash characters `#` in the [codeTemplate] are replaced in left-to-right order
+ * with expressions that contain the values of, or evaluate to, the arguments.
+ * The number of hash marks must match the number or arguments.  Although
+ * declared with arguments [arg0] through [arg2], the form actually has no limit
+ * on the number of arguments.
+ *
+ * The [typeDescription] argument is interpreted as a description of the
+ * behavior of the JavaScript code.  Currently it describes the types that may
+ * be returned by the expression, with the additional behavior that the returned
+ * values may be fresh instances of the types.  The type information must be
+ * correct as it is trusted by the compiler in optimizations, and it must be
+ * precise as possible since it is used for native live type analysis to
+ * tree-shake large parts of the DOM libraries.  If poorly written, the
+ * [typeDescription] will cause unnecessarily bloated programs.  (You can check
+ * for this by compiling with `--verbose`; there is an info message describing
+ * the number of native (DOM) types that can be removed, which usually should be
+ * greater than zero.)
+ *
+ * The [typeDescription] is a [String] which contains a union of types separated
+ * by vertical bar `|` symbols, e.g.  `"num|String"` describes the union of
+ * numbers and Strings.  There is no type in Dart that is this precise.  The
+ * Dart alternative would be `Object` or `dynamic`, but these types imply that
+ * the JS-code might also be creating instances of all the DOM types.  If `null`
+ * is possible, it must be specified explicitly, e.g. `"String|Null"`.
+ * [typeDescription] has several extensions to help describe the behavior more
+ * accurately.  In addition to the union type already described:
+ *
+ *  + `=Object` is a plain JavaScript object.  Some DOM methods return instances
+ *     that have no corresponding Dart type (e.g. cross-frame documents),
+ *     `=Object` can be used to describe these untyped' values.
+ *
+ *  + `var` (or empty string).  If the entire [typeDescription] is `var` (or
+ *    empty string) then the type is `dynamic` but the code is known to not
+ *    create any instances.
+ *
+ * Examples:
+ *
+ *     // Parent window might be an opaque cross-frame window.
+ *     var thing = JS('=Object|Window', '#.parent', myWindow);
+ *
+ * Guidelines:
+ *
+ *  + Do not use any parameter, local, method or field names in the
+ *    [codeTemplate].  These names are all subject to arbitrary renaming by the
+ *    compiler.  Pass the values in via `#` substition, and test with the
+ *    `--minify` dart2js command-line option.
+ *
+ *  + The substituted expressions are values, not locations.
+ *
+ *        JS('void', '# += "x"', this.field);
+ *
+ *    `this.field` might not be a substituted as a reference to the field.  The
+ *    generated code might accidentally work as intended, but it also might be
+ *
+ *        var t1 = this.field;
+ *        t1 += "x";
+ *
+ *    or
+ *
+ *        this.get$field() += "x";
+ *
+ *    The remedy in this case is to expand the `+=` operator, leaving all
+ *    references to the Dart field as Dart code:
+ *
+ *        this.field = JS<String>('!', '# + "x"', this.field);
+ *
+ *  + Never use `#` in function bodies.
+ *
+ *    This is a variation on the previous guideline.  Since `#` is replaced with
+ *    an *expression* and the expression is only valid in the immediate context,
+ *    `#` should never appear in a function body.  Doing so might defer the
+ *    evaluation of the expression, and its side effects, until the function is
+ *    called.
+ *
+ *    For example,
+ *
+ *        var value = foo();
+ *        var f = JS('', 'function(){return #}', value)
+ *
+ *    might result in no immediate call to `foo` and a call to `foo` on every
+ *    call to the JavaScript function bound to `f`.  This is better:
+ *
+ *        var f = JS('',
+ *            '(function(val) { return function(){return val}; })(#)', value);
+ *
+ *    Since `#` occurs in the immediately evaluated expression, the expression
+ *    is immediately evaluated and bound to `val` in the immediate call.
+ *
+ *
+ * Additional notes.
+ *
+ * In the future we may extend [typeDescription] to include other aspects of the
+ * behavior, for example, separating the returned types from the instantiated
+ * types, or including effects to allow the compiler to perform more
+ * optimizations around the code.  This might be an extension of [JS] or a new
+ * function similar to [JS] with additional arguments for the new information.
+ */
+// Add additional optional arguments if needed. The method is treated internally
+// as a variable argument method.
+T JS<T extends Object>(String typeDescription, String codeTemplate,
+    [arg0,
+    arg1,
+    arg2,
+    arg3,
+    arg4,
+    arg5,
+    arg6,
+    arg7,
+    arg8,
+    arg9,
+    arg10,
+    arg11,
+    arg12,
+    arg13,
+    arg14,
+    arg15,
+    arg16,
+    arg17,
+    arg18,
+    arg19]) {}
+
+/// Annotates the compiled Js name for fields and methods.
+/// Similar behaviour to `JS` from `package:js/js.dart` (but usable from runtime
+/// files), and not to be confused with `JSName` from `js_helper` (which deals
+/// with names of externs).
+// TODO(jmesserly): remove this in favor of js_helper's `@JSName`
+// (Currently they have slightly different semantics, but they can be unified.)
+class JSExportName {
+  final String name;
+  const JSExportName(this.name);
+}
+
+/**
+ * Returns the JavaScript constructor function for Dart's Object class.
+ * This can be used for type tests, as in
+ *
+ *     if (JS<bool>('!', '# instanceof #', obj, JS_DART_OBJECT_CONSTRUCTOR()))
+ *       ...
+ */
+JS_DART_OBJECT_CONSTRUCTOR() {}
+
+/**
+ * Returns the interceptor for class [type].  The interceptor is the type's
+ * constructor's `prototype` property.  [type] will typically be the class, not
+ * an interface, e.g. `JS_INTERCEPTOR_CONSTANT(JSInt)`, not
+ * `JS_INTERCEPTOR_CONSTANT(int)`.
+ */
+JS_INTERCEPTOR_CONSTANT(Type type) {}
+
+/**
+ * Returns the prefix used for generated is checks on classes.
+ */
+String JS_OPERATOR_IS_PREFIX() {}
+
+/**
+ * Returns the prefix used for generated type argument substitutions on classes.
+ */
+String JS_OPERATOR_AS_PREFIX() {}
+
+/// Returns the name of the class `Object` in the generated code.
+String JS_OBJECT_CLASS_NAME() {}
+
+/// Returns the name of the class `Null` in the generated code.
+String JS_NULL_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.
+ */
+String JS_IS_INDEXABLE_FIELD_NAME() {}
+
+/// Returns the name used for generated function types on classes and methods.
+String JS_SIGNATURE_NAME() {}
+
+/// Returns the name used to tag typedefs.
+String JS_TYPEDEF_TAG() {}
+
+/// 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 JS name for [name] from the Namer.
+String JS_GET_NAME(String name) {}
+
+/// Returns the state of a flag that is determined by the state of the compiler
+/// when the program has been analyzed.
+bool JS_GET_FLAG(String name) {}
+
+/**
+ * Pretend [code] is executed.  Generates no executable code.  This is used to
+ * model effects at some other point in external code.  For example, the
+ * following models an assignment to foo with an unknown value.
+ *
+ *     var foo;
+ *
+ *     main() {
+ *       JS_EFFECT((_){ foo = _; })
+ *     }
+ *
+ * TODO(sra): Replace this hack with something to mark the volatile or
+ * externally initialized elements.
+ */
+void JS_EFFECT(Function code) {
+  code(null);
+}
+
+/**
+ * Use this class for creating constants that hold JavaScript code.
+ * For example:
+ *
+ * const constant = JS_CONST('typeof window != "undefined");
+ *
+ * This code will generate:
+ * $.JS_CONST_1 = typeof window != "undefined";
+ */
+class JS_CONST {
+  final String code;
+  const JS_CONST(this.code);
+}
+
+/**
+ * JavaScript string concatenation. Inputs must be Strings.  Corresponds to the
+ * HStringConcat SSA instruction and may be constant-folded.
+ */
+String JS_STRING_CONCAT(String a, String b) {
+  // This body is unused, only here for type analysis.
+  return JS<String>('!', '# + #', a, b);
+}
+
+/// Same `@rest` annotation and `spread` function as in
+/// `package:js/src/varargs.dart`.
+///
+/// Runtime files cannot import packages, which is why we have an ad-hoc copy.
+
+class _Rest {
+  const _Rest();
+}
+
+const _Rest rest = _Rest();
+
+dynamic spread(args) {
+  throw StateError('The spread function cannot be called, '
+      'it should be compiled away.');
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/identity_hash_map.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/identity_hash_map.dart
new file mode 100644
index 0000000..04107cc
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/identity_hash_map.dart
@@ -0,0 +1,137 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart._js_helper;
+
+class IdentityMap<K, V> extends InternalMap<K, V> {
+  final _map = JS('', 'new Map()');
+
+  // We track the number of modifications done to the key set of the
+  // hash map to be able to throw when the map is modified while being
+  // iterated over.
+  //
+  // Value cycles after 2^30 modifications so that modification counts are
+  // always unboxed (Smi) values. Modification detection will be missed if you
+  // make exactly some multiple of 2^30 modifications between advances of an
+  // iterator.
+  @notNull
+  int _modifications = 0;
+
+  IdentityMap();
+  IdentityMap.from(JSArray entries) {
+    var map = _map;
+    for (int i = 0, n = JS<int>('!', '#.length', entries); i < n; i += 2) {
+      JS('', '#.set(#[#], #[#])', map, entries, i, entries, i + 1);
+    }
+  }
+
+  int get length => JS<int>('!', '#.size', _map);
+  bool get isEmpty => JS<bool>('!', '#.size == 0', _map);
+  bool get isNotEmpty => JS<bool>('!', '#.size != 0', _map);
+
+  Iterable<K> get keys => _JSMapIterable<K>(this, true);
+  Iterable<V> get values => _JSMapIterable<V>(this, false);
+
+  bool containsKey(Object key) {
+    return JS<bool>('!', '#.has(#)', _map, key);
+  }
+
+  bool containsValue(Object value) {
+    for (var v in JS('', '#.values()', _map)) {
+      if (v == value) return true;
+    }
+    return false;
+  }
+
+  void addAll(Map<K, V> other) {
+    if (other.isNotEmpty) {
+      var map = _map;
+      other.forEach((key, value) {
+        JS('', '#.set(#, #)', map, key, value);
+      });
+      _modifications = (_modifications + 1) & 0x3ffffff;
+    }
+  }
+
+  V operator [](Object key) {
+    V value = JS('', '#.get(#)', _map, key);
+    return value == null ? null : value; // coerce undefined to null.
+  }
+
+  void operator []=(K key, V value) {
+    var map = _map;
+    int length = JS('!', '#.size', map);
+    JS('', '#.set(#, #)', map, key, value);
+    if (length != JS<int>('!', '#.size', map)) {
+      _modifications = (_modifications + 1) & 0x3ffffff;
+    }
+  }
+
+  V putIfAbsent(K key, V ifAbsent()) {
+    if (JS<bool>('!', '#.has(#)', _map, key)) {
+      return JS('', '#.get(#)', _map, key);
+    }
+    V value = ifAbsent();
+    if (value == null) value = null; // coerce undefined to null.
+    JS('', '#.set(#, #)', _map, key, value);
+    _modifications = (_modifications + 1) & 0x3ffffff;
+    return value;
+  }
+
+  V remove(Object key) {
+    V value = JS('', '#.get(#)', _map, key);
+    if (JS<bool>('!', '#.delete(#)', _map, key)) {
+      _modifications = (_modifications + 1) & 0x3ffffff;
+    }
+    return value == null ? null : value; // coerce undefined to null.
+  }
+
+  void clear() {
+    if (JS<int>('!', '#.size', _map) > 0) {
+      JS('', '#.clear()', _map);
+      _modifications = (_modifications + 1) & 0x3ffffff;
+    }
+  }
+}
+
+class _JSMapIterable<E> extends EfficientLengthIterable<E> {
+  final InternalMap _map;
+  @notNull
+  final bool _isKeys;
+  _JSMapIterable(this._map, this._isKeys);
+
+  int get length => _map.length;
+  bool get isEmpty => _map.isEmpty;
+
+  @JSExportName('Symbol.iterator')
+  _jsIterator() {
+    var map = _map;
+    var iterator =
+        JS('', '# ? #.keys() : #.values()', _isKeys, map._map, map._map);
+    int modifications = map._modifications;
+    return JS(
+        '',
+        '''{
+      next() {
+        if (# != #) {
+          throw #;
+        }
+        return #.next();
+      }
+    }''',
+        modifications,
+        map._modifications,
+        ConcurrentModificationError(map),
+        iterator);
+  }
+
+  Iterator<E> get iterator => DartIterator<E>(_jsIterator());
+
+  bool contains(Object element) =>
+      _isKeys ? _map.containsKey(element) : _map.containsValue(element);
+
+  void forEach(void f(E element)) {
+    for (var entry in this) f(entry);
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/interceptors.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/interceptors.dart
new file mode 100644
index 0000000..6ddd96b
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/interceptors.dart
@@ -0,0 +1,233 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart._interceptors;
+
+import 'dart:collection';
+import 'dart:_internal' hide Symbol;
+import 'dart:_js_helper';
+import 'dart:_foreign_helper' show JS, JSExportName;
+import 'dart:math' show Random, ln2;
+import 'dart:_runtime' as dart;
+
+part 'js_array.dart';
+part 'js_number.dart';
+part 'js_string.dart';
+
+// TODO(jmesserly): remove, this doesn't do anything for us.
+abstract class Interceptor {
+  const Interceptor();
+
+  // Use native JS toString method instead of standard Dart Object.toString.
+  String toString() => JS<String>('!', '#.toString()', this);
+}
+
+// TODO(jmesserly): remove
+getInterceptor(obj) => obj;
+
+/**
+ * The interceptor class for [bool].
+ */
+@JsPeerInterface(name: 'Boolean')
+class JSBool extends Interceptor implements bool {
+  const JSBool();
+
+  // Note: if you change this, also change the function [S].
+  @notNull
+  String toString() => JS<String>('!', r'String(#)', this);
+
+  // The values here are SMIs, co-prime and differ about half of the bit
+  // positions, including the low bit, so they are different mod 2^k.
+  @notNull
+  int get hashCode => this ? (2 * 3 * 23 * 3761) : (269 * 811);
+
+  @notNull
+  bool operator &(@nullCheck bool other) =>
+      JS<bool>('!', "# && #", other, this);
+
+  @notNull
+  bool operator |(@nullCheck bool other) =>
+      JS<bool>('!', "# || #", other, this);
+
+  @notNull
+  bool operator ^(@nullCheck bool other) => !identical(this, other);
+
+  Type get runtimeType => bool;
+}
+
+/**
+ * The supertype for JSString and JSArray. Used by the backend as to
+ * have a type mask that contains the objects that we can use the
+ * native JS [] operator and length on.
+ */
+abstract class JSIndexable<E> {
+  int get length;
+  E operator [](int index);
+}
+
+/**
+ * The interface implemented by JavaScript objects.  These are methods in
+ * addition to the regular Dart Object methods like [Object.hashCode].
+ *
+ * This is the type that should be exported by a JavaScript interop library.
+ */
+abstract class JSObject {}
+
+/**
+ * Interceptor base class for JavaScript objects not recognized as some more
+ * specific native type.
+ */
+abstract class JavaScriptObject extends Interceptor implements JSObject {
+  const JavaScriptObject();
+
+  // It would be impolite to stash a property on the object.
+  int get hashCode => 0;
+
+  Type get runtimeType => JSObject;
+}
+
+/**
+ * Interceptor for plain JavaScript objects created as JavaScript object
+ * literals or `new Object()`.
+ */
+class PlainJavaScriptObject extends JavaScriptObject {
+  const PlainJavaScriptObject();
+}
+
+/**
+ * Interceptor for unclassified JavaScript objects, typically objects with a
+ * non-trivial prototype chain.
+ *
+ * This class also serves as a fallback for unknown JavaScript exceptions.
+ */
+class UnknownJavaScriptObject extends JavaScriptObject {
+  const UnknownJavaScriptObject();
+
+  String toString() => JS<String>('!', 'String(#)', this);
+}
+
+class NativeError extends Interceptor {
+  String dartStack() => JS<String>('!', '#.stack', this);
+}
+
+// Note that this needs to be in interceptors.dart in order for
+// it to be picked up as an extension type.
+@JsPeerInterface(name: 'TypeError')
+class JSNoSuchMethodError extends NativeError implements NoSuchMethodError {
+  static final _nullError = RegExp(r"^Cannot read property '(.+)' of null$");
+  static final _notAFunction = RegExp(r"^(.+) is not a function$");
+  static final _extensionName = RegExp(r"^Symbol\(dartx\.(.+)\)$");
+  static final _privateName = RegExp(r"^Symbol\((_.+)\)$");
+
+  String _fieldName(String message) {
+    var match = _nullError.firstMatch(message);
+    if (match == null) return null;
+    var name = match[1];
+    match = _extensionName.firstMatch(name) ?? _privateName.firstMatch(name);
+    return match != null ? match[1] : name;
+  }
+
+  String _functionCallTarget(String message) {
+    var match = _notAFunction.firstMatch(message);
+    return match != null ? match[1] : null;
+  }
+
+  String dartStack() {
+    var stack = super.dartStack();
+    // Strip TypeError from first line.
+    stack = toString() + '\n' + stack.split('\n').sublist(1).join('\n');
+    return stack;
+  }
+
+  StackTrace get stackTrace => dart.stackTrace(this);
+
+  String toString() {
+    String message = JS('!', '#.message', this);
+    var callTarget = _functionCallTarget(message);
+    if (callTarget != null) {
+      return "NoSuchMethodError: tried to call a non-function, such as null: "
+          "'$callTarget'";
+    }
+    // TODO(vsm): Distinguish between null reference errors and other
+    // TypeErrors.  We should not get non-null TypeErrors from DDC code,
+    // but we may from native JavaScript.
+    var name = _fieldName(message);
+    if (name == null) {
+      // Not a Null NSM error: fallback to JS.
+      return JS<String>('!', '#.toString()', this);
+    }
+    return "NoSuchMethodError: invalid member on null: '$name'";
+  }
+}
+
+@JsPeerInterface(name: 'Function')
+class JSFunction extends Interceptor {
+  toString() {
+    // If the function is a Type object, we should just display the type name.
+    //
+    // Regular Dart code should typically get wrapped type objects instead of
+    // raw type (aka JS constructor) objects, however raw type objects can be
+    // exposed to Dart code via JS interop or debugging tools.
+    if (dart.isType(this)) return dart.typeName(this);
+
+    return JS<String>('!', r'"Closure: " + # + " from: " + #',
+        dart.typeName(dart.getReifiedType(this)), this);
+  }
+
+  // TODO(jmesserly): remove these once we canonicalize tearoffs.
+  operator ==(other) {
+    if (other == null) return false;
+    var boundObj = JS<Object>('', '#._boundObject', this);
+    if (boundObj == null) return JS<bool>('!', '# === #', this, other);
+    return JS(
+        'bool',
+        '# === #._boundObject && #._boundMethod === #._boundMethod',
+        boundObj,
+        other,
+        this,
+        other);
+  }
+
+  get hashCode {
+    var boundObj = JS<Object>('', '#._boundObject', this);
+    if (boundObj == null) return identityHashCode(this);
+
+    var boundMethod = JS<Object>('!', '#._boundMethod', this);
+    int hash = (17 * 31 + boundObj.hashCode) & 0x1fffffff;
+    return (hash * 31 + identityHashCode(boundMethod)) & 0x1fffffff;
+  }
+
+  get runtimeType => dart.wrapType(dart.getReifiedType(this));
+}
+
+/// A class used for implementing `null` tear-offs.
+class JSNull {
+  toString() => 'null';
+  noSuchMethod(Invocation i) => dart.defaultNoSuchMethod(null, i);
+}
+
+final Object jsNull = JSNull();
+
+// Note that this needs to be in interceptors.dart in order for
+// it to be picked up as an extension type.
+@JsPeerInterface(name: 'RangeError')
+class JSRangeError extends Interceptor implements ArgumentError {
+  StackTrace get stackTrace => dart.stackTrace(this);
+
+  get invalidValue => null;
+  get name => null;
+  get message => JS<String>('!', '#.message', this);
+
+  String toString() => "Invalid argument: $message";
+}
+
+// Obsolete in dart dev compiler. Added only so that the same version of
+// dart:html can be used in dart2js an dev compiler.
+// Warning: calls to these methods need to be removed before custom elements
+// and cross-frame dom objects behave correctly in ddc.
+// See https://github.com/dart-lang/sdk/issues/28326
+findInterceptorConstructorForType(Type type) {}
+findConstructorForNativeSubclassType(Type type, String name) {}
+getNativeInterceptor(object) {}
+setDispatchProperty(object, value) {}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/isolate_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/isolate_helper.dart
new file mode 100644
index 0000000..490c4b9
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/isolate_helper.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart._isolate_helper;
+
+import 'dart:_runtime' as dart;
+import 'dart:async';
+import 'dart:_foreign_helper' show JS;
+
+/// Deprecated way of initializing `main()` in DDC, typically called from JS.
+@deprecated
+void startRootIsolate(main, args) {
+  if (args == null) args = <String>[];
+  if (args is List) {
+    if (args is! List<String>) args = List<String>.from(args);
+    // DDC attaches signatures only when torn off, and the typical way of
+    // getting `main` via the JS ABI won't do this. So use JS to invoke main.
+    if (JS<bool>('!', 'typeof # == "function"', main)) {
+      // JS will ignore extra arguments.
+      JS('', '#(#, #)', main, args, null);
+    } else {
+      // Not a function. Use a dynamic call to throw an error.
+      (main as dynamic)(args);
+    }
+  } else {
+    throw ArgumentError("Arguments to main must be a List: $args");
+  }
+}
+
+// TODO(vsm): Other libraries import global from here.  Consider replacing
+// those uses to just refer to the one in dart:runtime.
+final global = dart.global_;
+
+class TimerImpl implements Timer {
+  final bool _once;
+  int _handle;
+  int _tick = 0;
+
+  TimerImpl(int milliseconds, void callback()) : _once = true {
+    if (hasTimer()) {
+      void internalCallback() {
+        _handle = null;
+        dart.removeAsyncCallback();
+        _tick = 1;
+        callback();
+      }
+
+      dart.addAsyncCallback();
+
+      _handle = JS(
+          'int', '#.setTimeout(#, #)', global, internalCallback, milliseconds);
+    } else {
+      throw UnsupportedError("`setTimeout()` not found.");
+    }
+  }
+
+  TimerImpl.periodic(int milliseconds, void callback(Timer timer))
+      : _once = false {
+    if (hasTimer()) {
+      dart.addAsyncCallback();
+      int start = JS<int>('!', 'Date.now()');
+      _handle = JS<int>('!', '#.setInterval(#, #)', global, () {
+        int tick = this._tick + 1;
+        if (milliseconds > 0) {
+          int duration = JS<int>('!', 'Date.now()') - start;
+          if (duration > (tick + 1) * milliseconds) {
+            tick = duration ~/ milliseconds;
+          }
+        }
+        this._tick = tick;
+        callback(this);
+      }, milliseconds);
+    } else {
+      throw UnsupportedError("Periodic timer.");
+    }
+  }
+
+  int get tick => _tick;
+
+  void cancel() {
+    if (hasTimer()) {
+      if (_handle == null) return;
+      dart.removeAsyncCallback();
+      if (_once) {
+        JS('void', '#.clearTimeout(#)', global, _handle);
+      } else {
+        JS('void', '#.clearInterval(#)', global, _handle);
+      }
+      _handle = null;
+    } else {
+      throw UnsupportedError("Canceling a timer.");
+    }
+  }
+
+  bool get isActive => _handle != null;
+}
+
+bool hasTimer() {
+  return JS('', '#.setTimeout', global) != null;
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart
new file mode 100644
index 0000000..f064b24
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart
@@ -0,0 +1,694 @@
+// Copyright (c) 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 dart._interceptors;
+
+/**
+ * The interceptor class for [List]. The compiler recognizes this
+ * class as an interceptor, and changes references to [:this:] to
+ * actually use the receiver of the method, which is generated as an extra
+ * argument added to each member.
+ */
+@JsPeerInterface(name: 'Array')
+class JSArray<E> implements List<E>, JSIndexable<E> {
+  const JSArray();
+
+  /**
+   * Constructor for adding type parameters to an existing JavaScript
+   * Array. Used for creating literal lists.
+   */
+  factory JSArray.of(list) {
+    // TODO(sra): Move this to core.List for better readability.
+    //
+    // TODO(jmesserly): this uses special compiler magic to close over the
+    // parameterized ES6 'JSArray' class.
+    JS('', '#.__proto__ = JSArray.prototype', list);
+    return JS('-dynamic', '#', list);
+  }
+
+  // TODO(jmesserly): consider a fixed array subclass instead.
+  factory JSArray.fixed(list) {
+    JS('', '#.__proto__ = JSArray.prototype', list);
+    JS('', r'#.fixed$length = Array', list);
+    return JS('-dynamic', '#', list);
+  }
+
+  factory JSArray.unmodifiable(list) {
+    JS('', '#.__proto__ = JSArray.prototype', list);
+    JS('', r'#.fixed$length = Array', list);
+    JS('', r'#.immutable$list = Array', list);
+    return JS('-dynamic', '#', list);
+  }
+
+  static void markFixedList(list) {
+    // Functions are stored in the hidden class and not as properties in
+    // the object. We never actually look at the value, but only want
+    // to know if the property exists.
+    JS('', r'#.fixed$length = Array', list);
+  }
+
+  static void markUnmodifiableList(list) {
+    // Functions are stored in the hidden class and not as properties in
+    // the object. We never actually look at the value, but only want
+    // to know if the property exists.
+    JS('', r'#.fixed$length = Array', list);
+    JS('', r'#.immutable$list = Array', list);
+  }
+
+  checkMutable(reason) {
+    if (JS<bool>('!', r'#.immutable$list', this)) {
+      throw UnsupportedError(reason);
+    }
+  }
+
+  checkGrowable(reason) {
+    if (JS<bool>('!', r'#.fixed$length', this)) {
+      throw UnsupportedError(reason);
+    }
+  }
+
+  List<R> cast<R>() => List.castFrom<E, R>(this);
+  void add(E value) {
+    checkGrowable('add');
+    JS('void', r'#.push(#)', this, value);
+  }
+
+  E removeAt(@nullCheck int index) {
+    checkGrowable('removeAt');
+    if (index < 0 || index >= length) {
+      throw RangeError.value(index);
+    }
+    return JS('-dynamic', r'#.splice(#, 1)[0]', this, index);
+  }
+
+  void insert(@nullCheck int index, E value) {
+    checkGrowable('insert');
+    if (index < 0 || index > length) {
+      throw RangeError.value(index);
+    }
+    JS('void', r'#.splice(#, 0, #)', this, index, value);
+  }
+
+  void insertAll(@nullCheck int index, Iterable<E> iterable) {
+    checkGrowable('insertAll');
+    RangeError.checkValueInInterval(index, 0, this.length, "index");
+    if (iterable is! EfficientLengthIterable) {
+      iterable = iterable.toList();
+    }
+    @nullCheck
+    int insertionLength = iterable.length;
+    this.length += insertionLength;
+    int end = index + insertionLength;
+    this.setRange(end, this.length, this, index);
+    this.setRange(index, end, iterable);
+  }
+
+  void setAll(@nullCheck int index, Iterable<E> iterable) {
+    checkMutable('setAll');
+    RangeError.checkValueInInterval(index, 0, this.length, "index");
+    for (var element in iterable) {
+      this[index++] = element;
+    }
+  }
+
+  E removeLast() {
+    checkGrowable('removeLast');
+    if (length == 0) throw diagnoseIndexError(this, -1);
+    return JS('var', r'#.pop()', this);
+  }
+
+  bool remove(Object element) {
+    checkGrowable('remove');
+    var length = this.length;
+    for (int i = 0; i < length; i++) {
+      if (this[i] == element) {
+        JS('var', r'#.splice(#, 1)', this, i);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Removes elements matching [test] from [this] List.
+   */
+  void removeWhere(bool test(E element)) {
+    checkGrowable('removeWhere');
+    _removeWhere(test, true);
+  }
+
+  void retainWhere(bool test(E element)) {
+    checkGrowable('retainWhere');
+    _removeWhere(test, false);
+  }
+
+  void _removeWhere(bool test(E element), bool removeMatching) {
+    // Performed in two steps, to avoid exposing an inconsistent state
+    // to the [test] function. First the elements to retain are found, and then
+    // the original list is updated to contain those elements.
+
+    // TODO(sra): Replace this algorithm with one that retains a list of ranges
+    // to be removed.  Most real uses remove 0, 1 or a few clustered elements.
+
+    List retained = [];
+    int end = this.length;
+    for (int i = 0; i < end; i++) {
+      // TODO(22407): Improve bounds check elimination to allow this JS code to
+      // be replaced by indexing.
+      E element = JS('-dynamic', '#[#]', this, i);
+      // !test() ensures bool conversion in checked mode.
+      if (!test(element) == removeMatching) {
+        retained.add(element);
+      }
+      if (this.length != end) throw ConcurrentModificationError(this);
+    }
+    if (retained.length == end) return;
+    this.length = retained.length;
+    @nullCheck
+    var length = retained.length;
+    for (int i = 0; i < length; i++) {
+      JS('', '#[#] = #[#]', this, i, retained, i);
+    }
+  }
+
+  Iterable<E> where(bool f(E element)) {
+    return WhereIterable<E>(this, f);
+  }
+
+  Iterable<T> expand<T>(Iterable<T> f(E element)) {
+    return ExpandIterable<E, T>(this, f);
+  }
+
+  void addAll(Iterable<E> collection) {
+    int i = this.length;
+    checkGrowable('addAll');
+    for (E e in collection) {
+      assert(i == this.length || (throw ConcurrentModificationError(this)));
+      i++;
+      JS('void', r'#.push(#)', this, e);
+    }
+  }
+
+  void clear() {
+    length = 0;
+  }
+
+  void forEach(void f(E element)) {
+    int end = this.length;
+    for (int i = 0; i < end; i++) {
+      // TODO(22407): Improve bounds check elimination to allow this JS code to
+      // be replaced by indexing.
+      var/*=E*/ element = JS('', '#[#]', this, i);
+      f(element);
+      if (this.length != end) throw ConcurrentModificationError(this);
+    }
+  }
+
+  Iterable<T> map<T>(T f(E element)) {
+    return MappedListIterable<E, T>(this, f);
+  }
+
+  String join([String separator = ""]) {
+    var length = this.length;
+    var list = List(length);
+    for (int i = 0; i < length; i++) {
+      list[i] = "${this[i]}";
+    }
+    return JS<String>('!', "#.join(#)", list, separator);
+  }
+
+  Iterable<E> take(int n) {
+    return SubListIterable<E>(this, 0, n);
+  }
+
+  Iterable<E> takeWhile(bool test(E value)) {
+    return TakeWhileIterable<E>(this, test);
+  }
+
+  Iterable<E> skip(int n) {
+    return SubListIterable<E>(this, n, null);
+  }
+
+  Iterable<E> skipWhile(bool test(E value)) {
+    return SkipWhileIterable<E>(this, test);
+  }
+
+  E reduce(E combine(E previousValue, E element)) {
+    int length = this.length;
+    if (length == 0) throw IterableElementError.noElement();
+    E value = this[0];
+    for (int i = 1; i < length; i++) {
+      // TODO(22407): Improve bounds check elimination to allow this JS code to
+      // be replaced by indexing.
+      var/*=E*/ element = JS('', '#[#]', this, i);
+      value = combine(value, element);
+      if (length != this.length) throw ConcurrentModificationError(this);
+    }
+    return value;
+  }
+
+  T fold<T>(T initialValue, T combine(T previousValue, E element)) {
+    var value = initialValue;
+    int length = this.length;
+    for (int i = 0; i < length; i++) {
+      // TODO(22407): Improve bounds check elimination to allow this JS code to
+      // be replaced by indexing.
+      var/*=E*/ element = JS('', '#[#]', this, i);
+      value = combine(value, element);
+      if (this.length != length) throw ConcurrentModificationError(this);
+    }
+    return value;
+  }
+
+  E firstWhere(bool test(E value), {E orElse()}) {
+    int end = this.length;
+    for (int i = 0; i < end; ++i) {
+      // TODO(22407): Improve bounds check elimination to allow this JS code to
+      // be replaced by indexing.
+      var/*=E*/ element = JS('', '#[#]', this, i);
+      if (test(element)) return element;
+      if (this.length != end) throw ConcurrentModificationError(this);
+    }
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E lastWhere(bool test(E element), {E orElse()}) {
+    int length = this.length;
+    for (int i = length - 1; i >= 0; i--) {
+      // TODO(22407): Improve bounds check elimination to allow this JS code to
+      // be replaced by indexing.
+      var/*=E*/ element = JS('', '#[#]', this, i);
+      if (test(element)) return element;
+      if (length != this.length) {
+        throw ConcurrentModificationError(this);
+      }
+    }
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E singleWhere(bool test(E element), {E orElse()}) {
+    int length = this.length;
+    E match = null;
+    bool matchFound = false;
+    for (int i = 0; i < length; i++) {
+      // TODO(22407): Improve bounds check elimination to allow this JS code to
+      // be replaced by indexing.
+      E element = JS('-dynamic', '#[#]', this, i);
+      if (test(element)) {
+        if (matchFound) {
+          throw IterableElementError.tooMany();
+        }
+        matchFound = true;
+        match = element;
+      }
+      if (length != this.length) {
+        throw ConcurrentModificationError(this);
+      }
+    }
+    if (matchFound) return match;
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E elementAt(int index) {
+    return this[index];
+  }
+
+  List<E> sublist(@nullCheck int start, [int end]) {
+    if (start < 0 || start > length) {
+      throw RangeError.range(start, 0, length, "start");
+    }
+    if (end == null) {
+      end = length;
+    } else {
+      @notNull
+      var _end = end;
+      if (_end < start || _end > length) {
+        throw RangeError.range(end, start, length, "end");
+      }
+    }
+    if (start == end) return <E>[];
+    return JSArray<E>.of(JS('', r'#.slice(#, #)', this, start, end));
+  }
+
+  Iterable<E> getRange(int start, int end) {
+    RangeError.checkValidRange(start, end, this.length);
+    return SubListIterable<E>(this, start, end);
+  }
+
+  E get first {
+    if (length > 0) return this[0];
+    throw IterableElementError.noElement();
+  }
+
+  E get last {
+    if (length > 0) return this[length - 1];
+    throw IterableElementError.noElement();
+  }
+
+  E get single {
+    if (length == 1) return this[0];
+    if (length == 0) throw IterableElementError.noElement();
+    throw IterableElementError.tooMany();
+  }
+
+  void removeRange(@nullCheck int start, @nullCheck int end) {
+    checkGrowable('removeRange');
+    RangeError.checkValidRange(start, end, this.length);
+    int deleteCount = end - start;
+    JS('', '#.splice(#, #)', this, start, deleteCount);
+  }
+
+  void setRange(@nullCheck int start, @nullCheck int end, Iterable<E> iterable,
+      [@nullCheck int skipCount = 0]) {
+    checkMutable('set range');
+
+    RangeError.checkValidRange(start, end, this.length);
+    int length = end - start;
+    if (length == 0) return;
+    RangeError.checkNotNegative(skipCount, "skipCount");
+
+    List<E> otherList;
+    int otherStart = 0;
+    // TODO(floitsch): Make this accept more.
+    if (iterable is List<E>) {
+      otherList = iterable;
+      otherStart = skipCount;
+    } else {
+      otherList = iterable.skip(skipCount).toList(growable: false);
+      otherStart = 0;
+    }
+    if (otherStart + length > otherList.length) {
+      throw IterableElementError.tooFew();
+    }
+    if (otherStart < start) {
+      // Copy backwards to ensure correct copy if [from] is this.
+      // TODO(sra): If [from] is the same Array as [this], we can copy without
+      // type annotation checks on the stores.
+      for (int i = length - 1; i >= 0; i--) {
+        // Use JS to avoid bounds check (the bounds check elimination
+        // optimzation is too weak). The 'E' type annotation is a store type
+        // check - we can't rely on iterable, it could be List<dynamic>.
+        E element = otherList[otherStart + i];
+        JS('', '#[#] = #', this, start + i, element);
+      }
+    } else {
+      for (int i = 0; i < length; i++) {
+        E element = otherList[otherStart + i];
+        JS('', '#[#] = #', this, start + i, element);
+      }
+    }
+  }
+
+  void fillRange(@nullCheck int start, @nullCheck int end, [E fillValue]) {
+    checkMutable('fill range');
+    RangeError.checkValidRange(start, end, this.length);
+    for (int i = start; i < end; i++) {
+      // Store is safe since [fillValue] type has been checked as parameter.
+      JS('', '#[#] = #', this, i, fillValue);
+    }
+  }
+
+  void replaceRange(
+      @nullCheck int start, @nullCheck int end, Iterable<E> replacement) {
+    checkGrowable('replace range');
+    RangeError.checkValidRange(start, end, this.length);
+    if (replacement is! EfficientLengthIterable) {
+      replacement = replacement.toList();
+    }
+    int removeLength = end - start;
+    @nullCheck
+    int insertLength = replacement.length;
+    if (removeLength >= insertLength) {
+      int delta = removeLength - insertLength;
+      int insertEnd = start + insertLength;
+      int newLength = this.length - delta;
+      this.setRange(start, insertEnd, replacement);
+      if (delta != 0) {
+        this.setRange(insertEnd, newLength, this, end);
+        this.length = newLength;
+      }
+    } else {
+      int delta = insertLength - removeLength;
+      int newLength = this.length + delta;
+      int insertEnd = start + insertLength; // aka. end + delta.
+      this.length = newLength;
+      this.setRange(insertEnd, newLength, this, end);
+      this.setRange(start, insertEnd, replacement);
+    }
+  }
+
+  bool any(bool test(E element)) {
+    int end = this.length;
+    for (int i = 0; i < end; i++) {
+      // TODO(22407): Improve bounds check elimination to allow this JS code to
+      // be replaced by indexing.
+      var/*=E*/ element = JS('', '#[#]', this, i);
+      if (test(element)) return true;
+      if (this.length != end) throw ConcurrentModificationError(this);
+    }
+    return false;
+  }
+
+  bool every(bool test(E element)) {
+    int end = this.length;
+    for (int i = 0; i < end; i++) {
+      // TODO(22407): Improve bounds check elimination to allow this JS code to
+      // be replaced by indexing.
+      E element = JS('-dynamic', '#[#]', this, i);
+      if (!test(element)) return false;
+      if (this.length != end) throw ConcurrentModificationError(this);
+    }
+    return true;
+  }
+
+  Iterable<E> get reversed => ReversedListIterable<E>(this);
+
+  void sort([int compare(E a, E b)]) {
+    checkMutable('sort');
+    if (compare == null) {
+      Sort.sort(this, (a, b) => Comparable.compare(a, b));
+    } else {
+      Sort.sort(this, compare);
+    }
+  }
+
+  void shuffle([Random random]) {
+    checkMutable('shuffle');
+    if (random == null) random = Random();
+    int length = this.length;
+    while (length > 1) {
+      int pos = random.nextInt(length);
+      length -= 1;
+      var tmp = this[length];
+      this[length] = this[pos];
+      this[pos] = tmp;
+    }
+  }
+
+  int indexOf(Object element, [@nullCheck int start = 0]) {
+    int length = this.length;
+    if (start >= length) {
+      return -1;
+    }
+    if (start < 0) {
+      start = 0;
+    }
+    for (int i = start; i < length; i++) {
+      if (this[i] == element) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  int lastIndexOf(Object element, [int _startIndex]) {
+    @notNull
+    int startIndex = _startIndex ?? this.length - 1;
+    if (startIndex >= this.length) {
+      startIndex = this.length - 1;
+    } else if (startIndex < 0) {
+      return -1;
+    }
+    for (int i = startIndex; i >= 0; i--) {
+      if (this[i] == element) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  bool contains(Object other) {
+    var length = this.length;
+    for (int i = 0; i < length; i++) {
+      E element = JS('Null', '#[#]', this, i);
+      if (element == other) return true;
+    }
+    return false;
+  }
+
+  @notNull
+  bool get isEmpty => length == 0;
+
+  @notNull
+  bool get isNotEmpty => !isEmpty;
+
+  String toString() => ListBase.listToString(this);
+
+  List<E> toList({@nullCheck bool growable = true}) {
+    var list = JS('', '#.slice()', this);
+    if (!growable) markFixedList(list);
+    return JSArray<E>.of(list);
+  }
+
+  Set<E> toSet() => Set<E>.from(this);
+
+  Iterator<E> get iterator => ArrayIterator<E>(this);
+
+  int get hashCode => identityHashCode(this);
+
+  @notNull
+  bool operator ==(other) => identical(this, other);
+
+  @notNull
+  int get length => JS<int>('!', r'#.length', this);
+
+  void set length(@nullCheck int newLength) {
+    checkGrowable('set length');
+    // TODO(sra): Remove this test and let JavaScript throw an error.
+    if (newLength < 0) {
+      throw RangeError.range(newLength, 0, null, 'newLength');
+    }
+    // JavaScript with throw a RangeError for numbers that are too big. The
+    // message does not contain the value.
+    JS('void', r'#.length = #', this, newLength);
+  }
+
+  E operator [](int index) {
+    // Suppress redundant null checks via JS.
+    if (index == null ||
+        JS<int>('!', '#', index) >= JS<int>('!', '#.length', this) ||
+        JS<int>('!', '#', index) < 0) {
+      throw diagnoseIndexError(this, index);
+    }
+    return JS('var', '#[#]', this, index);
+  }
+
+  void operator []=(int index, E value) {
+    checkMutable('indexed set');
+    if (index == null ||
+        JS<int>('!', '#', index) >= JS<int>('!', '#.length', this) ||
+        JS<int>('!', '#', index) < 0) {
+      throw diagnoseIndexError(this, index);
+    }
+    JS('void', r'#[#] = #', this, index, value);
+  }
+
+  Map<int, E> asMap() {
+    return ListMapView<E>(this);
+  }
+
+  Type get runtimeType =>
+      dart.wrapType(JS('', '#(#)', dart.getGenericClass(List), E));
+
+  Iterable<E> followedBy(Iterable<E> other) =>
+      FollowedByIterable<E>.firstEfficient(this, other);
+
+  Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this);
+
+  List<E> operator +(List<E> other) {
+    int totalLength = this.length + other.length;
+    return <E>[]
+      ..length = totalLength
+      ..setRange(0, this.length, this)
+      ..setRange(this.length, totalLength, other);
+  }
+
+  int indexWhere(bool test(E element), [int start = 0]) {
+    if (start >= this.length) return -1;
+    if (start < 0) start = 0;
+    for (int i = start; i < this.length; i++) {
+      if (test(this[i])) return i;
+    }
+    return -1;
+  }
+
+  int lastIndexWhere(bool test(E element), [int start]) {
+    if (start == null) start = this.length - 1;
+    if (start < 0) return -1;
+    for (int i = start; i >= 0; i--) {
+      if (test(this[i])) return i;
+    }
+    return -1;
+  }
+
+  void set first(E element) {
+    if (this.isEmpty) throw RangeError.index(0, this);
+    this[0] = element;
+  }
+
+  void set last(E element) {
+    if (this.isEmpty) throw RangeError.index(0, this);
+    this[this.length - 1] = element;
+  }
+}
+
+/**
+ * Dummy subclasses that allow the backend to track more precise
+ * information about arrays through their type. The CPA type inference
+ * relies on the fact that these classes do not override [] nor []=.
+ *
+ * These classes are really a fiction, and can have no methods, since
+ * getInterceptor always returns JSArray.  We should consider pushing the
+ * 'isGrowable' and 'isMutable' checks into the getInterceptor implementation so
+ * these classes can have specialized implementations. Doing so will challenge
+ * many assumptions in the JS backend.
+ */
+class JSMutableArray<E> extends JSArray<E> {}
+
+class JSFixedArray<E> extends JSMutableArray<E> {}
+
+class JSExtendableArray<E> extends JSMutableArray<E> {}
+
+class JSUnmodifiableArray<E> extends JSArray<E> {} // Already is JSIndexable.
+
+/// An [Iterator] that iterates a JSArray.
+///
+class ArrayIterator<E> implements Iterator<E> {
+  final JSArray<E> _iterable;
+  @notNull
+  final int _length;
+  @notNull
+  int _index;
+  E _current;
+
+  ArrayIterator(JSArray<E> iterable)
+      : _iterable = iterable,
+        _length = iterable.length,
+        _index = 0;
+
+  E get current => _current;
+
+  bool moveNext() {
+    @notNull
+    int length = _iterable.length;
+
+    // We have to do the length check even on fixed length Arrays.  If we can
+    // inline moveNext() we might be able to GVN the length and eliminate this
+    // check on known fixed length JSArray.
+    if (_length != length) {
+      throw throwConcurrentModificationError(_iterable);
+    }
+
+    if (_index >= length) {
+      _current = null;
+      return false;
+    }
+    _current = _iterable[_index];
+    _index++;
+    return true;
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart
new file mode 100644
index 0000000..5d6b037
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart
@@ -0,0 +1,826 @@
+// 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 dart._js_helper;
+
+import 'dart:collection';
+
+import 'dart:_foreign_helper' show JS, JS_STRING_CONCAT, JSExportName;
+
+import 'dart:_interceptors';
+import 'dart:_internal'
+    show
+        EfficientLengthIterable,
+        MappedIterable,
+        IterableElementError,
+        SubListIterable;
+
+import 'dart:_native_typed_data';
+import 'dart:_runtime' as dart;
+
+part 'annotations.dart';
+part 'linked_hash_map.dart';
+part 'identity_hash_map.dart';
+part 'custom_hash_map.dart';
+part 'native_helper.dart';
+part 'regexp_helper.dart';
+part 'string_helper.dart';
+part 'js_rti.dart';
+
+class _Patch {
+  const _Patch();
+}
+
+const _Patch patch = _Patch();
+
+/// Adapts a JS `[Symbol.iterator]` to a Dart `get iterator`.
+///
+/// This is the inverse of `JsIterator`, for classes where we can more
+/// efficiently obtain a JS iterator instead of a Dart one.
+///
+// TODO(jmesserly): this adapter is to work around
+// https://github.com/dart-lang/sdk/issues/28320
+class DartIterator<E> implements Iterator<E> {
+  final _jsIterator;
+  E _current;
+
+  DartIterator(this._jsIterator);
+
+  E get current => _current;
+
+  bool moveNext() {
+    final ret = JS('', '#.next()', _jsIterator);
+    _current = JS('', '#.value', ret);
+    return JS<bool>('!', '!#.done', ret);
+  }
+}
+
+/// Used to compile `sync*`.
+class SyncIterable<E> extends IterableBase<E> {
+  final Function() _initGenerator;
+  SyncIterable(this._initGenerator);
+
+  @JSExportName('Symbol.iterator')
+  _jsIterator() => _initGenerator();
+
+  get iterator => DartIterator(_initGenerator());
+}
+
+class Primitives {
+  @NoInline()
+  static int _parseIntError(String source, int handleError(String source)) {
+    if (handleError == null) throw FormatException(source);
+    return handleError(source);
+  }
+
+  static int parseInt(
+      @nullCheck String source, int _radix, int handleError(String source)) {
+    var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i');
+    // TODO(jmesserly): this isn't reified List<String>, but it's safe to use as
+    // long as we use it locally and don't expose it to user code.
+    List<String> match = JS('', '#.exec(#)', re, source);
+    int digitsIndex = 1;
+    int hexIndex = 2;
+    int decimalIndex = 3;
+    if (match == null) {
+      // TODO(sra): It might be that the match failed due to unrecognized U+0085
+      // spaces.  We could replace them with U+0020 spaces and try matching
+      // again.
+      return _parseIntError(source, handleError);
+    }
+    String decimalMatch = match[decimalIndex];
+    if (_radix == null) {
+      if (decimalMatch != null) {
+        // Cannot fail because we know that the digits are all decimal.
+        return JS<int>('!', r'parseInt(#, 10)', source);
+      }
+      if (match[hexIndex] != null) {
+        // Cannot fail because we know that the digits are all hex.
+        return JS<int>('!', r'parseInt(#, 16)', source);
+      }
+      return _parseIntError(source, handleError);
+    }
+    @notNull
+    var radix = _radix;
+    if (radix < 2 || radix > 36) {
+      throw RangeError.range(radix, 2, 36, 'radix');
+    }
+    if (radix == 10 && decimalMatch != null) {
+      // Cannot fail because we know that the digits are all decimal.
+      return JS<int>('!', r'parseInt(#, 10)', source);
+    }
+    // If radix >= 10 and we have only decimal digits the string is safe.
+    // Otherwise we need to check the digits.
+    if (radix < 10 || decimalMatch == null) {
+      // We know that the characters must be ASCII as otherwise the
+      // regexp wouldn't have matched. Lowercasing by doing `| 0x20` is thus
+      // guaranteed to be a safe operation, since it preserves digits
+      // and lower-cases ASCII letters.
+      int maxCharCode;
+      if (radix <= 10) {
+        // Allow all digits less than the radix. For example 0, 1, 2 for
+        // radix 3.
+        // "0".codeUnitAt(0) + radix - 1;
+        maxCharCode = (0x30 - 1) + radix;
+      } else {
+        // Letters are located after the digits in ASCII. Therefore we
+        // only check for the character code. The regexp above made already
+        // sure that the string does not contain anything but digits or
+        // letters.
+        // "a".codeUnitAt(0) + (radix - 10) - 1;
+        maxCharCode = (0x61 - 10 - 1) + radix;
+      }
+      assert(match[digitsIndex] is String);
+      String digitsPart = JS<String>('!', '#[#]', match, digitsIndex);
+      for (int i = 0; i < digitsPart.length; i++) {
+        int characterCode = digitsPart.codeUnitAt(i) | 0x20;
+        if (characterCode > maxCharCode) {
+          return _parseIntError(source, handleError);
+        }
+      }
+    }
+    // The above matching and checks ensures the source has at least one digits
+    // and all digits are suitable for the radix, so parseInt cannot return NaN.
+    return JS<int>('!', r'parseInt(#, #)', source, radix);
+  }
+
+  @NoInline()
+  static double _parseDoubleError(
+      String source, double handleError(String source)) {
+    if (handleError == null) {
+      throw FormatException('Invalid double', source);
+    }
+    return handleError(source);
+  }
+
+  static double parseDouble(
+      @nullCheck String source, double handleError(String source)) {
+    // Notice that JS parseFloat accepts garbage at the end of the string.
+    // Accept only:
+    // - [+/-]NaN
+    // - [+/-]Infinity
+    // - a Dart double literal
+    // We do allow leading or trailing whitespace.
+    if (!JS(
+        'bool',
+        r'/^\s*[+-]?(?:Infinity|NaN|'
+            r'(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(#)',
+        source)) {
+      return _parseDoubleError(source, handleError);
+    }
+    num result = JS('!', r'parseFloat(#)', source);
+    if (result.isNaN) {
+      var trimmed = source.trim();
+      if (trimmed == 'NaN' || trimmed == '+NaN' || trimmed == '-NaN') {
+        return result;
+      }
+      return _parseDoubleError(source, handleError);
+    }
+    return result;
+  }
+
+  /** `r"$".codeUnitAt(0)` */
+  static const int DOLLAR_CHAR_VALUE = 36;
+
+  static int dateNow() => JS<int>('!', r'Date.now()');
+
+  static void initTicker() {
+    if (timerFrequency != null) return;
+    // Start with low-resolution. We overwrite the fields if we find better.
+    timerFrequency = 1000;
+    timerTicks = dateNow;
+    if (JS<bool>('!', 'typeof window == "undefined"')) return;
+    var jsWindow = JS('var', 'window');
+    if (jsWindow == null) return;
+    var performance = JS('var', '#.performance', jsWindow);
+    if (performance == null) return;
+    if (JS<bool>('!', 'typeof #.now != "function"', performance)) return;
+    timerFrequency = 1000000;
+    timerTicks = () => (1000 * JS<num>('!', '#.now()', performance)).floor();
+  }
+
+  static int timerFrequency;
+  static num Function() timerTicks;
+
+  static bool get isD8 {
+    return JS(
+        'bool',
+        'typeof version == "function"'
+            ' && typeof os == "object" && "system" in os');
+  }
+
+  static bool get isJsshell {
+    return JS(
+        'bool', 'typeof version == "function" && typeof system == "function"');
+  }
+
+  static String currentUri() {
+    // In a browser return self.location.href.
+    if (JS<bool>('!', '!!#.location', dart.global_)) {
+      return JS<String>('!', '#.location.href', dart.global_);
+    }
+
+    // TODO(vsm): Consider supporting properly in non-browser settings.
+    return '';
+  }
+
+  // This is to avoid stack overflows due to very large argument arrays in
+  // apply().  It fixes http://dartbug.com/6919
+  @notNull
+  static String _fromCharCodeApply(List<int> array) {
+    const kMaxApply = 500;
+    @nullCheck
+    int end = array.length;
+    if (end <= kMaxApply) {
+      return JS<String>('!', r'String.fromCharCode.apply(null, #)', array);
+    }
+    String result = '';
+    for (int i = 0; i < end; i += kMaxApply) {
+      int chunkEnd = (i + kMaxApply < end) ? i + kMaxApply : end;
+      result = JS(
+          'String',
+          r'# + String.fromCharCode.apply(null, #.slice(#, #))',
+          result,
+          array,
+          i,
+          chunkEnd);
+    }
+    return result;
+  }
+
+  @notNull
+  static String stringFromCodePoints(JSArray<int> codePoints) {
+    List<int> a = <int>[];
+    for (@nullCheck var i in codePoints) {
+      if (i <= 0xffff) {
+        a.add(i);
+      } else if (i <= 0x10ffff) {
+        a.add(0xd800 + ((((i - 0x10000) >> 10) & 0x3ff)));
+        a.add(0xdc00 + (i & 0x3ff));
+      } else {
+        throw argumentErrorValue(i);
+      }
+    }
+    return _fromCharCodeApply(a);
+  }
+
+  @notNull
+  static String stringFromCharCodes(JSArray<int> charCodes) {
+    for (@nullCheck var i in charCodes) {
+      if (i < 0) throw argumentErrorValue(i);
+      if (i > 0xffff) return stringFromCodePoints(charCodes);
+    }
+    return _fromCharCodeApply(charCodes);
+  }
+
+  // [start] and [end] are validated.
+  @notNull
+  static String stringFromNativeUint8List(
+      NativeUint8List charCodes, @nullCheck int start, @nullCheck int end) {
+    const kMaxApply = 500;
+    if (end <= kMaxApply && start == 0 && end == charCodes.length) {
+      return JS<String>('!', r'String.fromCharCode.apply(null, #)', charCodes);
+    }
+    String result = '';
+    for (int i = start; i < end; i += kMaxApply) {
+      int chunkEnd = (i + kMaxApply < end) ? i + kMaxApply : end;
+      result = JS(
+          'String',
+          r'# + String.fromCharCode.apply(null, #.subarray(#, #))',
+          result,
+          charCodes,
+          i,
+          chunkEnd);
+    }
+    return result;
+  }
+
+  @notNull
+  static String stringFromCharCode(@nullCheck int charCode) {
+    if (0 <= charCode) {
+      if (charCode <= 0xffff) {
+        return JS<String>('!', 'String.fromCharCode(#)', charCode);
+      }
+      if (charCode <= 0x10ffff) {
+        var bits = charCode - 0x10000;
+        var low = 0xDC00 | (bits & 0x3ff);
+        var high = 0xD800 | (bits >> 10);
+        return JS<String>('!', 'String.fromCharCode(#, #)', high, low);
+      }
+    }
+    throw RangeError.range(charCode, 0, 0x10ffff);
+  }
+
+  static String stringConcatUnchecked(String string1, String string2) {
+    return JS_STRING_CONCAT(string1, string2);
+  }
+
+  static String flattenString(String str) {
+    return JS<String>('!', "#.charCodeAt(0) == 0 ? # : #", str, str, str);
+  }
+
+  static String getTimeZoneName(DateTime receiver) {
+    // Firefox and Chrome emit the timezone in parenthesis.
+    // Example: "Wed May 16 2012 21:13:00 GMT+0200 (CEST)".
+    // We extract this name using a regexp.
+    var d = lazyAsJsDate(receiver);
+    List match = JS('JSArray|Null', r'/\((.*)\)/.exec(#.toString())', d);
+    if (match != null) return match[1];
+
+    // Internet Explorer 10+ emits the zone name without parenthesis:
+    // Example: Thu Oct 31 14:07:44 PDT 2013
+    match = JS(
+        'JSArray|Null',
+        // Thu followed by a space.
+        r'/^[A-Z,a-z]{3}\s'
+            // Oct 31 followed by space.
+            r'[A-Z,a-z]{3}\s\d+\s'
+            // Time followed by a space.
+            r'\d{2}:\d{2}:\d{2}\s'
+            // The time zone name followed by a space.
+            r'([A-Z]{3,5})\s'
+            // The year.
+            r'\d{4}$/'
+            '.exec(#.toString())',
+        d);
+    if (match != null) return match[1];
+
+    // IE 9 and Opera don't provide the zone name. We fall back to emitting the
+    // UTC/GMT offset.
+    // Example (IE9): Wed Nov 20 09:51:00 UTC+0100 2013
+    //       (Opera): Wed Nov 20 2013 11:03:38 GMT+0100
+    match = JS('JSArray|Null', r'/(?:GMT|UTC)[+-]\d{4}/.exec(#.toString())', d);
+    if (match != null) return match[0];
+    return "";
+  }
+
+  static int getTimeZoneOffsetInMinutes(DateTime receiver) {
+    // Note that JS and Dart disagree on the sign of the offset.
+    return -JS<int>('!', r'#.getTimezoneOffset()', lazyAsJsDate(receiver));
+  }
+
+  static num valueFromDecomposedDate(
+      @nullCheck int years,
+      @nullCheck int month,
+      @nullCheck int day,
+      @nullCheck int hours,
+      @nullCheck int minutes,
+      @nullCheck int seconds,
+      @nullCheck int milliseconds,
+      @nullCheck bool isUtc) {
+    final int MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000;
+    var jsMonth = month - 1;
+    num value;
+    if (isUtc) {
+      value = JS('!', r'Date.UTC(#, #, #, #, #, #, #)', years, jsMonth, day,
+          hours, minutes, seconds, milliseconds);
+    } else {
+      value = JS('!', r'new Date(#, #, #, #, #, #, #).valueOf()', years,
+          jsMonth, day, hours, minutes, seconds, milliseconds);
+    }
+    if (value.isNaN ||
+        value < -MAX_MILLISECONDS_SINCE_EPOCH ||
+        value > MAX_MILLISECONDS_SINCE_EPOCH) {
+      return null;
+    }
+    if (years <= 0 || years < 100) return patchUpY2K(value, years, isUtc);
+    return value;
+  }
+
+  static num patchUpY2K(value, years, isUtc) {
+    var date = JS('', r'new Date(#)', value);
+    if (isUtc) {
+      JS('', r'#.setUTCFullYear(#)', date, years);
+    } else {
+      JS('', r'#.setFullYear(#)', date, years);
+    }
+    return JS('!', r'#.valueOf()', date);
+  }
+
+  // Lazily keep a JS Date stored in the JS object.
+  static lazyAsJsDate(DateTime receiver) {
+    if (JS<bool>('!', r'#.date === (void 0)', receiver)) {
+      JS('void', r'#.date = new Date(#)', receiver,
+          receiver.millisecondsSinceEpoch);
+    }
+    return JS('var', r'#.date', receiver);
+  }
+
+  // The getters for date and time parts below add a positive integer to ensure
+  // that the result is really an integer, because the JavaScript implementation
+  // may return -0.0 instead of 0.
+
+  static int getYear(DateTime receiver) {
+    return (receiver.isUtc)
+        ? JS<int>('!', r'(#.getUTCFullYear() + 0)', lazyAsJsDate(receiver))
+        : JS<int>('!', r'(#.getFullYear() + 0)', lazyAsJsDate(receiver));
+  }
+
+  static int getMonth(DateTime receiver) {
+    return (receiver.isUtc)
+        ? JS<int>('!', r'#.getUTCMonth() + 1', lazyAsJsDate(receiver))
+        : JS<int>('!', r'#.getMonth() + 1', lazyAsJsDate(receiver));
+  }
+
+  static int getDay(DateTime receiver) {
+    return (receiver.isUtc)
+        ? JS<int>('!', r'(#.getUTCDate() + 0)', lazyAsJsDate(receiver))
+        : JS<int>('!', r'(#.getDate() + 0)', lazyAsJsDate(receiver));
+  }
+
+  static int getHours(DateTime receiver) {
+    return (receiver.isUtc)
+        ? JS<int>('!', r'(#.getUTCHours() + 0)', lazyAsJsDate(receiver))
+        : JS<int>('!', r'(#.getHours() + 0)', lazyAsJsDate(receiver));
+  }
+
+  static int getMinutes(DateTime receiver) {
+    return (receiver.isUtc)
+        ? JS<int>('!', r'(#.getUTCMinutes() + 0)', lazyAsJsDate(receiver))
+        : JS<int>('!', r'(#.getMinutes() + 0)', lazyAsJsDate(receiver));
+  }
+
+  static int getSeconds(DateTime receiver) {
+    return (receiver.isUtc)
+        ? JS<int>('!', r'(#.getUTCSeconds() + 0)', lazyAsJsDate(receiver))
+        : JS<int>('!', r'(#.getSeconds() + 0)', lazyAsJsDate(receiver));
+  }
+
+  static int getMilliseconds(DateTime receiver) {
+    return (receiver.isUtc)
+        ? JS<int>('!', r'(#.getUTCMilliseconds() + 0)', lazyAsJsDate(receiver))
+        : JS<int>('!', r'(#.getMilliseconds() + 0)', lazyAsJsDate(receiver));
+  }
+
+  static int getWeekday(DateTime receiver) {
+    int weekday = (receiver.isUtc)
+        ? JS<int>('!', r'#.getUTCDay() + 0', lazyAsJsDate(receiver))
+        : JS<int>('!', r'#.getDay() + 0', lazyAsJsDate(receiver));
+    // Adjust by one because JS weeks start on Sunday.
+    return (weekday + 6) % 7 + 1;
+  }
+
+  static num valueFromDateString(str) {
+    if (str is! String) throw argumentErrorValue(str);
+    num value = JS('!', r'Date.parse(#)', str);
+    if (value.isNaN) throw argumentErrorValue(str);
+    return value;
+  }
+
+  static getProperty(object, key) {
+    if (object == null || object is bool || object is num || object is String) {
+      throw argumentErrorValue(object);
+    }
+    return JS('var', '#[#]', object, key);
+  }
+
+  static void setProperty(object, key, value) {
+    if (object == null || object is bool || object is num || object is String) {
+      throw argumentErrorValue(object);
+    }
+    JS('void', '#[#] = #', object, key, value);
+  }
+}
+
+/**
+ * Diagnoses an indexing error. Returns the ArgumentError or RangeError that
+ * describes the problem.
+ */
+@NoInline()
+Error diagnoseIndexError(indexable, int index) {
+  int length = indexable.length;
+  // The following returns the same error that would be thrown by calling
+  // [RangeError.checkValidIndex] with no optional parameters provided.
+  if (index < 0 || index >= length) {
+    return RangeError.index(index, indexable, 'index', null, length);
+  }
+  // The above should always match, but if it does not, use the following.
+  return RangeError.value(index, 'index');
+}
+
+/**
+ * Diagnoses a range error. Returns the ArgumentError or RangeError that
+ * describes the problem.
+ */
+@NoInline()
+Error diagnoseRangeError(int start, int end, int length) {
+  if (start == null) {
+    return ArgumentError.value(start, 'start');
+  }
+  if (start < 0 || start > length) {
+    return RangeError.range(start, 0, length, 'start');
+  }
+  if (end != null) {
+    if (end < start || end > length) {
+      return RangeError.range(end, start, length, 'end');
+    }
+  }
+  // The above should always match, but if it does not, use the following.
+  return ArgumentError.value(end, "end");
+}
+
+@notNull
+int stringLastIndexOfUnchecked(receiver, element, start) =>
+    JS<int>('!', r'#.lastIndexOf(#, #)', receiver, element, start);
+
+/// 'factory' for constructing ArgumentError.value to keep the call sites small.
+@NoInline()
+ArgumentError argumentErrorValue(object) {
+  return ArgumentError.value(object);
+}
+
+void throwArgumentErrorValue(value) {
+  throw argumentErrorValue(value);
+}
+
+checkInt(value) {
+  if (value is! int) throw argumentErrorValue(value);
+  return value;
+}
+
+throwRuntimeError(message) {
+  throw RuntimeError(message);
+}
+
+throwAbstractClassInstantiationError(className) {
+  throw AbstractClassInstantiationError(className);
+}
+
+@NoInline()
+throwConcurrentModificationError(collection) {
+  throw ConcurrentModificationError(collection);
+}
+
+class JsNoSuchMethodError extends Error implements NoSuchMethodError {
+  final String _message;
+  final String _method;
+  final String _receiver;
+
+  JsNoSuchMethodError(this._message, match)
+      : _method = match == null ? null : JS('String|Null', '#.method', match),
+        _receiver =
+            match == null ? null : JS('String|Null', '#.receiver', match);
+
+  String toString() {
+    if (_method == null) return 'NoSuchMethodError: $_message';
+    if (_receiver == null) {
+      return "NoSuchMethodError: method not found: '$_method' ($_message)";
+    }
+    return "NoSuchMethodError: "
+        "method not found: '$_method' on '$_receiver' ($_message)";
+  }
+}
+
+class UnknownJsTypeError extends Error {
+  final String _message;
+
+  UnknownJsTypeError(this._message);
+
+  String toString() => _message.isEmpty ? 'Error' : 'Error: $_message';
+}
+
+/**
+ * Called by generated code to build a map literal. [keyValuePairs] is
+ * a list of key, value, key, value, ..., etc.
+ */
+fillLiteralMap(keyValuePairs, Map result) {
+  // TODO(johnniwinther): Use JSArray to optimize this code instead of calling
+  // [getLength] and [getIndex].
+  int index = 0;
+  int length = getLength(keyValuePairs);
+  while (index < length) {
+    var key = getIndex(keyValuePairs, index++);
+    var value = getIndex(keyValuePairs, index++);
+    result[key] = value;
+  }
+  return result;
+}
+
+bool jsHasOwnProperty(var jsObject, String property) {
+  return JS<bool>('!', r'#.hasOwnProperty(#)', jsObject, property);
+}
+
+jsPropertyAccess(var jsObject, String property) {
+  return JS('var', r'#[#]', jsObject, property);
+}
+
+/**
+ * Called at the end of unaborted switch cases to get the singleton
+ * FallThroughError exception that will be thrown.
+ */
+getFallThroughError() => FallThroughErrorImplementation();
+
+/**
+ * A metadata annotation describing the types instantiated by a native element.
+ *
+ * The annotation is valid on a native method and a field of a native class.
+ *
+ * By default, a field of a native class is seen as an instantiation point for
+ * all native classes that are a subtype of the field's type, and a native
+ * method is seen as an instantiation point fo all native classes that are a
+ * subtype of the method's return type, or the argument types of the declared
+ * type of the method's callback parameter.
+ *
+ * An @[Creates] annotation overrides the default set of instantiated types.  If
+ * one or more @[Creates] annotations are present, the type of the native
+ * element is ignored, and the union of @[Creates] annotations is used instead.
+ * The names in the strings are resolved and the program will fail to compile
+ * with dart2js if they do not name types.
+ *
+ * The argument to [Creates] is a string.  The string is parsed as the names of
+ * one or more types, separated by vertical bars `|`.  There are some special
+ * names:
+ *
+ * * `=Object`. This means 'exactly Object', which is a plain JavaScript object
+ *   with properties and none of the subtypes of Object.
+ *
+ * Example: we may know that a method always returns a specific implementation:
+ *
+ *     @Creates('_NodeList')
+ *     List<Node> getElementsByTagName(String tag) native;
+ *
+ * Useful trick: A method can be marked as not instantiating any native classes
+ * with the annotation `@Creates('Null')`.  This is useful for fields on native
+ * classes that are used only in Dart code.
+ *
+ *     @Creates('Null')
+ *     var _cachedFoo;
+ */
+class Creates {
+  final String types;
+  const Creates(this.types);
+}
+
+/**
+ * A metadata annotation describing the types returned or yielded by a native
+ * element.
+ *
+ * The annotation is valid on a native method and a field of a native class.
+ *
+ * By default, a native method or field is seen as returning or yielding all
+ * subtypes if the method return type or field type.  This annotation allows a
+ * more precise set of types to be specified.
+ *
+ * See [Creates] for the syntax of the argument.
+ *
+ * Example: IndexedDB keys are numbers, strings and JavaScript Arrays of keys.
+ *
+ *     @Returns('String|num|JSExtendableArray')
+ *     dynamic key;
+ *
+ *     // Equivalent:
+ *     @Returns('String') @Returns('num') @Returns('JSExtendableArray')
+ *     dynamic key;
+ */
+class Returns {
+  final String types;
+  const Returns(this.types);
+}
+
+/**
+ * A metadata annotation placed on native methods and fields of native classes
+ * to specify the JavaScript name.
+ *
+ * This example declares a Dart field + getter + setter called `$dom_title` that
+ * corresponds to the JavaScript property `title`.
+ *
+ *     class Document native "*Foo" {
+ *       @JSName('title')
+ *       String $dom_title;
+ *     }
+ */
+class JSName {
+  final String name;
+  const JSName(this.name);
+}
+
+/**
+ * Special interface recognized by the compiler and implemented by DOM
+ * objects that support integer indexing. This interface is not
+ * visible to anyone, and is only injected into special libraries.
+ */
+abstract class JavaScriptIndexingBehavior<E> {}
+
+// TODO(lrn): These exceptions should be implemented in core.
+// When they are, remove the 'Implementation' here.
+
+/// Thrown by type assertions that fail.
+class TypeErrorImpl extends Error implements TypeError {
+  final String message;
+
+  TypeErrorImpl(this.message);
+
+  String toString() => message;
+}
+
+/// Thrown by the 'as' operator if the cast isn't valid.
+class CastErrorImpl extends Error implements CastError {
+  final String message;
+
+  CastErrorImpl(this.message);
+
+  String toString() => message;
+}
+
+class FallThroughErrorImplementation extends FallThroughError {
+  String toString() => "Switch case fall-through.";
+}
+
+/**
+ * Error thrown when a runtime error occurs.
+ */
+class RuntimeError extends Error {
+  final message;
+  RuntimeError(this.message);
+  String toString() => "RuntimeError: $message";
+}
+
+/// Error thrown by DDC when an `assert()` fails (with or without a message).
+class AssertionErrorImpl extends AssertionError {
+  final String _fileUri;
+  final int _line;
+  final int _column;
+  final String _conditionSource;
+
+  AssertionErrorImpl(Object message,
+      [this._fileUri, this._line, this._column, this._conditionSource])
+      : super(message);
+
+  String toString() {
+    var failureMessage = "";
+    if (_fileUri != null &&
+        _line != null &&
+        _column != null &&
+        _conditionSource != null) {
+      failureMessage += "$_fileUri:${_line}:${_column}\n$_conditionSource\n";
+    }
+    failureMessage +=
+        message != null ? Error.safeToString(message) : "is not true";
+
+    return "Assertion failed: $failureMessage";
+  }
+}
+
+/**
+ * Creates a random number with 64 bits of randomness.
+ *
+ * This will be truncated to the 53 bits available in a double.
+ */
+int random64() {
+  // TODO(lrn): Use a secure random source.
+  int int32a = JS("int", "(Math.random() * 0x100000000) >>> 0");
+  int int32b = JS("int", "(Math.random() * 0x100000000) >>> 0");
+  return int32a + int32b * 0x100000000;
+}
+
+class BooleanConversionAssertionError extends AssertionError {
+  toString() => 'Failed assertion: boolean expression must not be null';
+}
+
+// Hook to register new global object.  This is invoked from dart:html
+// whenever a new window is accessed for the first time.
+void registerGlobalObject(object) {
+  try {
+    if (dart.polyfill(object)) {
+      dart.applyAllExtensions(object);
+    }
+  } catch (e) {
+    // This may fail due to cross-origin errors.  In that case, we shouldn't
+    // need to polyfill as we can't get objects from that frame.
+
+    // TODO(vsm): Detect this more robustly - ideally before we try to polyfill.
+  }
+}
+
+/// Expose browser JS classes.
+void applyExtension(name, nativeObject) {
+  dart.applyExtension(name, nativeObject);
+}
+
+/// Used internally by DDC to map ES6 symbols to Dart.
+class PrivateSymbol implements Symbol {
+  // TODO(jmesserly): could also get this off the native symbol instead of
+  // storing it. Mirrors already does this conversion.
+  final String _name;
+  final Object _nativeSymbol;
+
+  const PrivateSymbol(this._name, this._nativeSymbol);
+
+  static String getName(Symbol symbol) => (symbol as PrivateSymbol)._name;
+
+  static Object getNativeSymbol(Symbol symbol) {
+    if (symbol is PrivateSymbol) return symbol._nativeSymbol;
+    return null;
+  }
+
+  bool operator ==(other) =>
+      other is PrivateSymbol &&
+      _name == other._name &&
+      identical(_nativeSymbol, other._nativeSymbol);
+
+  get hashCode => _name.hashCode;
+
+  // TODO(jmesserly): is this equivalent to _nativeSymbol toString?
+  toString() => 'Symbol("$_name")';
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_mirrors.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_mirrors.dart
new file mode 100644
index 0000000..a93f5fb
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_mirrors.dart
@@ -0,0 +1,598 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart._js_mirrors;
+
+import 'dart:mirrors';
+import 'dart:_runtime' as dart;
+import 'dart:_foreign_helper' show JS;
+import 'dart:_internal' as _internal show Symbol;
+import 'dart:_js_helper' show PrivateSymbol;
+
+String getName(Symbol symbol) {
+  if (symbol is PrivateSymbol) {
+    return PrivateSymbol.getName(symbol);
+  } else {
+    return _internal.Symbol.getName(symbol as _internal.Symbol);
+  }
+}
+
+Symbol getSymbol(name, library) =>
+    throw UnimplementedError("MirrorSystem.getSymbol unimplemented");
+
+final currentJsMirrorSystem = JsMirrorSystem();
+
+final _typeMirror = JS('', 'Symbol("_typeMirror")');
+
+InstanceMirror reflect(reflectee) {
+  // TODO(vsm): Consider caching the mirror here.  Unlike the type below,
+  // reflectee may be a primitive - i.e., we can't just add an expando.
+  if (reflectee is Function) {
+    return JsClosureMirror._(reflectee);
+  } else {
+    return JsInstanceMirror._(reflectee);
+  }
+}
+
+TypeMirror reflectType(Type key) {
+  var unwrapped = dart.unwrapType(key);
+  var property =
+      JS('', 'Object.getOwnPropertyDescriptor(#, #)', unwrapped, _typeMirror);
+  if (property != null) {
+    return JS('', '#.value', property);
+  }
+  // TODO(vsm): Might not be a class.
+  var mirror = JsClassMirror._(key);
+  JS('', '#[#] = #', unwrapped, _typeMirror, mirror);
+  return mirror;
+}
+
+typedef T _Lazy<T>();
+
+dynamic _getESSymbol(Symbol symbol) => PrivateSymbol.getNativeSymbol(symbol);
+
+dynamic _getMember(Symbol symbol) {
+  var privateSymbol = _getESSymbol(symbol);
+  if (privateSymbol != null) {
+    return privateSymbol;
+  }
+  var name = getName(symbol);
+  // TODO(jacobr): this code is duplicated in code_generator.dart
+  switch (name) {
+    case '[]':
+      name = '_get';
+      break;
+    case '[]=':
+      name = '_set';
+      break;
+    case 'unary-':
+      name = '_negate';
+      break;
+    case 'constructor':
+    case 'prototype':
+      name = '_$name';
+      break;
+  }
+  return name;
+}
+
+String _getNameForESSymbol(member) {
+  // Convert private JS symbol "Symbol(_foo)" to string "_foo".
+  assert(JS<bool>('!', 'typeof # == "symbol"', member));
+  var str = member.toString();
+  assert(str.startsWith('Symbol(') && str.endsWith(')'));
+  return str.substring(7, str.length - 1);
+}
+
+Symbol _getSymbolForESSymbol(member) {
+  var name = _getNameForESSymbol(member);
+  return PrivateSymbol(name, member);
+}
+
+// The [member] must be either a string (public) or an ES6 symbol (private).
+Symbol _getSymbolForMember(member) {
+  if (member is String) {
+    return Symbol(member);
+  } else {
+    var name = _getNameForESSymbol(member);
+    return PrivateSymbol(name, member);
+  }
+}
+
+Map<Symbol, dynamic> _toDartMap(data) {
+  if (data == null) return {};
+  var map = Map<Symbol, dynamic>();
+  // Note: we recorded a map from fields/methods to their type and metadata.
+  // The key is a string name for public members but an ES6 symbol for private
+  // ones.  That's works nicely for dynamic operations, but dart:mirrors expects
+  // Dart symbols, so we convert here.
+  var publicMembers = JS('', 'Object.getOwnPropertyNames(#)', data);
+  for (var member in publicMembers) {
+    var symbol = Symbol(member);
+    map[symbol] = JS('', '#[#]', data, member);
+  }
+
+  var privateMembers = JS('', 'Object.getOwnPropertySymbols(#)', data);
+  for (var member in privateMembers) {
+    var symbol = _getSymbolForESSymbol(member);
+    map[symbol] = JS('', '#[#]', data, member);
+  }
+  return map;
+}
+
+dynamic _runtimeType(obj) => dart.wrapType(dart.getReifiedType(obj));
+
+_unimplemented(Type t, Invocation i) {
+  throw UnimplementedError('$t.${getName(i.memberName)} unimplemented');
+}
+
+dynamic _toJsMap(Map<Symbol, dynamic> map) {
+  if (map == null) return null;
+  var obj = JS('', '{}');
+  map.forEach((Symbol key, value) {
+    JS('', '#[#] = #', obj, getName(key), value);
+  });
+  return obj;
+}
+
+class JsMirrorSystem implements MirrorSystem {
+  get libraries => const {};
+
+  noSuchMethod(Invocation i) {
+    _unimplemented(this.runtimeType, i);
+  }
+}
+
+class JsMirror implements Mirror {
+  noSuchMethod(Invocation i) {
+    _unimplemented(this.runtimeType, i);
+  }
+}
+
+class JsCombinatorMirror extends JsMirror implements CombinatorMirror {}
+
+class JsDeclarationMirror extends JsMirror implements DeclarationMirror {}
+
+class JsIsolateMirror extends JsMirror implements IsolateMirror {}
+
+class JsLibraryDependencyMirror extends JsMirror
+    implements LibraryDependencyMirror {}
+
+class JsObjectMirror extends JsMirror implements ObjectMirror {}
+
+class JsInstanceMirror extends JsObjectMirror implements InstanceMirror {
+  // Reflected object
+  final reflectee;
+  bool get hasReflectee => true;
+
+  ClassMirror get type {
+    // The spec guarantees that `null` is the singleton instance of the `Null`
+    // class.
+    if (reflectee == null) return reflectClass(Null);
+    return reflectType(_runtimeType(reflectee));
+  }
+
+  JsInstanceMirror._(this.reflectee);
+
+  bool operator ==(Object other) {
+    return (other is JsInstanceMirror) && identical(reflectee, other.reflectee);
+  }
+
+  int get hashCode {
+    // Avoid hash collisions with the reflectee. This constant is in Smi range
+    // and happens to be the inner padding from RFC 2104.
+    return identityHashCode(reflectee) ^ 0x36363636;
+  }
+
+  InstanceMirror getField(Symbol symbol) {
+    var name = _getMember(symbol);
+    var field = dart.dloadMirror(reflectee, name);
+    return reflect(field);
+  }
+
+  InstanceMirror setField(Symbol symbol, Object value) {
+    var name = _getMember(symbol);
+    dart.dputMirror(reflectee, name, value);
+    return reflect(value);
+  }
+
+  InstanceMirror invoke(Symbol symbol, List<dynamic> args,
+      [Map<Symbol, dynamic> namedArgs]) {
+    var name = _getMember(symbol);
+    var result =
+        dart.callMethod(reflectee, name, null, args, _toJsMap(namedArgs), name);
+    return reflect(result);
+  }
+
+  String toString() => "InstanceMirror on '$reflectee'";
+}
+
+class JsClosureMirror extends JsInstanceMirror implements ClosureMirror {
+  JsClosureMirror._(reflectee) : super._(reflectee);
+
+  InstanceMirror apply(List<dynamic> args, [Map<Symbol, dynamic> namedArgs]) {
+    var result = dart.dcall(reflectee, args, _toJsMap(namedArgs));
+    return reflect(result);
+  }
+}
+
+// For generic classes, mirrors uses the same representation, [ClassMirror],
+// for the instantiated and uninstantiated type.  Somewhat awkwardly, most APIs
+// (e.g., [newInstance]) treat the uninstantiated type as if instantiated
+// with all dynamic.  The representation below is correspondingly a bit wonky.
+// For an uninstantiated generic class, [_cls] is the instantiated type (with
+// dynamic) and [_raw] is null.  For an instantiated generic class, [_cls] is
+// the instantiated type (with the corresponding type parameters), and [_raw]
+// is the generic factory.
+class JsClassMirror extends JsMirror implements ClassMirror {
+  final Type _cls;
+  final Symbol simpleName;
+  // Generic class factory for instantiated types.
+  final dynamic _raw;
+
+  ClassMirror _originalDeclaration;
+
+  // TODO(vsm): Do this properly
+  ClassMirror _mixin = null;
+  List<TypeMirror> _typeArguments;
+
+  List<InstanceMirror> _metadata;
+  Map<Symbol, DeclarationMirror> _declarations;
+
+  List<InstanceMirror> get metadata {
+    if (_metadata == null) {
+      // Load metadata.
+      var unwrapped = dart.unwrapType(_cls);
+      // Only get metadata directly embedded on this class, not its
+      // superclasses.
+      Function fn = JS(
+          '',
+          'Object.hasOwnProperty.call(#, dart.metadata) ? #[dart.metadata] : null',
+          unwrapped,
+          unwrapped);
+      _metadata = (fn == null)
+          ? const <InstanceMirror>[]
+          : List<InstanceMirror>.unmodifiable(fn().map((i) => reflect(i)));
+    }
+    return _metadata;
+  }
+
+  Map<Symbol, DeclarationMirror> get declarations {
+    if (_declarations == null) {
+      // Load declarations.
+      // TODO(vsm): This is only populating the default constructor right now.
+      _declarations = Map<Symbol, DeclarationMirror>();
+      var unwrapped = dart.unwrapType(_cls);
+      var constructors = _toDartMap(dart.getConstructors(unwrapped));
+      constructors.forEach((symbol, ft) {
+        var name = getName(symbol);
+        _declarations[symbol] = JsMethodMirror._constructor(this, symbol, ft);
+      });
+      if (constructors.isEmpty) {
+        // Add a default
+        var name = 'new';
+        var ft = dart.fnType(dart.unwrapType(_cls), []);
+        var symbol = Symbol(name);
+        _declarations[symbol] = JsMethodMirror._constructor(this, symbol, ft);
+      }
+      var fields = _toDartMap(dart.getFields(unwrapped));
+      fields.forEach((symbol, t) {
+        _declarations[symbol] = JsVariableMirror._fromField(symbol, t);
+      });
+      var methods = _toDartMap(dart.getMethods(unwrapped));
+      methods.forEach((symbol, ft) {
+        var name = getName(symbol);
+        _declarations[symbol] =
+            JsMethodMirror._instanceMethod(this, symbol, ft);
+      });
+
+      getterType(type) {
+        if (JS<bool>('!', '# instanceof Array', type)) {
+          var array = JS('', '#.slice()', type);
+          type = JS('', '#[0]', array);
+          JS('', '#[0] = #', array, dart.fnType(type, []));
+          return array;
+        } else {
+          return dart.fnType(type, []);
+        }
+      }
+
+      var getters = _toDartMap(dart.getGetters(unwrapped));
+      getters.forEach((symbol, type) {
+        _declarations[symbol] =
+            JsMethodMirror._instanceMethod(this, symbol, getterType(type));
+      });
+
+      setterType(type) {
+        if (JS<bool>('!', '# instanceof Array', type)) {
+          var array = JS('', '#.slice()', type);
+          type = JS('', '#[0]', array);
+          JS('', '#[0] = #', array, dart.fnType(dart.void_, [type]));
+          return array;
+        } else {
+          return dart.fnType(dart.void_, [type]);
+        }
+      }
+
+      var setters = _toDartMap(dart.getSetters(unwrapped));
+      setters.forEach((symbol, type) {
+        var name = getName(symbol) + '=';
+        // Create a separate symbol for the setter.
+        symbol = PrivateSymbol(name, _getESSymbol(symbol));
+        _declarations[symbol] =
+            JsMethodMirror._instanceMethod(this, symbol, setterType(type));
+      });
+
+      var staticFields = _toDartMap(dart.getStaticFields(unwrapped));
+      staticFields.forEach((symbol, t) {
+        _declarations[symbol] = JsVariableMirror._fromField(symbol, t);
+      });
+      var statics = _toDartMap(dart.getStaticMethods(unwrapped));
+      statics.forEach((symbol, ft) {
+        _declarations[symbol] = JsMethodMirror._staticMethod(this, symbol, ft);
+      });
+
+      var staticGetters = _toDartMap(dart.getStaticGetters(unwrapped));
+      staticGetters.forEach((symbol, type) {
+        _declarations[symbol] =
+            JsMethodMirror._staticMethod(this, symbol, getterType(type));
+      });
+
+      var staticSetters = _toDartMap(dart.getStaticSetters(unwrapped));
+      staticSetters.forEach((symbol, type) {
+        _declarations[symbol] =
+            JsMethodMirror._staticMethod(this, symbol, setterType(type));
+      });
+      _declarations =
+          Map<Symbol, DeclarationMirror>.unmodifiable(_declarations);
+    }
+    return _declarations;
+  }
+
+  JsClassMirror._(Type cls, {bool instantiated = true})
+      : _cls = cls,
+        _raw = instantiated ? dart.getGenericClass(dart.unwrapType(cls)) : null,
+        simpleName = Symbol(JS<String>('!', '#.name', dart.unwrapType(cls))) {
+    var typeArgs = dart.getGenericArgs(dart.unwrapType(_cls));
+    if (typeArgs == null) {
+      _typeArguments = const [];
+    } else {
+      _typeArguments =
+          List.unmodifiable(typeArgs.map((t) => reflectType(dart.wrapType(t))));
+    }
+  }
+
+  InstanceMirror newInstance(Symbol constructorName, List args,
+      [Map<Symbol, dynamic> namedArgs]) {
+    // TODO(vsm): Support named arguments.
+    var name = getName(constructorName);
+    assert(namedArgs == null || namedArgs.isEmpty);
+    // Default constructors are mapped to new.
+    if (name == '') name = 'new';
+    var cls = dart.unwrapType(_cls);
+    var ctr = JS('', '#.#', cls, name);
+    // Only generative Dart constructors are wired up as real JS constructors.
+    var instance = JS<bool>('!', '#.prototype == #.prototype', cls, ctr)
+        // Generative
+        ? JS('', 'new #(...#)', ctr, args)
+        // Factory
+        : JS('', '#(...#)', ctr, args);
+    return reflect(instance);
+  }
+
+  // TODO(vsm): Need to check for NSM, types on accessors below.  Unlike the
+  // InstanceMirror case, there is no dynamic helper to delegate to - we never
+  // need a dload, etc. on a static.
+
+  InstanceMirror getField(Symbol symbol) {
+    var name = getName(symbol);
+    return reflect(JS('', '#[#]', dart.unwrapType(_cls), name));
+  }
+
+  InstanceMirror setField(Symbol symbol, Object value) {
+    var name = getName(symbol);
+    JS('', '#[#] = #', dart.unwrapType(_cls), name, value);
+    return reflect(value);
+  }
+
+  InstanceMirror invoke(Symbol symbol, List<dynamic> args,
+      [Map<Symbol, dynamic> namedArgs]) {
+    var name = getName(symbol);
+    if (namedArgs != null) {
+      args = List.from(args);
+      args.add(_toJsMap(namedArgs));
+    }
+    var result = JS('', '#.#(...#)', dart.unwrapType(_cls), name, args);
+    return reflect(result);
+  }
+
+  List<ClassMirror> get superinterfaces {
+    _Lazy<List<Type>> interfaceThunk =
+        JS('', '#[dart.implements]', dart.unwrapType(_cls));
+    if (interfaceThunk == null) {
+      return [];
+    } else {
+      List<Type> interfaces = interfaceThunk();
+      return interfaces.map((t) => reflectType(t)).toList();
+    }
+  }
+
+  bool get hasReflectedType => true;
+  Type get reflectedType {
+    return _cls;
+  }
+
+  bool get isOriginalDeclaration => _raw == null;
+
+  List<TypeMirror> get typeArguments => _typeArguments;
+
+  TypeMirror get originalDeclaration {
+    if (_raw == null) {
+      return this;
+    }
+    if (_originalDeclaration != null) {
+      return _originalDeclaration;
+    }
+    _originalDeclaration = JsClassMirror._(dart.wrapType(JS('', '#()', _raw)),
+        instantiated: false);
+    return _originalDeclaration;
+  }
+
+  ClassMirror get superclass {
+    if (_cls == Object) {
+      return null;
+    } else {
+      return reflectType(
+          dart.wrapType(JS<Type>('!', '#.__proto__', dart.unwrapType(_cls))));
+    }
+  }
+
+  ClassMirror get mixin {
+    if (_mixin != null) {
+      return _mixin;
+    }
+    var mixin = dart.getMixin(dart.unwrapType(_cls));
+    if (mixin == null) {
+      // If there is no mixin, return this mirror per API.
+      _mixin = this;
+      return _mixin;
+    }
+    _mixin = reflectType(dart.wrapType(mixin));
+    return _mixin;
+  }
+
+  String toString() => "ClassMirror on '$_cls'";
+}
+
+class JsVariableMirror extends JsMirror implements VariableMirror {
+  final Symbol _symbol;
+  final String _name;
+  final TypeMirror type;
+  final List<InstanceMirror> metadata;
+  final bool isFinal;
+
+  // TODO(vsm): Refactor this out.
+  Symbol get simpleName => _symbol;
+
+  // TODO(vsm): Fix this
+  final bool isStatic = false;
+
+  JsVariableMirror._(Symbol symbol, Type t, List annotations,
+      {this.isFinal = false})
+      : _symbol = symbol,
+        _name = getName(symbol),
+        type = reflectType(t),
+        metadata =
+            List<InstanceMirror>.unmodifiable(annotations?.map(reflect) ?? []);
+
+  JsVariableMirror._fromField(Symbol symbol, fieldInfo)
+      : this._(symbol, dart.wrapType(JS('', '#.type', fieldInfo)),
+            JS('', '#.metadata', fieldInfo),
+            isFinal: JS<bool>('!', '#.isFinal', fieldInfo));
+
+  String toString() => "VariableMirror on '$_name'";
+}
+
+class JsParameterMirror extends JsVariableMirror implements ParameterMirror {
+  JsParameterMirror._(Symbol member, Type t, List annotations)
+      : super._(member, t, annotations);
+
+  String toString() => "ParameterMirror on '$_name'";
+}
+
+class JsMethodMirror extends JsMirror implements MethodMirror {
+  final Symbol _symbol;
+  final String _name;
+  List<ParameterMirror> _params;
+  List<InstanceMirror> _metadata;
+  final bool isConstructor;
+  final bool isStatic;
+
+  // TODO(vsm): Fix this
+  final bool isFinal = false;
+  bool get isSetter => _name.endsWith('=');
+  bool get isPrivate => _name.startsWith('_');
+
+  // TODO(vsm): Refactor this out.
+  Symbol get simpleName => _symbol;
+
+  JsMethodMirror._constructor(JsClassMirror cls, Symbol symbol, ftype)
+      : _symbol = symbol,
+        _name = getName(symbol),
+        isConstructor = true,
+        isStatic = false {
+    _createParameterMirrorList(ftype);
+  }
+
+  JsMethodMirror._instanceMethod(JsClassMirror cls, Symbol symbol, ftype)
+      : _symbol = symbol,
+        _name = getName(symbol),
+        isConstructor = false,
+        isStatic = false {
+    _createParameterMirrorList(ftype);
+  }
+
+  JsMethodMirror._staticMethod(JsClassMirror cls, Symbol symbol, ftype)
+      : _symbol = symbol,
+        _name = getName(symbol),
+        isConstructor = false,
+        isStatic = true {
+    _createParameterMirrorList(ftype);
+  }
+
+  // TODO(vsm): Support named constructors.
+  Symbol get constructorName => isConstructor ? _symbol : null;
+  List<ParameterMirror> get parameters => _params;
+  List<InstanceMirror> get metadata => _metadata;
+
+  void _createParameterMirrorList(ftype) {
+    if (ftype == null) {
+      // TODO(vsm): No explicit constructor.  Verify this.
+      _params = const [];
+      _metadata = const [];
+      return;
+    }
+
+    // TODO(vsm): Why does generic function type trigger true for List?
+    if (ftype is! Function && ftype is List) {
+      // Record metadata
+      _metadata = List<InstanceMirror>.unmodifiable(
+          ftype.skip(1).map((a) => reflect(a)));
+      ftype = ftype[0];
+    } else {
+      _metadata = const [];
+    }
+
+    // TODO(vsm): Handle generic function types properly.  Or deprecate mirrors
+    // before we need to!
+    ftype = dart.getFunctionTypeMirror(ftype);
+
+    // TODO(vsm): Add named args.
+    List args = ftype.args;
+    List opts = ftype.optionals;
+    var params = List<ParameterMirror>(args.length + opts.length);
+
+    for (var i = 0; i < args.length; ++i) {
+      var type = args[i];
+      var metadata = ftype.metadata[i];
+      // TODO(vsm): Recover the param name.
+      var param =
+          JsParameterMirror._(Symbol(''), dart.wrapType(type), metadata);
+      params[i] = param;
+    }
+
+    for (var i = 0; i < opts.length; ++i) {
+      var type = opts[i];
+      var metadata = ftype.metadata[args.length + i];
+      // TODO(vsm): Recover the param name.
+      var param =
+          JsParameterMirror._(Symbol(''), dart.wrapType(type), metadata);
+      params[i + args.length] = param;
+    }
+
+    _params = List.unmodifiable(params);
+  }
+
+  String toString() => "MethodMirror on '$_name'";
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_number.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_number.dart
new file mode 100644
index 0000000..5f8c7e0
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_number.dart
@@ -0,0 +1,627 @@
+// Copyright (c) 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 dart._interceptors;
+
+/**
+ * The implementation of Dart's int & double methods.
+ * These are made available as extension methods on `Number` in JS.
+ */
+@JsPeerInterface(name: 'Number')
+class JSNumber extends Interceptor implements int, double {
+  const JSNumber();
+
+  @notNull
+  int compareTo(@nullCheck num b) {
+    if (this < b) {
+      return -1;
+    } else if (this > b) {
+      return 1;
+    } else if (this == b) {
+      if (this == 0) {
+        bool bIsNegative = b.isNegative;
+        if (isNegative == bIsNegative) return 0;
+        if (isNegative) return -1;
+        return 1;
+      }
+      return 0;
+    } else if (isNaN) {
+      if (b.isNaN) {
+        return 0;
+      }
+      return 1;
+    } else {
+      return -1;
+    }
+  }
+
+  @notNull
+  bool get isNegative => (this == 0) ? (1 / this) < 0 : this < 0;
+
+  @notNull
+  bool get isNaN => JS<bool>('!', r'isNaN(#)', this);
+
+  @notNull
+  bool get isInfinite {
+    return JS<bool>('!', r'# == (1/0)', this) ||
+        JS<bool>('!', r'# == (-1/0)', this);
+  }
+
+  @notNull
+  bool get isFinite => JS<bool>('!', r'isFinite(#)', this);
+
+  @notNull
+  JSNumber remainder(@nullCheck num b) {
+    return JS<num>('!', r'# % #', this, b);
+  }
+
+  @notNull
+  JSNumber abs() => JS<num>('!', r'Math.abs(#)', this);
+
+  @notNull
+  JSNumber get sign => this > 0 ? 1 : this < 0 ? -1 : this;
+
+  @notNull
+  static const int _MIN_INT32 = -0x80000000;
+  @notNull
+  static const int _MAX_INT32 = 0x7FFFFFFF;
+
+  @notNull
+  int toInt() {
+    if (this >= _MIN_INT32 && this <= _MAX_INT32) {
+      return JS<int>('!', '# | 0', this);
+    }
+    if (JS<bool>('!', r'isFinite(#)', this)) {
+      return JS<int>(
+          '!', r'# + 0', truncateToDouble()); // Converts -0.0 to +0.0.
+    }
+    // This is either NaN, Infinity or -Infinity.
+    throw UnsupportedError(JS("String", '"" + #', this));
+  }
+
+  @notNull
+  int truncate() => toInt();
+
+  @notNull
+  int ceil() => ceilToDouble().toInt();
+
+  @notNull
+  int floor() => floorToDouble().toInt();
+
+  @notNull
+  int round() {
+    if (this > 0) {
+      // This path excludes the special cases -0.0, NaN and -Infinity, leaving
+      // only +Infinity, for which a direct test is faster than [isFinite].
+      if (JS<bool>('!', r'# !== (1/0)', this)) {
+        return JS<int>('!', r'Math.round(#)', this);
+      }
+    } else if (JS<bool>('!', '# > (-1/0)', this)) {
+      // This test excludes NaN and -Infinity, leaving only -0.0.
+      //
+      // Subtraction from zero rather than negation forces -0.0 to 0.0 so code
+      // inside Math.round and code to handle result never sees -0.0, which on
+      // some JavaScript VMs can be a slow path.
+      return JS<int>('!', r'0 - Math.round(0 - #)', this);
+    }
+    // This is either NaN, Infinity or -Infinity.
+    throw UnsupportedError(JS("String", '"" + #', this));
+  }
+
+  @notNull
+  double ceilToDouble() => JS<num>('!', r'Math.ceil(#)', this);
+
+  @notNull
+  double floorToDouble() => JS<num>('!', r'Math.floor(#)', this);
+
+  @notNull
+  double roundToDouble() {
+    if (this < 0) {
+      return JS<num>('!', r'-Math.round(-#)', this);
+    } else {
+      return JS<num>('!', r'Math.round(#)', this);
+    }
+  }
+
+  @notNull
+  double truncateToDouble() => this < 0 ? ceilToDouble() : floorToDouble();
+
+  @notNull
+  num clamp(@nullCheck num lowerLimit, @nullCheck num upperLimit) {
+    if (lowerLimit.compareTo(upperLimit) > 0) {
+      throw argumentErrorValue(lowerLimit);
+    }
+    if (this.compareTo(lowerLimit) < 0) return lowerLimit;
+    if (this.compareTo(upperLimit) > 0) return upperLimit;
+    return this;
+  }
+
+  @notNull
+  double toDouble() => this;
+
+  @notNull
+  String toStringAsFixed(@notNull int fractionDigits) {
+    if (fractionDigits < 0 || fractionDigits > 20) {
+      throw RangeError.range(fractionDigits, 0, 20, "fractionDigits");
+    }
+    String result = JS<String>('!', r'#.toFixed(#)', this, fractionDigits);
+    if (this == 0 && isNegative) return "-$result";
+    return result;
+  }
+
+  @notNull
+  String toStringAsExponential([int fractionDigits]) {
+    String result;
+    if (fractionDigits != null) {
+      @notNull
+      var _fractionDigits = fractionDigits;
+      if (_fractionDigits < 0 || _fractionDigits > 20) {
+        throw RangeError.range(_fractionDigits, 0, 20, "fractionDigits");
+      }
+      result = JS<String>('!', r'#.toExponential(#)', this, _fractionDigits);
+    } else {
+      result = JS<String>('!', r'#.toExponential()', this);
+    }
+    if (this == 0 && isNegative) return "-$result";
+    return result;
+  }
+
+  @notNull
+  String toStringAsPrecision(@nullCheck int precision) {
+    if (precision < 1 || precision > 21) {
+      throw RangeError.range(precision, 1, 21, "precision");
+    }
+    String result = JS<String>('!', r'#.toPrecision(#)', this, precision);
+    if (this == 0 && isNegative) return "-$result";
+    return result;
+  }
+
+  @notNull
+  String toRadixString(@nullCheck int radix) {
+    if (radix < 2 || radix > 36) {
+      throw RangeError.range(radix, 2, 36, "radix");
+    }
+    String result = JS<String>('!', r'#.toString(#)', this, radix);
+    const int rightParenCode = 0x29;
+    if (result.codeUnitAt(result.length - 1) != rightParenCode) {
+      return result;
+    }
+    return _handleIEtoString(result);
+  }
+
+  @notNull
+  static String _handleIEtoString(String result) {
+    // Result is probably IE's untraditional format for large numbers,
+    // e.g., "8.0000000000008(e+15)" for 0x8000000000000800.toString(16).
+    var match = JS<List>(
+        '', r'/^([\da-z]+)(?:\.([\da-z]+))?\(e\+(\d+)\)$/.exec(#)', result);
+    if (match == null) {
+      // Then we don't know how to handle it at all.
+      throw UnsupportedError("Unexpected toString result: $result");
+    }
+    result = JS('!', '#', match[1]);
+    int exponent = JS("!", "+#", match[3]);
+    if (match[2] != null) {
+      result = JS('!', '# + #', result, match[2]);
+      exponent -= JS<int>('!', '#.length', match[2]);
+    }
+    return result + "0" * exponent;
+  }
+
+  // Note: if you change this, also change the function [S].
+  @notNull
+  String toString() {
+    if (this == 0 && JS<bool>('!', '(1 / #) < 0', this)) {
+      return '-0.0';
+    } else {
+      return JS<String>('!', r'"" + (#)', this);
+    }
+  }
+
+  @notNull
+  int get hashCode {
+    int intValue = JS<int>('!', '# | 0', this);
+    // Fast exit for integers in signed 32-bit range. Masking converts -0.0 to 0
+    // and ensures that result fits in JavaScript engine's Smi range.
+    if (this == intValue) return 0x1FFFFFFF & intValue;
+
+    // We would like to access the exponent and mantissa as integers but there
+    // are no JavaScript operations that do this, so use log2-floor-pow-divide
+    // to extract the values.
+    num absolute = JS<num>('!', 'Math.abs(#)', this);
+    num lnAbsolute = JS<num>('!', 'Math.log(#)', absolute);
+    num log2 = lnAbsolute / ln2;
+    // Floor via '# | 0' converts NaN to zero so the final result is not NaN.
+    int floorLog2 = JS<int>('!', '# | 0', log2);
+    num factor = JS<num>('!', 'Math.pow(2, #)', floorLog2);
+    num scaled = absolute < 1 ? absolute / factor : factor / absolute;
+    // [scaled] is in the range [0.5, 1].
+
+    // Multiply and truncate to pick up all the mantissa bits. Multiplying by
+    // 0x20000000000000 (which has 53 zero bits) converts the mantissa into an
+    // integer. There are interesting subsets where all the bit variance is in
+    // the most significant bits of the mantissa (e.g. 0.5, 0.625, 0.75), so we
+    // need to mix in the most significant bits. We do this by scaling with a
+    // constant that has many bits set to use the multiplier to mix in bits from
+    // all over the mantissa into low positions.
+    num rescaled1 = scaled * 0x20000000000000;
+    num rescaled2 = scaled * 0x0C95A6C285A6C9;
+    int d1 = JS<int>('!', '# | 0', rescaled1);
+    int d2 = JS<int>('!', '# | 0', rescaled2);
+    // Mix in exponent to distinguish e.g. 1.25 from 2.5.
+    int d3 = floorLog2;
+    int h = 0x1FFFFFFF & ((d1 + d2) * (601 * 997) + d3 * (1259));
+    return h;
+  }
+
+  @notNull
+  JSNumber operator -() => JS<num>('!', r'-#', this);
+
+  @notNull
+  JSNumber operator +(@nullCheck num other) {
+    return JS<num>('!', '# + #', this, other);
+  }
+
+  @notNull
+  JSNumber operator -(@nullCheck num other) {
+    return JS<num>('!', '# - #', this, other);
+  }
+
+  @notNull
+  double operator /(@nullCheck num other) {
+    return JS<num>('!', '# / #', this, other);
+  }
+
+  @notNull
+  JSNumber operator *(@nullCheck num other) {
+    return JS<num>('!', '# * #', this, other);
+  }
+
+  @notNull
+  JSNumber operator %(@nullCheck num other) {
+    // Euclidean Modulo.
+    num result = JS<num>('!', r'# % #', this, other);
+    if (result == 0) return (0 as JSNumber); // Make sure we don't return -0.0.
+    if (result > 0) return result;
+    if (JS<num>('!', '#', other) < 0) {
+      return result - JS<num>('!', '#', other);
+    } else {
+      return result + JS<num>('!', '#', other);
+    }
+  }
+
+  @notNull
+  bool _isInt32(@notNull num value) =>
+      JS<bool>('!', '(# | 0) === #', value, value);
+
+  @notNull
+  int operator ~/(@nullCheck num other) {
+    if (_isInt32(this) && _isInt32(other) && 0 != other && -1 != other) {
+      return JS<int>('!', r'(# / #) | 0', this, other);
+    } else {
+      return _tdivSlow(other);
+    }
+  }
+
+  @notNull
+  int _tdivSlow(num other) {
+    return (JS<num>('!', r'# / #', this, other)).toInt();
+  }
+
+  // TODO(ngeoffray): Move the bit operations below to [JSInt] and
+  // make them take an int. Because this will make operations slower,
+  // we define these methods on number for now but we need to decide
+  // the grain at which we do the type checks.
+
+  @notNull
+  int operator <<(@nullCheck num other) {
+    if (other < 0) throwArgumentErrorValue(other);
+    return _shlPositive(other);
+  }
+
+  @notNull
+  int _shlPositive(@notNull num other) {
+    // JavaScript only looks at the last 5 bits of the shift-amount. Shifting
+    // by 33 is hence equivalent to a shift by 1.
+    return JS<bool>('!', r'# > 31', other)
+        ? 0
+        : JS<int>('!', r'(# << #) >>> 0', this, other);
+  }
+
+  @notNull
+  int operator >>(@nullCheck num other) {
+    if (JS<num>('!', '#', other) < 0) throwArgumentErrorValue(other);
+    return _shrOtherPositive(other);
+  }
+
+  @notNull
+  int _shrOtherPositive(@notNull num other) {
+    return JS<num>('!', '#', this) > 0
+        ? _shrBothPositive(other)
+        // For negative numbers we just clamp the shift-by amount.
+        // `this` could be negative but not have its 31st bit set.
+        // The ">>" would then shift in 0s instead of 1s. Therefore
+        // we cannot simply return 0xFFFFFFFF.
+        : JS<int>('!', r'(# >> #) >>> 0', this, other > 31 ? 31 : other);
+  }
+
+  @notNull
+  int _shrBothPositive(@notNull num other) {
+    return JS<bool>('!', r'# > 31', other)
+        // JavaScript only looks at the last 5 bits of the shift-amount. In JS
+        // shifting by 33 is hence equivalent to a shift by 1. Shortcut the
+        // computation when that happens.
+        ? 0
+        // Given that `this` is positive we must not use '>>'. Otherwise a
+        // number that has the 31st bit set would be treated as negative and
+        // shift in ones.
+        : JS<int>('!', r'# >>> #', this, other);
+  }
+
+  @notNull
+  int operator &(@nullCheck num other) {
+    return JS<int>('!', r'(# & #) >>> 0', this, other);
+  }
+
+  @notNull
+  int operator |(@nullCheck num other) {
+    return JS<int>('!', r'(# | #) >>> 0', this, other);
+  }
+
+  @notNull
+  int operator ^(@nullCheck num other) {
+    return JS<int>('!', r'(# ^ #) >>> 0', this, other);
+  }
+
+  @notNull
+  bool operator <(@nullCheck num other) {
+    return JS<bool>('!', '# < #', this, other);
+  }
+
+  @notNull
+  bool operator >(@nullCheck num other) {
+    return JS<bool>('!', '# > #', this, other);
+  }
+
+  @notNull
+  bool operator <=(@nullCheck num other) {
+    return JS<bool>('!', '# <= #', this, other);
+  }
+
+  @notNull
+  bool operator >=(@nullCheck num other) {
+    return JS<bool>('!', '# >= #', this, other);
+  }
+
+  // int members.
+  // TODO(jmesserly): all numbers will have these in dynamic dispatch.
+  // We can fix by checking it at dispatch time but we'd need to structure them
+  // differently.
+
+  @notNull
+  bool get isEven => (this & 1) == 0;
+
+  @notNull
+  bool get isOdd => (this & 1) == 1;
+
+  @notNull
+  int toUnsigned(@nullCheck int width) {
+    return this & ((1 << width) - 1);
+  }
+
+  @notNull
+  int toSigned(@nullCheck int width) {
+    int signMask = 1 << (width - 1);
+    return (this & (signMask - 1)) - (this & signMask);
+  }
+
+  @notNull
+  int get bitLength {
+    int nonneg = this < 0 ? -this - 1 : this;
+    int wordBits = 32;
+    while (nonneg >= 0x100000000) {
+      nonneg = nonneg ~/ 0x100000000;
+      wordBits += 32;
+    }
+    return wordBits - _clz32(nonneg);
+  }
+
+  @notNull
+  static int _clz32(@notNull int uint32) {
+    // TODO(sra): Use `Math.clz32(uint32)` (not available on IE11).
+    return 32 - _bitCount(_spread(uint32));
+  }
+
+  // Returns pow(this, e) % m.
+  @notNull
+  int modPow(@nullCheck int e, @nullCheck int m) {
+    if (e < 0) throw RangeError.range(e, 0, null, "exponent");
+    if (m <= 0) throw RangeError.range(m, 1, null, "modulus");
+    if (e == 0) return 1;
+
+    const int maxPreciseInteger = 9007199254740991;
+
+    // Reject inputs that are outside the range of integer values that can be
+    // represented precisely as a Number (double).
+    if (this < -maxPreciseInteger || this > maxPreciseInteger) {
+      throw RangeError.range(
+          this, -maxPreciseInteger, maxPreciseInteger, 'receiver');
+    }
+    if (e > maxPreciseInteger) {
+      throw RangeError.range(e, 0, maxPreciseInteger, 'exponent');
+    }
+    if (m > maxPreciseInteger) {
+      throw RangeError.range(e, 1, maxPreciseInteger, 'modulus');
+    }
+
+    // This is floor(sqrt(maxPreciseInteger)).
+    const int maxValueThatCanBeSquaredWithoutTruncation = 94906265;
+    if (m > maxValueThatCanBeSquaredWithoutTruncation) {
+      // Use BigInt version to avoid truncation in multiplications below. The
+      // 'maxPreciseInteger' check on [m] ensures that toInt() does not round.
+      return BigInt.from(this).modPow(BigInt.from(e), BigInt.from(m)).toInt();
+    }
+
+    int b = this;
+    if (b < 0 || b > m) {
+      b %= m;
+    }
+    int r = 1;
+    while (e > 0) {
+      if (e.isOdd) {
+        r = (r * b) % m;
+      }
+      e ~/= 2;
+      b = (b * b) % m;
+    }
+    return r;
+  }
+
+  // If inv is false, returns gcd(x, y).
+  // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1.
+  // If inv is true and gcd(x, y) != 1, throws Exception("Not coprime").
+  @notNull
+  static int _binaryGcd(@notNull int x, @notNull int y, @notNull bool inv) {
+    int s = 1;
+    if (!inv) {
+      while (x.isEven && y.isEven) {
+        x ~/= 2;
+        y ~/= 2;
+        s *= 2;
+      }
+      if (y.isOdd) {
+        var t = x;
+        x = y;
+        y = t;
+      }
+    }
+    final bool ac = x.isEven;
+    int u = x;
+    int v = y;
+    int a = 1, b = 0, c = 0, d = 1;
+    do {
+      while (u.isEven) {
+        u ~/= 2;
+        if (ac) {
+          if (!a.isEven || !b.isEven) {
+            a += y;
+            b -= x;
+          }
+          a ~/= 2;
+        } else if (!b.isEven) {
+          b -= x;
+        }
+        b ~/= 2;
+      }
+      while (v.isEven) {
+        v ~/= 2;
+        if (ac) {
+          if (!c.isEven || !d.isEven) {
+            c += y;
+            d -= x;
+          }
+          c ~/= 2;
+        } else if (!d.isEven) {
+          d -= x;
+        }
+        d ~/= 2;
+      }
+      if (u >= v) {
+        u -= v;
+        if (ac) a -= c;
+        b -= d;
+      } else {
+        v -= u;
+        if (ac) c -= a;
+        d -= b;
+      }
+    } while (u != 0);
+    if (!inv) return s * v;
+    if (v != 1) throw Exception("Not coprime");
+    if (d < 0) {
+      d += x;
+      if (d < 0) d += x;
+    } else if (d > x) {
+      d -= x;
+      if (d > x) d -= x;
+    }
+    return d;
+  }
+
+  // Returns 1/this % m, with m > 0.
+  @notNull
+  int modInverse(@nullCheck int m) {
+    if (m <= 0) throw RangeError.range(m, 1, null, "modulus");
+    if (m == 1) return 0;
+    int t = this;
+    if ((t < 0) || (t >= m)) t %= m;
+    if (t == 1) return 1;
+    if ((t == 0) || (t.isEven && m.isEven)) {
+      throw Exception("Not coprime");
+    }
+    return _binaryGcd(m, t, true);
+  }
+
+  // Returns gcd of abs(this) and abs(other).
+  @notNull
+  int gcd(@nullCheck int other) {
+    int x = this.abs();
+    int y = other.abs();
+    if (x == 0) return y;
+    if (y == 0) return x;
+    if ((x == 1) || (y == 1)) return 1;
+    return _binaryGcd(x, y, false);
+  }
+
+  // Assumes i is <= 32-bit and unsigned.
+  @notNull
+  static int _bitCount(@notNull int i) {
+    // See "Hacker's Delight", section 5-1, "Counting 1-Bits".
+
+    // The basic strategy is to use "divide and conquer" to
+    // add pairs (then quads, etc.) of bits together to obtain
+    // sub-counts.
+    //
+    // A straightforward approach would look like:
+    //
+    // i = (i & 0x55555555) + ((i >>  1) & 0x55555555);
+    // i = (i & 0x33333333) + ((i >>  2) & 0x33333333);
+    // i = (i & 0x0F0F0F0F) + ((i >>  4) & 0x0F0F0F0F);
+    // i = (i & 0x00FF00FF) + ((i >>  8) & 0x00FF00FF);
+    // i = (i & 0x0000FFFF) + ((i >> 16) & 0x0000FFFF);
+    //
+    // The code below removes unnecessary &'s and uses a
+    // trick to remove one instruction in the first line.
+
+    i = _shru(i, 0) - (_shru(i, 1) & 0x55555555);
+    i = (i & 0x33333333) + (_shru(i, 2) & 0x33333333);
+    i = 0x0F0F0F0F & (i + _shru(i, 4));
+    i += _shru(i, 8);
+    i += _shru(i, 16);
+    return (i & 0x0000003F);
+  }
+
+  @notNull
+  static int _shru(int value, int shift) =>
+      JS<int>('!', '# >>> #', value, shift);
+  @notNull
+  static int _shrs(int value, int shift) =>
+      JS<int>('!', '# >> #', value, shift);
+  @notNull
+  static int _ors(int a, int b) => JS<int>('!', '# | #', a, b);
+
+  // Assumes i is <= 32-bit
+  @notNull
+  static int _spread(@notNull int i) {
+    i = _ors(i, _shrs(i, 1));
+    i = _ors(i, _shrs(i, 2));
+    i = _ors(i, _shrs(i, 4));
+    i = _ors(i, _shrs(i, 8));
+    i = _shru(_ors(i, _shrs(i, 16)), 0);
+    return i;
+  }
+
+  @notNull
+  int operator ~() => JS<int>('!', r'(~#) >>> 0', this);
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_primitives.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_primitives.dart
new file mode 100644
index 0000000..1347b62
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_primitives.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.
+
+/// dart2js "primitives", that is, features that cannot be implemented without
+/// access to JavaScript features.
+library dart2js._js_primitives;
+
+import 'dart:_foreign_helper' show JS;
+
+/**
+ * This is the low-level method that is used to implement [print].  It is
+ * possible to override this function from JavaScript by defining a function in
+ * JavaScript called "dartPrint".
+ *
+ * Notice that it is also possible to intercept calls to [print] from within a
+ * Dart program using zones. This means that there is no guarantee that a call
+ * to print ends in this method.
+ */
+void printString(String string) {
+  if (JS<bool>('!', r'typeof dartPrint == "function"')) {
+    // Support overriding print from JavaScript.
+    JS('void', r'dartPrint(#)', string);
+    return;
+  }
+
+  // Inside browser or nodejs.
+  if (JS<bool>('!', r'typeof console == "object"') &&
+      JS<bool>('!', r'typeof console.log != "undefined"')) {
+    JS('void', r'console.log(#)', string);
+    return;
+  }
+
+  // Don't throw inside IE, the console is only defined if dev tools is open.
+  if (JS<bool>('!', r'typeof window == "object"')) {
+    return;
+  }
+
+  // Running in d8, the V8 developer shell, or in Firefox' js-shell.
+  if (JS<bool>('!', r'typeof print == "function"')) {
+    JS('void', r'print(#)', string);
+    return;
+  }
+
+  // This is somewhat nasty, but we don't want to drag in a bunch of
+  // dependencies to handle a situation that cannot happen. So we
+  // avoid using Dart [:throw:] and Dart [toString].
+  JS('void', 'throw "Unable to print message: " + String(#)', string);
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_rti.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_rti.dart
new file mode 100644
index 0000000..015c83e
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_rti.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.
+
+part of dart._js_helper;
+
+// TODO(leafp): Maybe get rid of this?  Currently used by the interceptors
+// library, but that should probably be culled as well.
+Type getRuntimeType(var object) =>
+    JS('Type|null', 'dart.getReifiedType(#)', object);
+
+/// 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;
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_string.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_string.dart
new file mode 100644
index 0000000..4271d34
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_string.dart
@@ -0,0 +1,507 @@
+// Copyright (c) 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 dart._interceptors;
+
+/**
+ * The interceptor class for [String]. The compiler recognizes this
+ * class as an interceptor, and changes references to [:this:] to
+ * actually use the receiver of the method, which is generated as an extra
+ * argument added to each member.
+ */
+@JsPeerInterface(name: 'String')
+class JSString extends Interceptor implements String, JSIndexable<String> {
+  const JSString();
+
+  @notNull
+  int codeUnitAt(@nullCheck int index) {
+    // Suppress 2nd null check on index and null check on length
+    // (JS String.length cannot be null).
+    final len = this.length;
+    if (index < 0 || index >= len) {
+      throw RangeError.index(index, this, 'index', null, len);
+    }
+    return JS<int>('!', r'#.charCodeAt(#)', this, index);
+  }
+
+  @notNull
+  Iterable<Match> allMatches(@nullCheck String string,
+      [@nullCheck int start = 0]) {
+    final len = string.length;
+    if (0 > start || start > len) {
+      throw RangeError.range(start, 0, len);
+    }
+    return allMatchesInStringUnchecked(this, string, start);
+  }
+
+  Match matchAsPrefix(@nullCheck String string, [@nullCheck int start = 0]) {
+    int stringLength = JS('!', '#.length', string);
+    if (start < 0 || start > stringLength) {
+      throw RangeError.range(start, 0, stringLength);
+    }
+    int thisLength = JS('!', '#.length', this);
+    if (start + thisLength > stringLength) return null;
+    for (int i = 0; i < thisLength; i++) {
+      if (string.codeUnitAt(start + i) != this.codeUnitAt(i)) {
+        return null;
+      }
+    }
+    return StringMatch(start, string, this);
+  }
+
+  @notNull
+  String operator +(@nullCheck String other) {
+    return JS<String>('!', r'# + #', this, other);
+  }
+
+  @notNull
+  bool endsWith(@nullCheck String other) {
+    var otherLength = other.length;
+    var thisLength = this.length;
+    if (otherLength > thisLength) return false;
+    return other == substring(thisLength - otherLength);
+  }
+
+  @notNull
+  String replaceAll(Pattern from, @nullCheck String to) {
+    return stringReplaceAllUnchecked(this, from, to);
+  }
+
+  @notNull
+  String replaceAllMapped(Pattern from, String convert(Match match)) {
+    return this.splitMapJoin(from, onMatch: convert);
+  }
+
+  @notNull
+  String splitMapJoin(Pattern from,
+      {String onMatch(Match match), String onNonMatch(String nonMatch)}) {
+    return stringReplaceAllFuncUnchecked(this, from, onMatch, onNonMatch);
+  }
+
+  @notNull
+  String replaceFirst(Pattern from, @nullCheck String to,
+      [@nullCheck int startIndex = 0]) {
+    RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex");
+    return stringReplaceFirstUnchecked(this, from, to, startIndex);
+  }
+
+  @notNull
+  String replaceFirstMapped(
+      Pattern from, @nullCheck String replace(Match match),
+      [@nullCheck int startIndex = 0]) {
+    RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex");
+    return stringReplaceFirstMappedUnchecked(this, from, replace, startIndex);
+  }
+
+  @notNull
+  List<String> split(@nullCheck Pattern pattern) {
+    if (pattern is String) {
+      return JSArray.of(JS('', r'#.split(#)', this, pattern));
+    } else if (pattern is JSSyntaxRegExp && regExpCaptureCount(pattern) == 0) {
+      var re = regExpGetNative(pattern);
+      return JSArray.of(JS('', r'#.split(#)', this, re));
+    } else {
+      return _defaultSplit(pattern);
+    }
+  }
+
+  @notNull
+  String replaceRange(
+      @nullCheck int start, int end, @nullCheck String replacement) {
+    end = RangeError.checkValidRange(start, end, this.length);
+    return stringReplaceRangeUnchecked(this, start, end, replacement);
+  }
+
+  @notNull
+  List<String> _defaultSplit(Pattern pattern) {
+    List<String> result = <String>[];
+    // End of most recent match. That is, start of next part to add to result.
+    int start = 0;
+    // Length of most recent match.
+    // Set >0, so no match on the empty string causes the result to be [""].
+    int length = 1;
+    for (var match in pattern.allMatches(this)) {
+      @notNull
+      int matchStart = match.start;
+      @notNull
+      int matchEnd = match.end;
+      length = matchEnd - matchStart;
+      if (length == 0 && start == matchStart) {
+        // An empty match right after another match is ignored.
+        // This includes an empty match at the start of the string.
+        continue;
+      }
+      int end = matchStart;
+      result.add(this.substring(start, end));
+      start = matchEnd;
+    }
+    if (start < this.length || length > 0) {
+      // An empty match at the end of the string does not cause a "" at the end.
+      // A non-empty match ending at the end of the string does add a "".
+      result.add(this.substring(start));
+    }
+    return result;
+  }
+
+  @notNull
+  bool startsWith(Pattern pattern, [@nullCheck int index = 0]) {
+    // Suppress null check on length and all but the first
+    // reference to index.
+    int length = JS<int>('!', '#.length', this);
+    if (index < 0 || JS<int>('!', '#', index) > length) {
+      throw RangeError.range(index, 0, this.length);
+    }
+    if (pattern is String) {
+      String other = pattern;
+      int otherLength = JS<int>('!', '#.length', other);
+      int endIndex = index + otherLength;
+      if (endIndex > length) return false;
+      return other ==
+          JS<String>('!', r'#.substring(#, #)', this, index, endIndex);
+    }
+    return pattern.matchAsPrefix(this, index) != null;
+  }
+
+  @notNull
+  String substring(@nullCheck int startIndex, [int _endIndex]) {
+    var length = this.length;
+    final endIndex = _endIndex ?? length;
+    if (startIndex < 0) throw RangeError.value(startIndex);
+    if (startIndex > endIndex) throw RangeError.value(startIndex);
+    if (endIndex > length) throw RangeError.value(endIndex);
+    return JS<String>('!', r'#.substring(#, #)', this, startIndex, endIndex);
+  }
+
+  @notNull
+  String toLowerCase() {
+    return JS<String>('!', r'#.toLowerCase()', this);
+  }
+
+  @notNull
+  String toUpperCase() {
+    return JS<String>('!', r'#.toUpperCase()', this);
+  }
+
+  // Characters with Whitespace property (Unicode 6.3).
+  // 0009..000D    ; White_Space # Cc       <control-0009>..<control-000D>
+  // 0020          ; White_Space # Zs       SPACE
+  // 0085          ; White_Space # Cc       <control-0085>
+  // 00A0          ; White_Space # Zs       NO-BREAK SPACE
+  // 1680          ; White_Space # Zs       OGHAM SPACE MARK
+  // 2000..200A    ; White_Space # Zs       EN QUAD..HAIR SPACE
+  // 2028          ; White_Space # Zl       LINE SEPARATOR
+  // 2029          ; White_Space # Zp       PARAGRAPH SEPARATOR
+  // 202F          ; White_Space # Zs       NARROW NO-BREAK SPACE
+  // 205F          ; White_Space # Zs       MEDIUM MATHEMATICAL SPACE
+  // 3000          ; White_Space # Zs       IDEOGRAPHIC SPACE
+  //
+  // BOM: 0xFEFF
+  @notNull
+  static bool _isWhitespace(@notNull int codeUnit) {
+    // Most codeUnits should be less than 256. Special case with a smaller
+    // switch.
+    if (codeUnit < 256) {
+      switch (codeUnit) {
+        case 0x09:
+        case 0x0A:
+        case 0x0B:
+        case 0x0C:
+        case 0x0D:
+        case 0x20:
+        case 0x85:
+        case 0xA0:
+          return true;
+        default:
+          return false;
+      }
+    }
+    switch (codeUnit) {
+      case 0x1680:
+      case 0x2000:
+      case 0x2001:
+      case 0x2002:
+      case 0x2003:
+      case 0x2004:
+      case 0x2005:
+      case 0x2006:
+      case 0x2007:
+      case 0x2008:
+      case 0x2009:
+      case 0x200A:
+      case 0x2028:
+      case 0x2029:
+      case 0x202F:
+      case 0x205F:
+      case 0x3000:
+      case 0xFEFF:
+        return true;
+      default:
+        return false;
+    }
+  }
+
+  /// Finds the index of the first non-whitespace character, or the
+  /// end of the string. Start looking at position [index].
+  @notNull
+  static int _skipLeadingWhitespace(String string, @nullCheck int index) {
+    const int SPACE = 0x20;
+    const int CARRIAGE_RETURN = 0x0D;
+    var stringLength = string.length;
+    while (index < stringLength) {
+      int codeUnit = string.codeUnitAt(index);
+      if (codeUnit != SPACE &&
+          codeUnit != CARRIAGE_RETURN &&
+          !_isWhitespace(codeUnit)) {
+        break;
+      }
+      index++;
+    }
+    return index;
+  }
+
+  /// Finds the index after the last non-whitespace character, or 0.
+  /// Start looking at position [index - 1].
+  @notNull
+  static int _skipTrailingWhitespace(String string, @nullCheck int index) {
+    const int SPACE = 0x20;
+    const int CARRIAGE_RETURN = 0x0D;
+    while (index > 0) {
+      int codeUnit = string.codeUnitAt(index - 1);
+      if (codeUnit != SPACE &&
+          codeUnit != CARRIAGE_RETURN &&
+          !_isWhitespace(codeUnit)) {
+        break;
+      }
+      index--;
+    }
+    return index;
+  }
+
+  // Dart2js can't use JavaScript trim directly,
+  // because JavaScript does not trim
+  // the NEXT LINE (NEL) character (0x85).
+  @notNull
+  String trim() {
+    const int NEL = 0x85;
+
+    // Start by doing JS trim. Then check if it leaves a NEL at
+    // either end of the string.
+    String result = JS('!', '#.trim()', this);
+    final length = result.length;
+    if (length == 0) return result;
+    int firstCode = result.codeUnitAt(0);
+    int startIndex = 0;
+    if (firstCode == NEL) {
+      startIndex = _skipLeadingWhitespace(result, 1);
+      if (startIndex == length) return "";
+    }
+
+    int endIndex = length;
+    // We know that there is at least one character that is non-whitespace.
+    // Therefore we don't need to verify that endIndex > startIndex.
+    int lastCode = result.codeUnitAt(endIndex - 1);
+    if (lastCode == NEL) {
+      endIndex = _skipTrailingWhitespace(result, endIndex - 1);
+    }
+    if (startIndex == 0 && endIndex == length) return result;
+    return JS<String>('!', r'#.substring(#, #)', result, startIndex, endIndex);
+  }
+
+  // Dart2js can't use JavaScript trimLeft directly,
+  // because it is not in ES5, so not every browser implements it,
+  // and because those that do will not trim the NEXT LINE character (0x85).
+  @notNull
+  String trimLeft() {
+    const int NEL = 0x85;
+
+    // Start by doing JS trim. Then check if it leaves a NEL at
+    // the beginning of the string.
+    String result;
+    int startIndex = 0;
+    if (JS<bool>('!', 'typeof #.trimLeft != "undefined"', this)) {
+      result = JS<String>('!', '#.trimLeft()', this);
+      if (result.length == 0) return result;
+      int firstCode = result.codeUnitAt(0);
+      if (firstCode == NEL) {
+        startIndex = _skipLeadingWhitespace(result, 1);
+      }
+    } else {
+      result = this;
+      startIndex = _skipLeadingWhitespace(this, 0);
+    }
+    if (startIndex == 0) return result;
+    if (startIndex == result.length) return "";
+    return JS<String>('!', r'#.substring(#)', result, startIndex);
+  }
+
+  // Dart2js can't use JavaScript trimRight directly,
+  // because it is not in ES5 and because JavaScript does not trim
+  // the NEXT LINE character (0x85).
+  @notNull
+  String trimRight() {
+    const int NEL = 0x85;
+
+    // Start by doing JS trim. Then check if it leaves a NEL or BOM at
+    // the end of the string.
+    String result;
+    @notNull
+    int endIndex = 0;
+    // trimRight is implemented by Firefox and Chrome/Blink,
+    // so use it if it is there.
+    if (JS<bool>('!', 'typeof #.trimRight != "undefined"', this)) {
+      result = JS<String>('!', '#.trimRight()', this);
+      endIndex = result.length;
+      if (endIndex == 0) return result;
+      int lastCode = result.codeUnitAt(endIndex - 1);
+      if (lastCode == NEL) {
+        endIndex = _skipTrailingWhitespace(result, endIndex - 1);
+      }
+    } else {
+      result = this;
+      endIndex = _skipTrailingWhitespace(this, this.length);
+    }
+
+    if (endIndex == result.length) return result;
+    if (endIndex == 0) return "";
+    return JS<String>('!', r'#.substring(#, #)', result, 0, endIndex);
+  }
+
+  @notNull
+  String operator *(@nullCheck int times) {
+    if (0 >= times) return '';
+    if (times == 1 || this.length == 0) return this;
+    if (times != JS<int>('!', '# >>> 0', times)) {
+      // times >= 2^32. We can't create a string that big.
+      throw const OutOfMemoryError();
+    }
+    var result = '';
+    String s = this;
+    while (true) {
+      if (times & 1 == 1) result = s + result;
+      times = JS<int>('!', '# >>> 1', times);
+      if (times == 0) break;
+      s += s;
+    }
+    return result;
+  }
+
+  @notNull
+  String padLeft(@nullCheck int width, [String padding = ' ']) {
+    int delta = width - this.length;
+    if (delta <= 0) return this;
+    return padding * delta + this;
+  }
+
+  @notNull
+  String padRight(@nullCheck int width, [String padding = ' ']) {
+    int delta = width - this.length;
+    if (delta <= 0) return this;
+    return this + padding * delta;
+  }
+
+  @notNull
+  List<int> get codeUnits => CodeUnits(this);
+
+  @notNull
+  Runes get runes => Runes(this);
+
+  @notNull
+  int indexOf(@nullCheck Pattern pattern, [@nullCheck int start = 0]) {
+    if (start < 0 || start > this.length) {
+      throw RangeError.range(start, 0, this.length);
+    }
+    if (pattern is String) {
+      return stringIndexOfStringUnchecked(this, pattern, start);
+    }
+    if (pattern is JSSyntaxRegExp) {
+      JSSyntaxRegExp re = pattern;
+      Match match = firstMatchAfter(re, this, start);
+      return (match == null) ? -1 : match.start;
+    }
+    var length = this.length;
+    for (int i = start; i <= length; i++) {
+      if (pattern.matchAsPrefix(this, i) != null) return i;
+    }
+    return -1;
+  }
+
+  @notNull
+  int lastIndexOf(@nullCheck Pattern pattern, [int _start]) {
+    var length = this.length;
+    var start = _start ?? length;
+    if (start < 0 || start > length) {
+      throw RangeError.range(start, 0, length);
+    }
+    if (pattern is String) {
+      String other = pattern;
+      if (start + other.length > length) {
+        start = length - other.length;
+      }
+      return stringLastIndexOfUnchecked(this, other, start);
+    }
+    for (int i = start; i >= 0; i--) {
+      if (pattern.matchAsPrefix(this, i) != null) return i;
+    }
+    return -1;
+  }
+
+  @notNull
+  bool contains(@nullCheck Pattern other, [@nullCheck int startIndex = 0]) {
+    if (startIndex < 0 || startIndex > this.length) {
+      throw RangeError.range(startIndex, 0, this.length);
+    }
+    return stringContainsUnchecked(this, other, startIndex);
+  }
+
+  @notNull
+  bool get isEmpty => JS<int>('!', '#.length', this) == 0;
+
+  @notNull
+  bool get isNotEmpty => !isEmpty;
+
+  @notNull
+  int compareTo(@nullCheck String other) {
+    return this == other ? 0 : JS<bool>('!', r'# < #', this, other) ? -1 : 1;
+  }
+
+  // Note: if you change this, also change the function [S].
+  @notNull
+  String toString() => this;
+
+  /**
+   * This is the [Jenkins hash function][1] but using masking to keep
+   * values in SMI range.
+   *
+   * [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
+   */
+  @notNull
+  int get hashCode {
+    // TODO(ahe): This method shouldn't have to use JS. Update when our
+    // optimizations are smarter.
+    int hash = 0;
+    int length = JS('!', '#.length', this);
+    for (int i = 0; i < length; i++) {
+      hash = 0x1fffffff & (hash + JS<int>('!', r'#.charCodeAt(#)', this, i));
+      hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
+      hash = JS<int>('!', '# ^ (# >> 6)', hash, hash);
+    }
+    hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
+    hash = JS<int>('!', '# ^ (# >> 11)', hash, hash);
+    return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
+  }
+
+  @notNull
+  Type get runtimeType => String;
+
+  @notNull
+  final int length;
+
+  @notNull
+  String operator [](@nullCheck int index) {
+    if (index >= JS<int>('!', '#.length', this) || index < 0) {
+      throw diagnoseIndexError(this, index);
+    }
+    return JS<String>('!', '#[#]', this, index);
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/linked_hash_map.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/linked_hash_map.dart
new file mode 100644
index 0000000..1c03db8
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/linked_hash_map.dart
@@ -0,0 +1,278 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Efficient JavaScript based implementation of a linked hash map used as a
+// backing map for constant maps and the [LinkedHashMap] patch
+
+part of dart._js_helper;
+
+abstract class InternalMap<K, V> extends MapBase<K, V>
+    implements LinkedHashMap<K, V>, HashMap<K, V> {
+  @notNull
+  get _map;
+
+  @notNull
+  int get _modifications;
+
+  void forEach(void action(K key, V value)) {
+    int modifications = _modifications;
+    for (var entry in JS('Iterable', '#.entries()', _map)) {
+      action(JS('', '#[0]', entry), JS('', '#[1]', entry));
+      if (modifications != _modifications) {
+        throw ConcurrentModificationError(this);
+      }
+    }
+  }
+}
+
+/// A linked hash map implementation based on ES6 Map.
+///
+/// Items that can use identity semantics are stored directly in the backing
+/// map.
+///
+/// Items that have a custom equality/hashCode are first canonicalized by
+/// looking up the canonical key by its hashCode.
+class LinkedMap<K, V> extends InternalMap<K, V> {
+  /// The backing store for this map.
+  ///
+  /// Keys that use identity equality are stored directly. For other types of
+  /// keys, we first look them up (by hashCode) in the [_keyMap] map, then
+  /// we lookup the key in this map.
+  @notNull
+  final _map = JS('', 'new Map()');
+
+  /// Items that use custom equality semantics.
+  ///
+  /// This maps from the item's hashCode to the canonical key, which is then
+  /// used to lookup the item in [_map]. Keeping the data in our primary backing
+  /// map gives us the ordering semantics requred by [LinkedHashMap], while
+  /// also providing convenient access to keys/values.
+  @notNull
+  final _keyMap = JS('', 'new Map()');
+
+  // We track the number of modifications done to the key set of the
+  // hash map to be able to throw when the map is modified while being
+  // iterated over.
+  //
+  // Value cycles after 2^30 modifications so that modification counts are
+  // always unboxed (Smi) values. Modification detection will be missed if you
+  // make exactly some multiple of 2^30 modifications between advances of an
+  // iterator.
+  @notNull
+  int _modifications = 0;
+
+  LinkedMap();
+
+  /// Called by generated code for a map literal.
+  LinkedMap.from(JSArray entries) {
+    var map = _map;
+    var keyMap = _keyMap;
+    for (int i = 0, n = JS('!', '#.length', entries); i < n; i += 2) {
+      K key = JS('', '#[#]', entries, i);
+      V value = JS('', '#[#]', entries, i + 1);
+      if (key == null) {
+        key = null;
+      } else if (JS<bool>('!', '#[#] !== #', key,
+          dart.extensionSymbol('_equals'), dart.identityEquals)) {
+        key = putLinkedMapKey(key, keyMap);
+      }
+      JS('', '#.set(#, #)', map, key, value);
+    }
+  }
+
+  @notNull
+  int get length => JS<int>('!', '#.size', _map);
+
+  @notNull
+  bool get isEmpty => JS<bool>('!', '#.size == 0', _map);
+
+  @notNull
+  bool get isNotEmpty => JS<bool>('!', '#.size != 0', _map);
+
+  Iterable<K> get keys => _JSMapIterable<K>(this, true);
+  Iterable<V> get values => _JSMapIterable<V>(this, false);
+
+  @notNull
+  bool containsKey(Object key) {
+    if (key == null) {
+      key = null;
+    } else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
+        dart.identityEquals)) {
+      @notNull
+      var k = key;
+      var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode);
+      if (buckets != null) {
+        for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
+          k = JS('', '#[#]', buckets, i);
+          if (k == key) return true;
+        }
+      }
+      return false;
+    }
+    return JS<bool>('!', '#.has(#)', _map, key);
+  }
+
+  bool containsValue(Object value) {
+    for (var v in JS('', '#.values()', _map)) {
+      if (v == value) return true;
+    }
+    return false;
+  }
+
+  void addAll(Map<K, V> other) {
+    var map = _map;
+    int length = JS('', '#.size', map);
+    other.forEach((K key, V value) {
+      if (key == null) {
+        key = null;
+      } else if (JS<bool>('!', '#[#] !== #', key,
+          dart.extensionSymbol('_equals'), dart.identityEquals)) {
+        key = putLinkedMapKey(key, _keyMap);
+      }
+      JS('', '#.set(#, #)', _map, key, value);
+    });
+    if (length != JS<int>('!', '#.size', map)) {
+      _modifications = (_modifications + 1) & 0x3ffffff;
+    }
+  }
+
+  V operator [](Object key) {
+    if (key == null) {
+      key = null;
+    } else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
+        dart.identityEquals)) {
+      @notNull
+      var k = key;
+      var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode);
+      if (buckets != null) {
+        for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
+          k = JS('', '#[#]', buckets, i);
+          if (k == key) return JS('', '#.get(#)', _map, k);
+        }
+      }
+      return null;
+    }
+    V value = JS('', '#.get(#)', _map, key);
+    return value == null ? null : value; // coerce undefined to null.
+  }
+
+  void operator []=(K key, V value) {
+    if (key == null) {
+      key = null;
+    } else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
+        dart.identityEquals)) {
+      key = putLinkedMapKey(key, _keyMap);
+    }
+    var map = _map;
+    int length = JS('', '#.size', map);
+    JS('', '#.set(#, #)', map, key, value);
+    if (length != JS<int>('!', '#.size', map)) {
+      _modifications = (_modifications + 1) & 0x3ffffff;
+    }
+  }
+
+  V putIfAbsent(K key, V ifAbsent()) {
+    var map = _map;
+    if (key == null) {
+      key = null;
+      if (JS<bool>('!', '#.has(null)', map)) return JS('', '#.get(null)', map);
+    } else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
+        dart.identityEquals)) {
+      @notNull
+      K k = key;
+      var hash = JS<int>('!', '# & 0x3ffffff', k.hashCode);
+      var buckets = JS('', '#.get(#)', _keyMap, hash);
+      if (buckets == null) {
+        JS('', '#.set(#, [#])', _keyMap, hash, key);
+      } else {
+        for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
+          k = JS('', '#[#]', buckets, i);
+          if (k == key) return JS('', '#.get(#)', map, k);
+        }
+        JS('', '#.push(#)', buckets, key);
+      }
+    } else if (JS<bool>('!', '#.has(#)', map, key)) {
+      return JS('', '#.get(#)', map, key);
+    }
+    V value = ifAbsent();
+    if (value == null) value = null; // coerce undefined to null.
+    JS('', '#.set(#, #)', map, key, value);
+    _modifications = (_modifications + 1) & 0x3ffffff;
+    return value;
+  }
+
+  V remove(Object key) {
+    if (key == null) {
+      key = null;
+    } else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
+        dart.identityEquals)) {
+      @notNull
+      var k = key;
+      var hash = JS<int>('!', '# & 0x3ffffff', k.hashCode);
+      var buckets = JS('', '#.get(#)', _keyMap, hash);
+      if (buckets == null) return null; // not found
+      for (int i = 0, n = JS('!', '#.length', buckets);;) {
+        k = JS('', '#[#]', buckets, i);
+        if (k == key) {
+          key = k;
+          if (n == 1) {
+            JS('', '#.delete(#)', _keyMap, hash);
+          } else {
+            JS('', '#.splice(#, 1)', buckets, i);
+          }
+          break;
+        }
+        if (++i >= n) return null; // not found
+      }
+    }
+    var map = _map;
+    V value = JS('', '#.get(#)', map, key);
+    if (JS<bool>('!', '#.delete(#)', map, key)) {
+      _modifications = (_modifications + 1) & 0x3ffffff;
+    }
+    return value == null ? null : value; // coerce undefined to null.
+  }
+
+  void clear() {
+    var map = _map;
+    if (JS<int>('!', '#.size', map) > 0) {
+      JS('', '#.clear()', map);
+      JS('', '#.clear()', _keyMap);
+      _modifications = (_modifications + 1) & 0x3ffffff;
+    }
+  }
+}
+
+@NoReifyGeneric()
+K putLinkedMapKey<K>(@notNull K key, keyMap) {
+  var hash = JS<int>('!', '# & 0x3ffffff', key.hashCode);
+  var buckets = JS('', '#.get(#)', keyMap, hash);
+  if (buckets == null) {
+    JS('', '#.set(#, [#])', keyMap, hash, key);
+    return key;
+  }
+  for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
+    @notNull
+    K k = JS('', '#[#]', buckets, i);
+    if (k == key) return k;
+  }
+  JS('', '#.push(#)', buckets, key);
+  return key;
+}
+
+class ImmutableMap<K, V> extends LinkedMap<K, V> {
+  ImmutableMap.from(JSArray entries) : super.from(entries);
+
+  void operator []=(Object key, Object value) {
+    throw _unsupported();
+  }
+
+  void addAll(Object other) => throw _unsupported();
+  void clear() => throw _unsupported();
+  V remove(Object key) => throw _unsupported();
+  V putIfAbsent(Object key, Object ifAbsent()) => throw _unsupported();
+
+  static Error _unsupported() =>
+      UnsupportedError("Cannot modify unmodifiable map");
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/mirror_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/mirror_helper.dart
new file mode 100644
index 0000000..f78926a
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/mirror_helper.dart
@@ -0,0 +1,8 @@
+// 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.
+/**
+ * Helps dealing with reflection in the case that the source code has been
+ * changed as a result of compiling with dart2dart.
+ */
+library dart._mirror_helper;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_helper.dart
new file mode 100644
index 0000000..cc214e8
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_helper.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 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 dart._js_helper;
+
+// Obsolete in dart dev compiler. Added only so that the same version of
+// dart:html can be used in dart2js an dev compiler.
+F convertDartClosureToJS<F>(F closure, int arity) {
+  return closure;
+}
+
+// Warning: calls to these methods need to be removed before custom elements
+// and cross-frame dom objects behave correctly in ddc
+// https://github.com/dart-lang/sdk/issues/28326
+setNativeSubclassDispatchRecord(proto, interceptor) {}
+findDispatchTagForInterceptorClass(interceptorClassConstructor) {}
+makeLeafDispatchRecord(interceptor) {}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart
new file mode 100644
index 0000000..2a7a621
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart
@@ -0,0 +1,1902 @@
+// 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.
+
+/**
+ * Specialized integers and floating point numbers,
+ * with SIMD support and efficient lists.
+ */
+library dart.typed_data.implementation;
+
+import 'dart:collection';
+import 'dart:_internal';
+import 'dart:_interceptors' show JSIndexable;
+import 'dart:_js_helper'
+    show
+        Creates,
+        JavaScriptIndexingBehavior,
+        JSName,
+        Native,
+        Null,
+        Returns,
+        diagnoseIndexError,
+        diagnoseRangeError;
+import 'dart:_foreign_helper' show JS;
+import 'dart:math' as Math;
+
+import 'dart:typed_data';
+
+@Native("ArrayBuffer")
+class NativeByteBuffer implements ByteBuffer {
+  @JSName('byteLength')
+  external int get lengthInBytes;
+
+  Type get runtimeType => ByteBuffer;
+
+  Uint8List asUint8List([int offsetInBytes = 0, int length]) {
+    return NativeUint8List.view(this, offsetInBytes, length);
+  }
+
+  Int8List asInt8List([int offsetInBytes = 0, int length]) {
+    return NativeInt8List.view(this, offsetInBytes, length);
+  }
+
+  Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int length]) {
+    return NativeUint8ClampedList.view(this, offsetInBytes, length);
+  }
+
+  Uint16List asUint16List([int offsetInBytes = 0, int length]) {
+    return NativeUint16List.view(this, offsetInBytes, length);
+  }
+
+  Int16List asInt16List([int offsetInBytes = 0, int length]) {
+    return NativeInt16List.view(this, offsetInBytes, length);
+  }
+
+  Uint32List asUint32List([int offsetInBytes = 0, int length]) {
+    return NativeUint32List.view(this, offsetInBytes, length);
+  }
+
+  Int32List asInt32List([int offsetInBytes = 0, int length]) {
+    return NativeInt32List.view(this, offsetInBytes, length);
+  }
+
+  Uint64List asUint64List([int offsetInBytes = 0, int length]) {
+    throw UnsupportedError("Uint64List not supported by dart2js.");
+  }
+
+  Int64List asInt64List([int offsetInBytes = 0, int length]) {
+    throw UnsupportedError("Int64List not supported by dart2js.");
+  }
+
+  Int32x4List asInt32x4List([int offsetInBytes = 0, int length]) {
+    NativeInt32List storage =
+        this.asInt32List(offsetInBytes, length != null ? length * 4 : null);
+    return NativeInt32x4List._externalStorage(storage);
+  }
+
+  Float32List asFloat32List([int offsetInBytes = 0, int length]) {
+    return NativeFloat32List.view(this, offsetInBytes, length);
+  }
+
+  Float64List asFloat64List([int offsetInBytes = 0, int length]) {
+    return NativeFloat64List.view(this, offsetInBytes, length);
+  }
+
+  Float32x4List asFloat32x4List([int offsetInBytes = 0, int length]) {
+    NativeFloat32List storage =
+        this.asFloat32List(offsetInBytes, length != null ? length * 4 : null);
+    return NativeFloat32x4List._externalStorage(storage);
+  }
+
+  Float64x2List asFloat64x2List([int offsetInBytes = 0, int length]) {
+    NativeFloat64List storage =
+        this.asFloat64List(offsetInBytes, length != null ? length * 2 : null);
+    return NativeFloat64x2List._externalStorage(storage);
+  }
+
+  ByteData asByteData([int offsetInBytes = 0, int length]) {
+    return NativeByteData.view(this, offsetInBytes, length);
+  }
+}
+
+/**
+ * A fixed-length list of Float32x4 numbers that is viewable as a
+ * [TypedData]. For long lists, this implementation will be considerably more
+ * space- and time-efficient than the default [List] implementation.
+ */
+class NativeFloat32x4List extends Object
+    with ListMixin<Float32x4>, FixedLengthListMixin<Float32x4>
+    implements Float32x4List {
+  final NativeFloat32List _storage;
+
+  /**
+   * Creates a [Float32x4List] of the specified length (in elements),
+   * all of whose elements are initially zero.
+   */
+  NativeFloat32x4List(int length) : _storage = NativeFloat32List(length * 4);
+
+  NativeFloat32x4List._externalStorage(this._storage);
+
+  NativeFloat32x4List._slowFromList(List<Float32x4> list)
+      : _storage = NativeFloat32List(list.length * 4) {
+    for (int i = 0; i < list.length; i++) {
+      var e = list[i];
+      _storage[(i * 4) + 0] = e.x;
+      _storage[(i * 4) + 1] = e.y;
+      _storage[(i * 4) + 2] = e.z;
+      _storage[(i * 4) + 3] = e.w;
+    }
+  }
+
+  Type get runtimeType => Float32x4List;
+
+  /**
+   * Creates a [Float32x4List] with the same size as the [elements] list
+   * and copies over the elements.
+   */
+  factory NativeFloat32x4List.fromList(List<Float32x4> list) {
+    if (list is NativeFloat32x4List) {
+      return NativeFloat32x4List._externalStorage(
+          NativeFloat32List.fromList(list._storage));
+    } else {
+      return NativeFloat32x4List._slowFromList(list);
+    }
+  }
+
+  ByteBuffer get buffer => _storage.buffer;
+
+  int get lengthInBytes => _storage.lengthInBytes;
+
+  int get offsetInBytes => _storage.offsetInBytes;
+
+  int get elementSizeInBytes => Float32x4List.bytesPerElement;
+
+  int get length => _storage.length ~/ 4;
+
+  Float32x4 operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    double _x = _storage[(index * 4) + 0];
+    double _y = _storage[(index * 4) + 1];
+    double _z = _storage[(index * 4) + 2];
+    double _w = _storage[(index * 4) + 3];
+    return NativeFloat32x4._truncated(_x, _y, _z, _w);
+  }
+
+  void operator []=(int index, Float32x4 value) {
+    _checkValidIndex(index, this, this.length);
+    _storage[(index * 4) + 0] = value.x;
+    _storage[(index * 4) + 1] = value.y;
+    _storage[(index * 4) + 2] = value.z;
+    _storage[(index * 4) + 3] = value.w;
+  }
+
+  Float32x4List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    return NativeFloat32x4List._externalStorage(
+        _storage.sublist(start * 4, end * 4));
+  }
+}
+
+/**
+ * A fixed-length list of Int32x4 numbers that is viewable as a
+ * [TypedData]. For long lists, this implementation will be considerably more
+ * space- and time-efficient than the default [List] implementation.
+ */
+class NativeInt32x4List extends Object
+    with ListMixin<Int32x4>, FixedLengthListMixin<Int32x4>
+    implements Int32x4List {
+  final Int32List _storage;
+
+  /**
+   * Creates a [Int32x4List] of the specified length (in elements),
+   * all of whose elements are initially zero.
+   */
+  NativeInt32x4List(int length) : _storage = NativeInt32List(length * 4);
+
+  NativeInt32x4List._externalStorage(Int32List storage) : _storage = storage;
+
+  NativeInt32x4List._slowFromList(List<Int32x4> list)
+      : _storage = NativeInt32List(list.length * 4) {
+    for (int i = 0; i < list.length; i++) {
+      var e = list[i];
+      _storage[(i * 4) + 0] = e.x;
+      _storage[(i * 4) + 1] = e.y;
+      _storage[(i * 4) + 2] = e.z;
+      _storage[(i * 4) + 3] = e.w;
+    }
+  }
+
+  Type get runtimeType => Int32x4List;
+
+  /**
+   * Creates a [Int32x4List] with the same size as the [elements] list
+   * and copies over the elements.
+   */
+  factory NativeInt32x4List.fromList(List<Int32x4> list) {
+    if (list is NativeInt32x4List) {
+      return NativeInt32x4List._externalStorage(
+          NativeInt32List.fromList(list._storage));
+    } else {
+      return NativeInt32x4List._slowFromList(list);
+    }
+  }
+
+  ByteBuffer get buffer => _storage.buffer;
+
+  int get lengthInBytes => _storage.lengthInBytes;
+
+  int get offsetInBytes => _storage.offsetInBytes;
+
+  int get elementSizeInBytes => Int32x4List.bytesPerElement;
+
+  int get length => _storage.length ~/ 4;
+
+  Int32x4 operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    int _x = _storage[(index * 4) + 0];
+    int _y = _storage[(index * 4) + 1];
+    int _z = _storage[(index * 4) + 2];
+    int _w = _storage[(index * 4) + 3];
+    return NativeInt32x4._truncated(_x, _y, _z, _w);
+  }
+
+  void operator []=(int index, Int32x4 value) {
+    _checkValidIndex(index, this, this.length);
+    _storage[(index * 4) + 0] = value.x;
+    _storage[(index * 4) + 1] = value.y;
+    _storage[(index * 4) + 2] = value.z;
+    _storage[(index * 4) + 3] = value.w;
+  }
+
+  Int32x4List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    return NativeInt32x4List._externalStorage(
+        _storage.sublist(start * 4, end * 4));
+  }
+}
+
+/**
+ * A fixed-length list of Float64x2 numbers that is viewable as a
+ * [TypedData]. For long lists, this implementation will be considerably more
+ * space- and time-efficient than the default [List] implementation.
+ */
+class NativeFloat64x2List extends Object
+    with ListMixin<Float64x2>, FixedLengthListMixin<Float64x2>
+    implements Float64x2List {
+  final NativeFloat64List _storage;
+
+  /**
+   * Creates a [Float64x2List] of the specified length (in elements),
+   * all of whose elements are initially zero.
+   */
+  NativeFloat64x2List(int length) : _storage = NativeFloat64List(length * 2);
+
+  NativeFloat64x2List._externalStorage(this._storage);
+
+  NativeFloat64x2List._slowFromList(List<Float64x2> list)
+      : _storage = NativeFloat64List(list.length * 2) {
+    for (int i = 0; i < list.length; i++) {
+      var e = list[i];
+      _storage[(i * 2) + 0] = e.x;
+      _storage[(i * 2) + 1] = e.y;
+    }
+  }
+
+  /**
+   * Creates a [Float64x2List] with the same size as the [elements] list
+   * and copies over the elements.
+   */
+  factory NativeFloat64x2List.fromList(List<Float64x2> list) {
+    if (list is NativeFloat64x2List) {
+      return NativeFloat64x2List._externalStorage(
+          NativeFloat64List.fromList(list._storage));
+    } else {
+      return NativeFloat64x2List._slowFromList(list);
+    }
+  }
+
+  Type get runtimeType => Float64x2List;
+
+  ByteBuffer get buffer => _storage.buffer;
+
+  int get lengthInBytes => _storage.lengthInBytes;
+
+  int get offsetInBytes => _storage.offsetInBytes;
+
+  int get elementSizeInBytes => Float64x2List.bytesPerElement;
+
+  int get length => _storage.length ~/ 2;
+
+  Float64x2 operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    double _x = _storage[(index * 2) + 0];
+    double _y = _storage[(index * 2) + 1];
+    return Float64x2(_x, _y);
+  }
+
+  void operator []=(int index, Float64x2 value) {
+    _checkValidIndex(index, this, this.length);
+    _storage[(index * 2) + 0] = value.x;
+    _storage[(index * 2) + 1] = value.y;
+  }
+
+  Float64x2List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    return NativeFloat64x2List._externalStorage(
+        _storage.sublist(start * 2, end * 2));
+  }
+}
+
+@Native("ArrayBufferView")
+class NativeTypedData implements TypedData {
+  /**
+   * Returns the byte buffer associated with this object.
+   */
+  @Creates('NativeByteBuffer')
+  // May be Null for IE's CanvasPixelArray.
+  @Returns('NativeByteBuffer|Null')
+  external ByteBuffer get buffer;
+
+  /**
+   * Returns the length of this view, in bytes.
+   */
+  @JSName('byteLength')
+  external int get lengthInBytes;
+
+  /**
+   * Returns the offset in bytes into the underlying byte buffer of this view.
+   */
+  @JSName('byteOffset')
+  external int get offsetInBytes;
+
+  /**
+   * Returns the number of bytes in the representation of each element in this
+   * list.
+   */
+  @JSName('BYTES_PER_ELEMENT')
+  external int get elementSizeInBytes;
+
+  void _invalidPosition(int position, int length, String name) {
+    if (position is! int) {
+      throw ArgumentError.value(position, name, 'Invalid list position');
+    } else {
+      throw RangeError.range(position, 0, length, name);
+    }
+  }
+
+  void _checkPosition(int position, int length, String name) {
+    if (JS<bool>('!', '(# >>> 0) !== #', position, position) ||
+        JS<int>('!', '#', position) > length) {
+      // 'int' guaranteed by above test.
+      _invalidPosition(position, length, name);
+    }
+  }
+}
+
+// Validates the unnamed constructor length argument.  Checking is necessary
+// because passing unvalidated values to the native constructors can cause
+// conversions or create views.
+int _checkLength(length) {
+  if (length is! int) throw ArgumentError('Invalid length $length');
+  return length;
+}
+
+// Validates `.view` constructor arguments.  Checking is necessary because
+// passing unvalidated values to the native constructors can cause conversions
+// (e.g. String arguments) or create typed data objects that are not actually
+// views of the input.
+void _checkViewArguments(buffer, offsetInBytes, length) {
+  if (buffer is! NativeByteBuffer) {
+    throw ArgumentError('Invalid view buffer');
+  }
+  if (offsetInBytes is! int) {
+    throw ArgumentError('Invalid view offsetInBytes $offsetInBytes');
+  }
+  if (length != null && length is! int) {
+    throw ArgumentError('Invalid view length $length');
+  }
+}
+
+// Ensures that [list] is a JavaScript Array or a typed array.  If necessary,
+// returns a copy of the list.
+List _ensureNativeList(List list) {
+  if (list is JSIndexable) return list;
+  List result = List(list.length);
+  for (int i = 0; i < list.length; i++) {
+    result[i] = list[i];
+  }
+  return result;
+}
+
+@Native("DataView")
+class NativeByteData extends NativeTypedData implements ByteData {
+  /**
+   * Creates a [ByteData] of the specified length (in elements), all of
+   * whose elements are initially zero.
+   */
+  factory NativeByteData(int length) => _create1(_checkLength(length));
+
+  /**
+   * Creates an [ByteData] _view_ of the specified region in the specified
+   * byte buffer. Changes in the [ByteData] will be visible in the byte
+   * buffer and vice versa. If the [offsetInBytes] index of the region is not
+   * specified, it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to null, which indicates
+   * that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   */
+  factory NativeByteData.view(
+      ByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => ByteData;
+
+  int get elementSizeInBytes => 1;
+
+  /**
+   * Returns the floating point number represented by the four bytes at
+   * the specified [byteOffset] in this object, in IEEE 754
+   * single-precision binary floating-point format (binary32).
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
+   */
+  double getFloat32(int byteOffset, [Endian endian = Endian.big]) =>
+      _getFloat32(byteOffset, Endian.little == endian);
+
+  @JSName('getFloat32')
+  @Returns('double')
+  double _getFloat32(int byteOffset, [bool littleEndian]) native;
+
+  /**
+   * Returns the floating point number represented by the eight bytes at
+   * the specified [byteOffset] in this object, in IEEE 754
+   * double-precision binary floating-point format (binary64).
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 8` is greater than the length of this object.
+   */
+  double getFloat64(int byteOffset, [Endian endian = Endian.big]) =>
+      _getFloat64(byteOffset, Endian.little == endian);
+
+  @JSName('getFloat64')
+  @Returns('double')
+  double _getFloat64(int byteOffset, [bool littleEndian]) native;
+
+  /**
+   * Returns the (possibly negative) integer represented by the two bytes at
+   * the specified [byteOffset] in this object, in two's complement binary
+   * form.
+   * The return value will be between 2<sup>15</sup> and 2<sup>15</sup> - 1,
+   * inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 2` is greater than the length of this object.
+   */
+  int getInt16(int byteOffset, [Endian endian = Endian.big]) =>
+      _getInt16(byteOffset, Endian.little == endian);
+
+  @JSName('getInt16')
+  @Returns('int')
+  int _getInt16(int byteOffset, [bool littleEndian]) native;
+
+  /**
+   * Returns the (possibly negative) integer represented by the four bytes at
+   * the specified [byteOffset] in this object, in two's complement binary
+   * form.
+   * The return value will be between 2<sup>31</sup> and 2<sup>31</sup> - 1,
+   * inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
+   */
+  int getInt32(int byteOffset, [Endian endian = Endian.big]) =>
+      _getInt32(byteOffset, Endian.little == endian);
+
+  @JSName('getInt32')
+  @Returns('int')
+  int _getInt32(int byteOffset, [bool littleEndian]) native;
+
+  /**
+   * Returns the (possibly negative) integer represented by the eight bytes at
+   * the specified [byteOffset] in this object, in two's complement binary
+   * form.
+   * The return value will be between 2<sup>63</sup> and 2<sup>63</sup> - 1,
+   * inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 8` is greater than the length of this object.
+   */
+  int getInt64(int byteOffset, [Endian endian = Endian.big]) {
+    throw UnsupportedError('Int64 accessor not supported by dart2js.');
+  }
+
+  /**
+   * Returns the (possibly negative) integer represented by the byte at the
+   * specified [byteOffset] in this object, in two's complement binary
+   * representation. The return value will be between -128 and 127, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * greater than or equal to the length of this object.
+   */
+  int getInt8(int byteOffset) native;
+
+  /**
+   * Returns the positive integer represented by the two bytes starting
+   * at the specified [byteOffset] in this object, in unsigned binary
+   * form.
+   * The return value will be between 0 and  2<sup>16</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 2` is greater than the length of this object.
+   */
+  int getUint16(int byteOffset, [Endian endian = Endian.big]) =>
+      _getUint16(byteOffset, Endian.little == endian);
+
+  @JSName('getUint16')
+  @Returns('int')
+  int _getUint16(int byteOffset, [bool littleEndian]) native;
+
+  /**
+   * Returns the positive integer represented by the four bytes starting
+   * at the specified [byteOffset] in this object, in unsigned binary
+   * form.
+   * The return value will be between 0 and  2<sup>32</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
+   */
+  int getUint32(int byteOffset, [Endian endian = Endian.big]) =>
+      _getUint32(byteOffset, Endian.little == endian);
+
+  @JSName('getUint32')
+  @Returns('int')
+  int _getUint32(int byteOffset, [bool littleEndian]) native;
+
+  /**
+   * Returns the positive integer represented by the eight bytes starting
+   * at the specified [byteOffset] in this object, in unsigned binary
+   * form.
+   * The return value will be between 0 and  2<sup>64</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 8` is greater than the length of this object.
+   */
+  int getUint64(int byteOffset, [Endian endian = Endian.big]) {
+    throw UnsupportedError('Uint64 accessor not supported by dart2js.');
+  }
+
+  /**
+   * Returns the positive integer represented by the byte at the specified
+   * [byteOffset] in this object, in unsigned binary form. The
+   * return value will be between 0 and 255, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * greater than or equal to the length of this object.
+   */
+  int getUint8(int byteOffset) native;
+
+  /**
+   * Sets the four bytes starting at the specified [byteOffset] in this
+   * object to the IEEE 754 single-precision binary floating-point
+   * (binary32) representation of the specified [value].
+   *
+   * **Note that this method can lose precision.** The input [value] is
+   * a 64-bit floating point value, which will be converted to 32-bit
+   * floating point value by IEEE 754 rounding rules before it is stored.
+   * If [value] cannot be represented exactly as a binary32, it will be
+   * converted to the nearest binary32 value.  If two binary32 values are
+   * equally close, the one whose least significant bit is zero will be used.
+   * Note that finite (but large) values can be converted to infinity, and
+   * small non-zero values can be converted to zero.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
+   */
+  void setFloat32(int byteOffset, num value, [Endian endian = Endian.big]) =>
+      _setFloat32(byteOffset, value, Endian.little == endian);
+
+  @JSName('setFloat32')
+  void _setFloat32(int byteOffset, num value, [bool littleEndian]) native;
+
+  /**
+   * Sets the eight bytes starting at the specified [byteOffset] in this
+   * object to the IEEE 754 double-precision binary floating-point
+   * (binary64) representation of the specified [value].
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 8` is greater than the length of this object.
+   */
+  void setFloat64(int byteOffset, num value, [Endian endian = Endian.big]) =>
+      _setFloat64(byteOffset, value, Endian.little == endian);
+
+  @JSName('setFloat64')
+  void _setFloat64(int byteOffset, num value, [bool littleEndian]) native;
+
+  /**
+   * Sets the two bytes starting at the specified [byteOffset] in this
+   * object to the two's complement binary representation of the specified
+   * [value], which must fit in two bytes. In other words, [value] must lie
+   * between 2<sup>15</sup> and 2<sup>15</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 2` is greater than the length of this object.
+   */
+  void setInt16(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _setInt16(byteOffset, value, Endian.little == endian);
+
+  @JSName('setInt16')
+  void _setInt16(int byteOffset, int value, [bool littleEndian]) native;
+
+  /**
+   * Sets the four bytes starting at the specified [byteOffset] in this
+   * object to the two's complement binary representation of the specified
+   * [value], which must fit in four bytes. In other words, [value] must lie
+   * between 2<sup>31</sup> and 2<sup>31</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
+   */
+  void setInt32(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _setInt32(byteOffset, value, Endian.little == endian);
+
+  @JSName('setInt32')
+  void _setInt32(int byteOffset, int value, [bool littleEndian]) native;
+
+  /**
+   * Sets the eight bytes starting at the specified [byteOffset] in this
+   * object to the two's complement binary representation of the specified
+   * [value], which must fit in eight bytes. In other words, [value] must lie
+   * between 2<sup>63</sup> and 2<sup>63</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 8` is greater than the length of this object.
+   */
+  void setInt64(int byteOffset, int value, [Endian endian = Endian.big]) {
+    throw UnsupportedError('Int64 accessor not supported by dart2js.');
+  }
+
+  /**
+   * Sets the byte at the specified [byteOffset] in this object to the
+   * two's complement binary representation of the specified [value], which
+   * must fit in a single byte. In other words, [value] must be between
+   * -128 and 127, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * greater than or equal to the length of this object.
+   */
+  void setInt8(int byteOffset, int value) native;
+
+  /**
+   * Sets the two bytes starting at the specified [byteOffset] in this object
+   * to the unsigned binary representation of the specified [value],
+   * which must fit in two bytes. in other words, [value] must be between
+   * 0 and 2<sup>16</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 2` is greater than the length of this object.
+   */
+  void setUint16(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _setUint16(byteOffset, value, Endian.little == endian);
+
+  @JSName('setUint16')
+  void _setUint16(int byteOffset, int value, [bool littleEndian]) native;
+
+  /**
+   * Sets the four bytes starting at the specified [byteOffset] in this object
+   * to the unsigned binary representation of the specified [value],
+   * which must fit in four bytes. in other words, [value] must be between
+   * 0 and 2<sup>32</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
+   */
+  void setUint32(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _setUint32(byteOffset, value, Endian.little == endian);
+
+  @JSName('setUint32')
+  void _setUint32(int byteOffset, int value, [bool littleEndian]) native;
+
+  /**
+   * Sets the eight bytes starting at the specified [byteOffset] in this object
+   * to the unsigned binary representation of the specified [value],
+   * which must fit in eight bytes. in other words, [value] must be between
+   * 0 and 2<sup>64</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 8` is greater than the length of this object.
+   */
+  void setUint64(int byteOffset, int value, [Endian endian = Endian.big]) {
+    throw UnsupportedError('Uint64 accessor not supported by dart2js.');
+  }
+
+  /**
+   * Sets the byte at the specified [byteOffset] in this object to the
+   * unsigned binary representation of the specified [value], which must fit
+   * in a single byte. in other words, [value] must be between 0 and 255,
+   * inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative,
+   * or greater than or equal to the length of this object.
+   */
+  void setUint8(int byteOffset, int value) native;
+
+  static NativeByteData _create1(arg) =>
+      JS('NativeByteData', 'new DataView(new ArrayBuffer(#))', arg);
+
+  static NativeByteData _create2(arg1, arg2) =>
+      JS('NativeByteData', 'new DataView(#, #)', arg1, arg2);
+
+  static NativeByteData _create3(arg1, arg2, arg3) =>
+      JS('NativeByteData', 'new DataView(#, #, #)', arg1, arg2, arg3);
+}
+
+abstract class NativeTypedArray extends NativeTypedData
+    implements JavaScriptIndexingBehavior {
+  int get length;
+
+  void _setRangeFast(
+      int start, int end, NativeTypedArray source, int skipCount) {
+    int targetLength = this.length;
+    _checkPosition(start, targetLength, "start");
+    _checkPosition(end, targetLength, "end");
+    if (start > end) throw RangeError.range(start, 0, end);
+    int count = end - start;
+
+    if (skipCount < 0) throw ArgumentError(skipCount);
+
+    int sourceLength = source.length;
+    if (sourceLength - skipCount < count) {
+      throw StateError('Not enough elements');
+    }
+
+    if (skipCount != 0 || sourceLength != count) {
+      // Create a view of the exact subrange that is copied from the source.
+      source = JS('', '#.subarray(#, #)', source, skipCount, skipCount + count);
+    }
+    JS('void', '#.set(#, #)', this, source, start);
+  }
+}
+
+abstract class NativeTypedArrayOfDouble extends NativeTypedArray
+    with ListMixin<double>, FixedLengthListMixin<double> {
+  int get length => JS<int>('!', '#.length', this);
+
+  double operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    return JS<double>('!', '#[#]', this, index);
+  }
+
+  void operator []=(int index, num value) {
+    _checkValidIndex(index, this, this.length);
+    JS('void', '#[#] = #', this, index, value);
+  }
+
+  void setRange(int start, int end, Iterable<double> iterable,
+      [int skipCount = 0]) {
+    if (iterable is NativeTypedArrayOfDouble) {
+      _setRangeFast(start, end, iterable, skipCount);
+      return;
+    }
+    super.setRange(start, end, iterable, skipCount);
+  }
+}
+
+abstract class NativeTypedArrayOfInt extends NativeTypedArray
+    with ListMixin<int>, FixedLengthListMixin<int>
+    implements List<int> {
+  int get length => JS<int>('!', '#.length', this);
+
+  // operator[]() is not here since different versions have different return
+  // types
+
+  void operator []=(int index, int value) {
+    _checkValidIndex(index, this, this.length);
+    JS('void', '#[#] = #', this, index, value);
+  }
+
+  void setRange(int start, int end, Iterable<int> iterable,
+      [int skipCount = 0]) {
+    if (iterable is NativeTypedArrayOfInt) {
+      _setRangeFast(start, end, iterable, skipCount);
+      return;
+    }
+    super.setRange(start, end, iterable, skipCount);
+  }
+}
+
+@Native("Float32Array")
+class NativeFloat32List extends NativeTypedArrayOfDouble
+    implements Float32List {
+  factory NativeFloat32List(int length) => _create1(_checkLength(length));
+
+  factory NativeFloat32List.fromList(List<double> elements) =>
+      _create1(_ensureNativeList(elements));
+
+  factory NativeFloat32List.view(
+      ByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => Float32List;
+
+  Float32List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    var source =
+        JS<NativeFloat32List>('!', '#.subarray(#, #)', this, start, end);
+    return _create1(source);
+  }
+
+  static NativeFloat32List _create1(arg) =>
+      JS<NativeFloat32List>('!', 'new Float32Array(#)', arg);
+
+  static NativeFloat32List _create2(arg1, arg2) =>
+      JS<NativeFloat32List>('!', 'new Float32Array(#, #)', arg1, arg2);
+
+  static NativeFloat32List _create3(arg1, arg2, arg3) =>
+      JS<NativeFloat32List>('!', 'new Float32Array(#, #, #)', arg1, arg2, arg3);
+}
+
+@Native("Float64Array")
+class NativeFloat64List extends NativeTypedArrayOfDouble
+    implements Float64List {
+  factory NativeFloat64List(int length) => _create1(_checkLength(length));
+
+  factory NativeFloat64List.fromList(List<double> elements) =>
+      _create1(_ensureNativeList(elements));
+
+  factory NativeFloat64List.view(
+      ByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => Float64List;
+
+  Float64List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    var source = JS('NativeFloat64List', '#.subarray(#, #)', this, start, end);
+    return _create1(source);
+  }
+
+  static NativeFloat64List _create1(arg) =>
+      JS('NativeFloat64List', 'new Float64Array(#)', arg);
+
+  static NativeFloat64List _create2(arg1, arg2) =>
+      JS('NativeFloat64List', 'new Float64Array(#, #)', arg1, arg2);
+
+  static NativeFloat64List _create3(arg1, arg2, arg3) =>
+      JS('NativeFloat64List', 'new Float64Array(#, #, #)', arg1, arg2, arg3);
+}
+
+@Native("Int16Array")
+class NativeInt16List extends NativeTypedArrayOfInt implements Int16List {
+  factory NativeInt16List(int length) => _create1(_checkLength(length));
+
+  factory NativeInt16List.fromList(List<int> elements) =>
+      _create1(_ensureNativeList(elements));
+
+  factory NativeInt16List.view(
+      NativeByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => Int16List;
+
+  int operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    return JS<int>('!', '#[#]', this, index);
+  }
+
+  Int16List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    var source = JS('NativeInt16List', '#.subarray(#, #)', this, start, end);
+    return _create1(source);
+  }
+
+  static NativeInt16List _create1(arg) =>
+      JS('NativeInt16List', 'new Int16Array(#)', arg);
+
+  static NativeInt16List _create2(arg1, arg2) =>
+      JS('NativeInt16List', 'new Int16Array(#, #)', arg1, arg2);
+
+  static NativeInt16List _create3(arg1, arg2, arg3) =>
+      JS('NativeInt16List', 'new Int16Array(#, #, #)', arg1, arg2, arg3);
+}
+
+@Native("Int32Array")
+class NativeInt32List extends NativeTypedArrayOfInt implements Int32List {
+  factory NativeInt32List(int length) => _create1(_checkLength(length));
+
+  factory NativeInt32List.fromList(List<int> elements) =>
+      _create1(_ensureNativeList(elements));
+
+  factory NativeInt32List.view(
+      ByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => Int32List;
+
+  int operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    return JS<int>('!', '#[#]', this, index);
+  }
+
+  Int32List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    var source = JS<NativeInt32List>('!', '#.subarray(#, #)', this, start, end);
+    return _create1(source);
+  }
+
+  static NativeInt32List _create1(arg) =>
+      JS<NativeInt32List>('!', 'new Int32Array(#)', arg);
+
+  static NativeInt32List _create2(arg1, arg2) =>
+      JS<NativeInt32List>('!', 'new Int32Array(#, #)', arg1, arg2);
+
+  static NativeInt32List _create3(arg1, arg2, arg3) =>
+      JS<NativeInt32List>('!', 'new Int32Array(#, #, #)', arg1, arg2, arg3);
+}
+
+@Native("Int8Array")
+class NativeInt8List extends NativeTypedArrayOfInt implements Int8List {
+  factory NativeInt8List(int length) => _create1(_checkLength(length));
+
+  factory NativeInt8List.fromList(List<int> elements) =>
+      _create1(_ensureNativeList(elements));
+
+  factory NativeInt8List.view(
+      ByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => Int8List;
+
+  int operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    return JS<int>('!', '#[#]', this, index);
+  }
+
+  Int8List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    var source = JS<NativeInt8List>('!', '#.subarray(#, #)', this, start, end);
+    return _create1(source);
+  }
+
+  static NativeInt8List _create1(arg) =>
+      JS<NativeInt8List>('!', 'new Int8Array(#)', arg);
+
+  static NativeInt8List _create2(arg1, arg2) =>
+      JS<NativeInt8List>('!', 'new Int8Array(#, #)', arg1, arg2);
+
+  static Int8List _create3(arg1, arg2, arg3) =>
+      JS<NativeInt8List>('!', 'new Int8Array(#, #, #)', arg1, arg2, arg3);
+}
+
+@Native("Uint16Array")
+class NativeUint16List extends NativeTypedArrayOfInt implements Uint16List {
+  factory NativeUint16List(int length) => _create1(_checkLength(length));
+
+  factory NativeUint16List.fromList(List<int> list) =>
+      _create1(_ensureNativeList(list));
+
+  factory NativeUint16List.view(
+      ByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => Uint16List;
+
+  int operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    return JS<int>('!', '#[#]', this, index);
+  }
+
+  Uint16List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    var source =
+        JS<NativeUint16List>('!', '#.subarray(#, #)', this, start, end);
+    return _create1(source);
+  }
+
+  static NativeUint16List _create1(arg) =>
+      JS<NativeUint16List>('!', 'new Uint16Array(#)', arg);
+
+  static NativeUint16List _create2(arg1, arg2) =>
+      JS<NativeUint16List>('!', 'new Uint16Array(#, #)', arg1, arg2);
+
+  static NativeUint16List _create3(arg1, arg2, arg3) =>
+      JS<NativeUint16List>('!', 'new Uint16Array(#, #, #)', arg1, arg2, arg3);
+}
+
+@Native("Uint32Array")
+class NativeUint32List extends NativeTypedArrayOfInt implements Uint32List {
+  factory NativeUint32List(int length) => _create1(_checkLength(length));
+
+  factory NativeUint32List.fromList(List<int> elements) =>
+      _create1(_ensureNativeList(elements));
+
+  factory NativeUint32List.view(
+      ByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => Uint32List;
+
+  int operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    return JS<int>('!', '#[#]', this, index);
+  }
+
+  Uint32List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    var source =
+        JS<NativeUint32List>('!', '#.subarray(#, #)', this, start, end);
+    return _create1(source);
+  }
+
+  static NativeUint32List _create1(arg) =>
+      JS<NativeUint32List>('!', 'new Uint32Array(#)', arg);
+
+  static NativeUint32List _create2(arg1, arg2) =>
+      JS<NativeUint32List>('!', 'new Uint32Array(#, #)', arg1, arg2);
+
+  static NativeUint32List _create3(arg1, arg2, arg3) =>
+      JS<NativeUint32List>('!', 'new Uint32Array(#, #, #)', arg1, arg2, arg3);
+}
+
+@Native("Uint8ClampedArray,CanvasPixelArray")
+class NativeUint8ClampedList extends NativeTypedArrayOfInt
+    implements Uint8ClampedList {
+  factory NativeUint8ClampedList(int length) => _create1(_checkLength(length));
+
+  factory NativeUint8ClampedList.fromList(List<int> elements) =>
+      _create1(_ensureNativeList(elements));
+
+  factory NativeUint8ClampedList.view(
+      ByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => Uint8ClampedList;
+
+  int get length => JS<int>('!', '#.length', this);
+
+  int operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    return JS<int>('!', '#[#]', this, index);
+  }
+
+  Uint8ClampedList sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    var source =
+        JS<NativeUint8ClampedList>('!', '#.subarray(#, #)', this, start, end);
+    return _create1(source);
+  }
+
+  static NativeUint8ClampedList _create1(arg) =>
+      JS<NativeUint8ClampedList>('!', 'new Uint8ClampedArray(#)', arg);
+
+  static NativeUint8ClampedList _create2(arg1, arg2) =>
+      JS<NativeUint8ClampedList>(
+          '!', 'new Uint8ClampedArray(#, #)', arg1, arg2);
+
+  static NativeUint8ClampedList _create3(arg1, arg2, arg3) => JS(
+      'NativeUint8ClampedList',
+      'new Uint8ClampedArray(#, #, #)',
+      arg1,
+      arg2,
+      arg3);
+}
+
+// On some browsers Uint8ClampedArray is a subtype of Uint8Array.  Marking
+// Uint8List as !nonleaf ensures that the native dispatch correctly handles
+// the potential for Uint8ClampedArray to 'accidentally' pick up the
+// dispatch record for Uint8List.
+@Native("Uint8Array,!nonleaf")
+class NativeUint8List extends NativeTypedArrayOfInt implements Uint8List {
+  factory NativeUint8List(int length) => _create1(_checkLength(length));
+
+  factory NativeUint8List.fromList(List<int> elements) =>
+      _create1(_ensureNativeList(elements));
+
+  factory NativeUint8List.view(
+      ByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => Uint8List;
+
+  int get length => JS<int>('!', '#.length', this);
+
+  int operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    return JS<int>('!', '#[#]', this, index);
+  }
+
+  Uint8List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    var source = JS<NativeUint8List>('!', '#.subarray(#, #)', this, start, end);
+    return _create1(source);
+  }
+
+  static NativeUint8List _create1(arg) =>
+      JS<NativeUint8List>('!', 'new Uint8Array(#)', arg);
+
+  static NativeUint8List _create2(arg1, arg2) =>
+      JS<NativeUint8List>('!', 'new Uint8Array(#, #)', arg1, arg2);
+
+  static NativeUint8List _create3(arg1, arg2, arg3) =>
+      JS<NativeUint8List>('!', 'new Uint8Array(#, #, #)', arg1, arg2, arg3);
+}
+
+/**
+ * Implementation of Dart Float32x4 immutable value type and operations.
+ * Float32x4 stores 4 32-bit floating point values in "lanes".
+ * The lanes are "x", "y", "z", and "w" respectively.
+ */
+class NativeFloat32x4 implements Float32x4 {
+  final double x;
+  final double y;
+  final double z;
+  final double w;
+
+  static final NativeFloat32List _list = NativeFloat32List(4);
+  static final Uint32List _uint32view = _list.buffer.asUint32List();
+
+  static _truncate(x) {
+    _list[0] = x;
+    return _list[0];
+  }
+
+  NativeFloat32x4(double x, double y, double z, double w)
+      : this.x = _truncate(x),
+        this.y = _truncate(y),
+        this.z = _truncate(z),
+        this.w = _truncate(w) {
+    // We would prefer to check for `double` but in dart2js we can't see the
+    // difference anyway.
+    if (x is! num) throw ArgumentError(x);
+    if (y is! num) throw ArgumentError(y);
+    if (z is! num) throw ArgumentError(z);
+    if (w is! num) throw ArgumentError(w);
+  }
+
+  NativeFloat32x4.splat(double v) : this(v, v, v, v);
+  NativeFloat32x4.zero() : this._truncated(0.0, 0.0, 0.0, 0.0);
+
+  /// Returns a bit-wise copy of [i] as a Float32x4.
+  factory NativeFloat32x4.fromInt32x4Bits(Int32x4 i) {
+    _uint32view[0] = i.x;
+    _uint32view[1] = i.y;
+    _uint32view[2] = i.z;
+    _uint32view[3] = i.w;
+    return NativeFloat32x4._truncated(_list[0], _list[1], _list[2], _list[3]);
+  }
+
+  NativeFloat32x4.fromFloat64x2(Float64x2 v)
+      : this._truncated(_truncate(v.x), _truncate(v.y), 0.0, 0.0);
+
+  /// Creates a new NativeFloat32x4.
+  ///
+  /// Does not verify if the given arguments are non-null.
+  NativeFloat32x4._doubles(double x, double y, double z, double w)
+      : this.x = _truncate(x),
+        this.y = _truncate(y),
+        this.z = _truncate(z),
+        this.w = _truncate(w);
+
+  /// Creates a new NativeFloat32x4.
+  ///
+  /// The constructor does not truncate the arguments. They must already be in
+  /// the correct range. It does not verify the type of the given arguments,
+  /// either.
+  NativeFloat32x4._truncated(this.x, this.y, this.z, this.w);
+
+  String toString() {
+    return '[$x, $y, $z, $w]';
+  }
+
+  /// Addition operator.
+  Float32x4 operator +(Float32x4 other) {
+    double _x = x + other.x;
+    double _y = y + other.y;
+    double _z = z + other.z;
+    double _w = w + other.w;
+    return NativeFloat32x4._doubles(_x, _y, _z, _w);
+  }
+
+  /// Negate operator.
+  Float32x4 operator -() {
+    return NativeFloat32x4._truncated(-x, -y, -z, -w);
+  }
+
+  /// Subtraction operator.
+  Float32x4 operator -(Float32x4 other) {
+    double _x = x - other.x;
+    double _y = y - other.y;
+    double _z = z - other.z;
+    double _w = w - other.w;
+    return NativeFloat32x4._doubles(_x, _y, _z, _w);
+  }
+
+  /// Multiplication operator.
+  Float32x4 operator *(Float32x4 other) {
+    double _x = x * other.x;
+    double _y = y * other.y;
+    double _z = z * other.z;
+    double _w = w * other.w;
+    return NativeFloat32x4._doubles(_x, _y, _z, _w);
+  }
+
+  /// Division operator.
+  Float32x4 operator /(Float32x4 other) {
+    double _x = x / other.x;
+    double _y = y / other.y;
+    double _z = z / other.z;
+    double _w = w / other.w;
+    return NativeFloat32x4._doubles(_x, _y, _z, _w);
+  }
+
+  /// Relational less than.
+  Int32x4 lessThan(Float32x4 other) {
+    bool _cx = x < other.x;
+    bool _cy = y < other.y;
+    bool _cz = z < other.z;
+    bool _cw = w < other.w;
+    return NativeInt32x4._truncated(
+        _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
+  }
+
+  /// Relational less than or equal.
+  Int32x4 lessThanOrEqual(Float32x4 other) {
+    bool _cx = x <= other.x;
+    bool _cy = y <= other.y;
+    bool _cz = z <= other.z;
+    bool _cw = w <= other.w;
+    return NativeInt32x4._truncated(
+        _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
+  }
+
+  /// Relational greater than.
+  Int32x4 greaterThan(Float32x4 other) {
+    bool _cx = x > other.x;
+    bool _cy = y > other.y;
+    bool _cz = z > other.z;
+    bool _cw = w > other.w;
+    return NativeInt32x4._truncated(
+        _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
+  }
+
+  /// Relational greater than or equal.
+  Int32x4 greaterThanOrEqual(Float32x4 other) {
+    bool _cx = x >= other.x;
+    bool _cy = y >= other.y;
+    bool _cz = z >= other.z;
+    bool _cw = w >= other.w;
+    return NativeInt32x4._truncated(
+        _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
+  }
+
+  /// Relational equal.
+  Int32x4 equal(Float32x4 other) {
+    bool _cx = x == other.x;
+    bool _cy = y == other.y;
+    bool _cz = z == other.z;
+    bool _cw = w == other.w;
+    return NativeInt32x4._truncated(
+        _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
+  }
+
+  /// Relational not-equal.
+  Int32x4 notEqual(Float32x4 other) {
+    bool _cx = x != other.x;
+    bool _cy = y != other.y;
+    bool _cz = z != other.z;
+    bool _cw = w != other.w;
+    return NativeInt32x4._truncated(
+        _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
+  }
+
+  /// Returns a copy of [this] each lane being scaled by [s].
+  Float32x4 scale(double s) {
+    double _x = s * x;
+    double _y = s * y;
+    double _z = s * z;
+    double _w = s * w;
+    return NativeFloat32x4._doubles(_x, _y, _z, _w);
+  }
+
+  /// Returns the absolute value of this [Float32x4].
+  Float32x4 abs() {
+    double _x = x.abs();
+    double _y = y.abs();
+    double _z = z.abs();
+    double _w = w.abs();
+    return NativeFloat32x4._truncated(_x, _y, _z, _w);
+  }
+
+  /// Clamps [this] to be in the range [lowerLimit]-[upperLimit].
+  Float32x4 clamp(Float32x4 lowerLimit, Float32x4 upperLimit) {
+    double _lx = lowerLimit.x;
+    double _ly = lowerLimit.y;
+    double _lz = lowerLimit.z;
+    double _lw = lowerLimit.w;
+    double _ux = upperLimit.x;
+    double _uy = upperLimit.y;
+    double _uz = upperLimit.z;
+    double _uw = upperLimit.w;
+    double _x = x;
+    double _y = y;
+    double _z = z;
+    double _w = w;
+    // MAX(MIN(self, upper), lower).
+    _x = _x > _ux ? _ux : _x;
+    _y = _y > _uy ? _uy : _y;
+    _z = _z > _uz ? _uz : _z;
+    _w = _w > _uw ? _uw : _w;
+    _x = _x < _lx ? _lx : _x;
+    _y = _y < _ly ? _ly : _y;
+    _z = _z < _lz ? _lz : _z;
+    _w = _w < _lw ? _lw : _w;
+    return NativeFloat32x4._truncated(_x, _y, _z, _w);
+  }
+
+  /// Extract the sign bit from each lane return them in the first 4 bits.
+  int get signMask {
+    var view = _uint32view;
+    var mx, my, mz, mw;
+    _list[0] = x;
+    _list[1] = y;
+    _list[2] = z;
+    _list[3] = w;
+    // This is correct because dart2js uses the unsigned right shift.
+    mx = (view[0] & 0x80000000) >> 31;
+    my = (view[1] & 0x80000000) >> 30;
+    mz = (view[2] & 0x80000000) >> 29;
+    mw = (view[3] & 0x80000000) >> 28;
+    return mx | my | mz | mw;
+  }
+
+  /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
+  Float32x4 shuffle(int mask) {
+    if ((mask < 0) || (mask > 255)) {
+      throw RangeError.range(mask, 0, 255, "mask");
+    }
+    _list[0] = x;
+    _list[1] = y;
+    _list[2] = z;
+    _list[3] = w;
+
+    double _x = _list[mask & 0x3];
+    double _y = _list[(mask >> 2) & 0x3];
+    double _z = _list[(mask >> 4) & 0x3];
+    double _w = _list[(mask >> 6) & 0x3];
+    return NativeFloat32x4._truncated(_x, _y, _z, _w);
+  }
+
+  /// Shuffle the lane values in [this] and [other]. The returned
+  /// Float32x4 will have XY lanes from [this] and ZW lanes from [other].
+  /// Uses the same [mask] as [shuffle].
+  Float32x4 shuffleMix(Float32x4 other, int mask) {
+    if ((mask < 0) || (mask > 255)) {
+      throw RangeError.range(mask, 0, 255, "mask");
+    }
+    _list[0] = x;
+    _list[1] = y;
+    _list[2] = z;
+    _list[3] = w;
+    double _x = _list[mask & 0x3];
+    double _y = _list[(mask >> 2) & 0x3];
+
+    _list[0] = other.x;
+    _list[1] = other.y;
+    _list[2] = other.z;
+    _list[3] = other.w;
+    double _z = _list[(mask >> 4) & 0x3];
+    double _w = _list[(mask >> 6) & 0x3];
+    return NativeFloat32x4._truncated(_x, _y, _z, _w);
+  }
+
+  /// Copy [this] and replace the [x] lane.
+  Float32x4 withX(double newX) {
+    return NativeFloat32x4._truncated(_truncate(newX), y, z, w);
+  }
+
+  /// Copy [this] and replace the [y] lane.
+  Float32x4 withY(double newY) {
+    return NativeFloat32x4._truncated(x, _truncate(newY), z, w);
+  }
+
+  /// Copy [this] and replace the [z] lane.
+  Float32x4 withZ(double newZ) {
+    return NativeFloat32x4._truncated(x, y, _truncate(newZ), w);
+  }
+
+  /// Copy [this] and replace the [w] lane.
+  Float32x4 withW(double newW) {
+    return NativeFloat32x4._truncated(x, y, z, _truncate(newW));
+  }
+
+  /// Returns the lane-wise minimum value in [this] or [other].
+  Float32x4 min(Float32x4 other) {
+    double _x = x < other.x ? x : other.x;
+    double _y = y < other.y ? y : other.y;
+    double _z = z < other.z ? z : other.z;
+    double _w = w < other.w ? w : other.w;
+    return NativeFloat32x4._truncated(_x, _y, _z, _w);
+  }
+
+  /// Returns the lane-wise maximum value in [this] or [other].
+  Float32x4 max(Float32x4 other) {
+    double _x = x > other.x ? x : other.x;
+    double _y = y > other.y ? y : other.y;
+    double _z = z > other.z ? z : other.z;
+    double _w = w > other.w ? w : other.w;
+    return NativeFloat32x4._truncated(_x, _y, _z, _w);
+  }
+
+  /// Returns the square root of [this].
+  Float32x4 sqrt() {
+    double _x = Math.sqrt(x);
+    double _y = Math.sqrt(y);
+    double _z = Math.sqrt(z);
+    double _w = Math.sqrt(w);
+    return NativeFloat32x4._doubles(_x, _y, _z, _w);
+  }
+
+  /// Returns the reciprocal of [this].
+  Float32x4 reciprocal() {
+    double _x = 1.0 / x;
+    double _y = 1.0 / y;
+    double _z = 1.0 / z;
+    double _w = 1.0 / w;
+    return NativeFloat32x4._doubles(_x, _y, _z, _w);
+  }
+
+  /// Returns the square root of the reciprocal of [this].
+  Float32x4 reciprocalSqrt() {
+    double _x = Math.sqrt(1.0 / x);
+    double _y = Math.sqrt(1.0 / y);
+    double _z = Math.sqrt(1.0 / z);
+    double _w = Math.sqrt(1.0 / w);
+    return NativeFloat32x4._doubles(_x, _y, _z, _w);
+  }
+}
+
+/**
+ * Interface of Dart Int32x4 and operations.
+ * Int32x4 stores 4 32-bit bit-masks in "lanes".
+ * The lanes are "x", "y", "z", and "w" respectively.
+ */
+class NativeInt32x4 implements Int32x4 {
+  final int x;
+  final int y;
+  final int z;
+  final int w;
+
+  static final _list = NativeInt32List(4);
+
+  static _truncate(x) {
+    _list[0] = x;
+    return _list[0];
+  }
+
+  NativeInt32x4(int x, int y, int z, int w)
+      : this.x = _truncate(x),
+        this.y = _truncate(y),
+        this.z = _truncate(z),
+        this.w = _truncate(w) {
+    if (x != this.x && x is! int) throw ArgumentError(x);
+    if (y != this.y && y is! int) throw ArgumentError(y);
+    if (z != this.z && z is! int) throw ArgumentError(z);
+    if (w != this.w && w is! int) throw ArgumentError(w);
+  }
+
+  NativeInt32x4.bool(bool x, bool y, bool z, bool w)
+      : this.x = x ? -1 : 0,
+        this.y = y ? -1 : 0,
+        this.z = z ? -1 : 0,
+        this.w = w ? -1 : 0;
+
+  /// Returns a bit-wise copy of [f] as a Int32x4.
+  factory NativeInt32x4.fromFloat32x4Bits(Float32x4 f) {
+    NativeFloat32List floatList = NativeFloat32x4._list;
+    floatList[0] = f.x;
+    floatList[1] = f.y;
+    floatList[2] = f.z;
+    floatList[3] = f.w;
+    NativeInt32List view = floatList.buffer.asInt32List();
+    return NativeInt32x4._truncated(view[0], view[1], view[2], view[3]);
+  }
+
+  NativeInt32x4._truncated(this.x, this.y, this.z, this.w);
+
+  String toString() => '[$x, $y, $z, $w]';
+
+  /// The bit-wise or operator.
+  Int32x4 operator |(Int32x4 other) {
+    // Dart2js uses unsigned results for bit-operations.
+    // We use "JS" to fall back to the signed versions.
+    return NativeInt32x4._truncated(
+        JS("int", "# | #", x, other.x),
+        JS("int", "# | #", y, other.y),
+        JS("int", "# | #", z, other.z),
+        JS("int", "# | #", w, other.w));
+  }
+
+  /// The bit-wise and operator.
+  Int32x4 operator &(Int32x4 other) {
+    // Dart2js uses unsigned results for bit-operations.
+    // We use "JS" to fall back to the signed versions.
+    return NativeInt32x4._truncated(
+        JS("int", "# & #", x, other.x),
+        JS("int", "# & #", y, other.y),
+        JS("int", "# & #", z, other.z),
+        JS("int", "# & #", w, other.w));
+  }
+
+  /// The bit-wise xor operator.
+  Int32x4 operator ^(Int32x4 other) {
+    // Dart2js uses unsigned results for bit-operations.
+    // We use "JS" to fall back to the signed versions.
+    return NativeInt32x4._truncated(
+        JS("int", "# ^ #", x, other.x),
+        JS("int", "# ^ #", y, other.y),
+        JS("int", "# ^ #", z, other.z),
+        JS("int", "# ^ #", w, other.w));
+  }
+
+  Int32x4 operator +(Int32x4 other) {
+    // Avoid going through the typed array by "| 0" the result.
+    return NativeInt32x4._truncated(
+        JS("int", "(# + #) | 0", x, other.x),
+        JS("int", "(# + #) | 0", y, other.y),
+        JS("int", "(# + #) | 0", z, other.z),
+        JS("int", "(# + #) | 0", w, other.w));
+  }
+
+  Int32x4 operator -(Int32x4 other) {
+    // Avoid going through the typed array by "| 0" the result.
+    return NativeInt32x4._truncated(
+        JS("int", "(# - #) | 0", x, other.x),
+        JS("int", "(# - #) | 0", y, other.y),
+        JS("int", "(# - #) | 0", z, other.z),
+        JS("int", "(# - #) | 0", w, other.w));
+  }
+
+  Int32x4 operator -() {
+    // Avoid going through the typed array by "| 0" the result.
+    return NativeInt32x4._truncated(
+        JS("int", "(-#) | 0", x),
+        JS("int", "(-#) | 0", y),
+        JS("int", "(-#) | 0", z),
+        JS("int", "(-#) | 0", w));
+  }
+
+  /// Extract the top bit from each lane return them in the first 4 bits.
+  int get signMask {
+    int mx = (x & 0x80000000) >> 31;
+    int my = (y & 0x80000000) >> 31;
+    int mz = (z & 0x80000000) >> 31;
+    int mw = (w & 0x80000000) >> 31;
+    return mx | my << 1 | mz << 2 | mw << 3;
+  }
+
+  /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
+  Int32x4 shuffle(int mask) {
+    if ((mask < 0) || (mask > 255)) {
+      throw RangeError.range(mask, 0, 255, "mask");
+    }
+    _list[0] = x;
+    _list[1] = y;
+    _list[2] = z;
+    _list[3] = w;
+    int _x = _list[mask & 0x3];
+    int _y = _list[(mask >> 2) & 0x3];
+    int _z = _list[(mask >> 4) & 0x3];
+    int _w = _list[(mask >> 6) & 0x3];
+    return NativeInt32x4._truncated(_x, _y, _z, _w);
+  }
+
+  /// Shuffle the lane values in [this] and [other]. The returned
+  /// Int32x4 will have XY lanes from [this] and ZW lanes from [other].
+  /// Uses the same [mask] as [shuffle].
+  Int32x4 shuffleMix(Int32x4 other, int mask) {
+    if ((mask < 0) || (mask > 255)) {
+      throw RangeError.range(mask, 0, 255, "mask");
+    }
+    _list[0] = x;
+    _list[1] = y;
+    _list[2] = z;
+    _list[3] = w;
+    int _x = _list[mask & 0x3];
+    int _y = _list[(mask >> 2) & 0x3];
+
+    _list[0] = other.x;
+    _list[1] = other.y;
+    _list[2] = other.z;
+    _list[3] = other.w;
+    int _z = _list[(mask >> 4) & 0x3];
+    int _w = _list[(mask >> 6) & 0x3];
+    return NativeInt32x4._truncated(_x, _y, _z, _w);
+  }
+
+  /// Returns a new [Int32x4] copied from [this] with a new x value.
+  Int32x4 withX(int x) {
+    int _x = _truncate(x);
+    return NativeInt32x4._truncated(_x, y, z, w);
+  }
+
+  /// Returns a new [Int32x4] copied from [this] with a new y value.
+  Int32x4 withY(int y) {
+    int _y = _truncate(y);
+    return NativeInt32x4._truncated(x, _y, z, w);
+  }
+
+  /// Returns a new [Int32x4] copied from [this] with a new z value.
+  Int32x4 withZ(int z) {
+    int _z = _truncate(z);
+    return NativeInt32x4._truncated(x, y, _z, w);
+  }
+
+  /// Returns a new [Int32x4] copied from [this] with a new w value.
+  Int32x4 withW(int w) {
+    int _w = _truncate(w);
+    return NativeInt32x4._truncated(x, y, z, _w);
+  }
+
+  /// Extracted x value. Returns `false` for 0, `true` for any other value.
+  bool get flagX => x != 0;
+
+  /// Extracted y value. Returns `false` for 0, `true` for any other value.
+  bool get flagY => y != 0;
+
+  /// Extracted z value. Returns `false` for 0, `true` for any other value.
+  bool get flagZ => z != 0;
+
+  /// Extracted w value. Returns `false` for 0, `true` for any other value.
+  bool get flagW => w != 0;
+
+  /// Returns a new [Int32x4] copied from [this] with a new x value.
+  Int32x4 withFlagX(bool flagX) {
+    int _x = flagX ? -1 : 0;
+    return NativeInt32x4._truncated(_x, y, z, w);
+  }
+
+  /// Returns a new [Int32x4] copied from [this] with a new y value.
+  Int32x4 withFlagY(bool flagY) {
+    int _y = flagY ? -1 : 0;
+    return NativeInt32x4._truncated(x, _y, z, w);
+  }
+
+  /// Returns a new [Int32x4] copied from [this] with a new z value.
+  Int32x4 withFlagZ(bool flagZ) {
+    int _z = flagZ ? -1 : 0;
+    return NativeInt32x4._truncated(x, y, _z, w);
+  }
+
+  /// Returns a new [Int32x4] copied from [this] with a new w value.
+  Int32x4 withFlagW(bool flagW) {
+    int _w = flagW ? -1 : 0;
+    return NativeInt32x4._truncated(x, y, z, _w);
+  }
+
+  /// Merge [trueValue] and [falseValue] based on [this]' bit mask:
+  /// Select bit from [trueValue] when bit in [this] is on.
+  /// Select bit from [falseValue] when bit in [this] is off.
+  Float32x4 select(Float32x4 trueValue, Float32x4 falseValue) {
+    var floatList = NativeFloat32x4._list;
+    var intView = NativeFloat32x4._uint32view;
+
+    floatList[0] = trueValue.x;
+    floatList[1] = trueValue.y;
+    floatList[2] = trueValue.z;
+    floatList[3] = trueValue.w;
+    int stx = intView[0];
+    int sty = intView[1];
+    int stz = intView[2];
+    int stw = intView[3];
+
+    floatList[0] = falseValue.x;
+    floatList[1] = falseValue.y;
+    floatList[2] = falseValue.z;
+    floatList[3] = falseValue.w;
+    int sfx = intView[0];
+    int sfy = intView[1];
+    int sfz = intView[2];
+    int sfw = intView[3];
+    int _x = (x & stx) | (~x & sfx);
+    int _y = (y & sty) | (~y & sfy);
+    int _z = (z & stz) | (~z & sfz);
+    int _w = (w & stw) | (~w & sfw);
+    intView[0] = _x;
+    intView[1] = _y;
+    intView[2] = _z;
+    intView[3] = _w;
+    return NativeFloat32x4._truncated(
+        floatList[0], floatList[1], floatList[2], floatList[3]);
+  }
+}
+
+class NativeFloat64x2 implements Float64x2 {
+  final double x;
+  final double y;
+
+  static NativeFloat64List _list = NativeFloat64List(2);
+  static NativeUint32List _uint32View = _list.buffer.asUint32List();
+
+  NativeFloat64x2(this.x, this.y) {
+    if (x is! num) throw ArgumentError(x);
+    if (y is! num) throw ArgumentError(y);
+  }
+
+  NativeFloat64x2.splat(double v) : this(v, v);
+
+  NativeFloat64x2.zero() : this.splat(0.0);
+
+  NativeFloat64x2.fromFloat32x4(Float32x4 v) : this(v.x, v.y);
+
+  /// Arguments [x] and [y] must be doubles.
+  NativeFloat64x2._doubles(this.x, this.y);
+
+  String toString() => '[$x, $y]';
+
+  /// Addition operator.
+  Float64x2 operator +(Float64x2 other) {
+    return NativeFloat64x2._doubles(x + other.x, y + other.y);
+  }
+
+  /// Negate operator.
+  Float64x2 operator -() {
+    return NativeFloat64x2._doubles(-x, -y);
+  }
+
+  /// Subtraction operator.
+  Float64x2 operator -(Float64x2 other) {
+    return NativeFloat64x2._doubles(x - other.x, y - other.y);
+  }
+
+  /// Multiplication operator.
+  Float64x2 operator *(Float64x2 other) {
+    return NativeFloat64x2._doubles(x * other.x, y * other.y);
+  }
+
+  /// Division operator.
+  Float64x2 operator /(Float64x2 other) {
+    return NativeFloat64x2._doubles(x / other.x, y / other.y);
+  }
+
+  /// Returns a copy of [this] each lane being scaled by [s].
+  Float64x2 scale(double s) {
+    return NativeFloat64x2._doubles(x * s, y * s);
+  }
+
+  /// Returns the absolute value of this [Float64x2].
+  Float64x2 abs() {
+    return NativeFloat64x2._doubles(x.abs(), y.abs());
+  }
+
+  /// Clamps [this] to be in the range [lowerLimit]-[upperLimit].
+  Float64x2 clamp(Float64x2 lowerLimit, Float64x2 upperLimit) {
+    double _lx = lowerLimit.x;
+    double _ly = lowerLimit.y;
+    double _ux = upperLimit.x;
+    double _uy = upperLimit.y;
+    double _x = x;
+    double _y = y;
+    // MAX(MIN(self, upper), lower).
+    _x = _x > _ux ? _ux : _x;
+    _y = _y > _uy ? _uy : _y;
+    _x = _x < _lx ? _lx : _x;
+    _y = _y < _ly ? _ly : _y;
+    return NativeFloat64x2._doubles(_x, _y);
+  }
+
+  /// Extract the sign bits from each lane return them in the first 2 bits.
+  int get signMask {
+    var view = _uint32View;
+    _list[0] = x;
+    _list[1] = y;
+    var mx = (view[1] & 0x80000000) >> 31;
+    var my = (view[3] & 0x80000000) >> 31;
+    return mx | my << 1;
+  }
+
+  /// Returns a new [Float64x2] copied from [this] with a new x value.
+  Float64x2 withX(double x) {
+    if (x is! num) throw ArgumentError(x);
+    return NativeFloat64x2._doubles(x, y);
+  }
+
+  /// Returns a new [Float64x2] copied from [this] with a new y value.
+  Float64x2 withY(double y) {
+    if (y is! num) throw ArgumentError(y);
+    return NativeFloat64x2._doubles(x, y);
+  }
+
+  /// Returns the lane-wise minimum value in [this] or [other].
+  Float64x2 min(Float64x2 other) {
+    return NativeFloat64x2._doubles(
+        x < other.x ? x : other.x, y < other.y ? y : other.y);
+  }
+
+  /// Returns the lane-wise maximum value in [this] or [other].
+  Float64x2 max(Float64x2 other) {
+    return NativeFloat64x2._doubles(
+        x > other.x ? x : other.x, y > other.y ? y : other.y);
+  }
+
+  /// Returns the lane-wise square root of [this].
+  Float64x2 sqrt() {
+    return NativeFloat64x2._doubles(Math.sqrt(x), Math.sqrt(y));
+  }
+}
+
+/// Checks that the value is a Uint32. If not, it's not valid as an array
+/// index or offset. Also ensures that the value is non-negative.
+bool _isInvalidArrayIndex(int index) {
+  return (JS<bool>('!', '(# >>> 0 !== #)', index, index));
+}
+
+/// Checks that [index] is a valid index into [list] which has length [length].
+///
+/// That is, [index] is an integer in the range `0..length - 1`.
+void _checkValidIndex(int index, List list, int length) {
+  if (_isInvalidArrayIndex(index) || JS<int>('!', '#', index) >= length) {
+    throw diagnoseIndexError(list, index);
+  }
+}
+
+/// Checks that [start] and [end] form a range of a list of length [length].
+///
+/// That is: `start` and `end` are integers with `0 <= start <= end <= length`.
+/// If `end` is `null` in which case it is considered to be `length`
+///
+/// Returns the actual value of `end`, which is `length` if `end` is `null`, and
+/// the original value of `end` otherwise.
+int _checkValidRange(int start, int end, int length) {
+  if (_isInvalidArrayIndex(start) || // Ensures start is non-negative int.
+      ((end == null)
+          ? start > length
+          : (_isInvalidArrayIndex(end) || start > end || end > length))) {
+    throw diagnoseRangeError(start, end, length);
+  }
+  if (end == null) return length;
+  return end;
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/README b/sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/README
new file mode 100644
index 0000000..7eb614e
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/README
@@ -0,0 +1,17 @@
+The files in this directory polyfill some of the functionality that browsers
+provide. When running command-line JS evaluators it is frequently necessary to
+execute the preambles before executing the output of dart2js.
+
+=Usage=
+- d8:
+    d8 <sdk>/lib/_internal/compiler/js_lib/preambles/d8.js <output>.js
+
+- jsshell:
+    jsshell -f <sdk>/lib/_internal/compiler/js_lib/preambles/d8.js -f <output>.js
+
+- node.js:
+  The d8 preamble file works for most programs.
+
+  Unfortunately we are not aware of any easy way to provide multiple input files
+  to node. It seems to be necessary to concatenate the d8 preamble and the
+  dart2js output.
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/d8.js b/sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/d8.js
new file mode 100644
index 0000000..0c432f5
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/d8.js
@@ -0,0 +1,291 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Javascript preamble, that lets the output of dart2js run on V8's d8 shell.
+
+// Node wraps files and provides them with a different `this`. The global
+// `this` can be accessed through `global`.
+
+var self = this;
+if (typeof global != "undefined") self = global;  // Node.js.
+
+(function(self) {
+  // Using strict mode to avoid accidentally defining global variables.
+  "use strict"; // Should be first statement of this function.
+
+  // Location (Uri.base)
+
+  var workingDirectory;
+  // TODO(sgjesse): This does not work on Windows.
+  if (typeof os == "object" && "system" in os) {
+    // V8.
+    workingDirectory = os.system("pwd");
+    var length = workingDirectory.length;
+    if (workingDirectory[length - 1] == '\n') {
+      workingDirectory = workingDirectory.substring(0, length - 1);
+    }
+  } else if (typeof process != "undefined" &&
+             typeof process.cwd == "function") {
+    // Node.js.
+    workingDirectory = process.cwd();
+  }
+  self.location = { href: "file://" + workingDirectory + "/" };
+
+  // Event loop.
+  // Task queue as cyclic list queue.
+  var taskQueue = new Array(8);  // Length is power of 2.
+  var head = 0;
+  var tail = 0;
+  var mask = taskQueue.length - 1;
+  function addTask(elem) {
+    taskQueue[head] = elem;
+    head = (head + 1) & mask;
+    if (head == tail) _growTaskQueue();
+  }
+  function removeTask() {
+    if (head == tail) return;
+    var result = taskQueue[tail];
+    taskQueue[tail] = undefined;
+    tail = (tail + 1) & mask;
+    return result;
+  }
+  function _growTaskQueue() {
+    // head == tail.
+    var length = taskQueue.length;
+    var split = head;
+    taskQueue.length = length * 2;
+    if (split * 2 < length) {  // split < length / 2
+      for (var i = 0; i < split; i++) {
+        taskQueue[length + i] = taskQueue[i];
+        taskQueue[i] = undefined;
+      }
+      head += length;
+    } else {
+      for (var i = split; i < length; i++) {
+        taskQueue[length + i] = taskQueue[i];
+        taskQueue[i] = undefined;
+      }
+      tail += length;
+    }
+    mask = taskQueue.length - 1;
+  }
+
+  // Mapping from timer id to timer function.
+  // The timer id is written on the function as .$timerId.
+  // That field is cleared when the timer is cancelled, but it is not returned
+  // from the queue until its time comes.
+  var timerIds = {};
+  var timerIdCounter = 1;  // Counter used to assign ids.
+
+  // Zero-timer queue as simple array queue using push/shift.
+  var zeroTimerQueue = [];
+
+  function addTimer(f, ms) {
+    var id = timerIdCounter++;
+    f.$timerId = id;
+    timerIds[id] = f;
+    if (ms == 0 && !isNextTimerDue()) {
+      zeroTimerQueue.push(f);
+    } else {
+      addDelayedTimer(f, ms);
+    }
+    return id;
+  }
+
+  function nextZeroTimer() {
+    while (zeroTimerQueue.length > 0) {
+      var action = zeroTimerQueue.shift();
+      if (action.$timerId !== undefined) return action;
+    }
+  }
+
+  function nextEvent() {
+    var action = removeTask();
+    if (action) {
+      return action;
+    }
+    do {
+      action = nextZeroTimer();
+      if (action) break;
+      var nextList = nextDelayedTimerQueue();
+      if (!nextList) {
+        return;
+      }
+      var newTime = nextList.shift();
+      advanceTimeTo(newTime);
+      zeroTimerQueue = nextList;
+    } while (true)
+    var id = action.$timerId;
+    clearTimerId(action, id);
+    return action;
+  }
+
+  // Mocking time.
+  var timeOffset = 0;
+  var now = function() {
+    // Install the mock Date object only once.
+    // Following calls to "now" will just use the new (mocked) Date.now
+    // method directly.
+    installMockDate();
+    now = Date.now;
+    return Date.now();
+  };
+  var originalDate = Date;
+  var originalNow = originalDate.now;
+  function advanceTimeTo(time) {
+    var now = originalNow();
+    if (timeOffset < time - now) {
+      timeOffset = time - now;
+    }
+  }
+  function installMockDate() {
+    var NewDate = function Date(Y, M, D, h, m, s, ms) {
+      if (this instanceof Date) {
+        // Assume a construct call.
+        switch (arguments.length) {
+          case 0:  return new originalDate(originalNow() + timeOffset);
+          case 1:  return new originalDate(Y);
+          case 2:  return new originalDate(Y, M);
+          case 3:  return new originalDate(Y, M, D);
+          case 4:  return new originalDate(Y, M, D, h);
+          case 5:  return new originalDate(Y, M, D, h, m);
+          case 6:  return new originalDate(Y, M, D, h, m, s);
+          default: return new originalDate(Y, M, D, h, m, s, ms);
+        }
+      }
+      return new originalDate(originalNow() + timeOffset).toString();
+    };
+    NewDate.UTC = originalDate.UTC;
+    NewDate.parse = originalDate.parse;
+    NewDate.now = function now() { return originalNow() + timeOffset; };
+    NewDate.prototype = originalDate.prototype;
+    originalDate.prototype.constructor = NewDate;
+    Date = NewDate;
+  }
+
+  // Heap priority queue with key index.
+  // Each entry is list of [timeout, callback1 ... callbackn].
+  var timerHeap = [];
+  var timerIndex = {};
+  function addDelayedTimer(f, ms) {
+    var timeout = now() + ms;
+    var timerList = timerIndex[timeout];
+    if (timerList == null) {
+      timerList = [timeout, f];
+      timerIndex[timeout] = timerList;
+      var index = timerHeap.length;
+      timerHeap.length += 1;
+      bubbleUp(index, timeout, timerList);
+    } else {
+      timerList.push(f);
+    }
+  }
+
+  function isNextTimerDue() {
+    if (timerHeap.length == 0) return false;
+    var head = timerHeap[0];
+    return head[0] < originalNow() + timeOffset;
+  }
+
+  function nextDelayedTimerQueue() {
+    if (timerHeap.length == 0) return null;
+    var result = timerHeap[0];
+    var last = timerHeap.pop();
+    if (timerHeap.length > 0) {
+      bubbleDown(0, last[0], last);
+    }
+    return result;
+  }
+
+  function bubbleUp(index, key, value) {
+    while (index != 0) {
+      var parentIndex = (index - 1) >> 1;
+      var parent = timerHeap[parentIndex];
+      var parentKey = parent[0];
+      if (key > parentKey) break;
+      timerHeap[index] = parent;
+      index = parentIndex;
+    }
+    timerHeap[index] = value;
+  }
+
+  function bubbleDown(index, key, value) {
+    while (true) {
+      var leftChildIndex = index * 2 + 1;
+      if (leftChildIndex >= timerHeap.length) break;
+      var minChildIndex = leftChildIndex;
+      var minChild = timerHeap[leftChildIndex];
+      var minChildKey = minChild[0];
+      var rightChildIndex = leftChildIndex + 1;
+      if (rightChildIndex < timerHeap.length) {
+        var rightChild = timerHeap[rightChildIndex];
+        var rightKey = rightChild[0];
+        if (rightKey < minChildKey) {
+          minChildIndex = rightChildIndex;
+          minChild = rightChild;
+          minChildKey = rightKey;
+        }
+      }
+      if (minChildKey > key) break;
+      timerHeap[index] = minChild;
+      index = minChildIndex;
+    }
+    timerHeap[index] = value;
+  }
+
+  function addInterval(f, ms) {
+    var id = timerIdCounter++;
+    function repeat() {
+      // Reactivate with the same id.
+      repeat.$timerId = id;
+      timerIds[id] = repeat;
+      addDelayedTimer(repeat, ms);
+      f();
+    }
+    repeat.$timerId = id;
+    timerIds[id] = repeat;
+    addDelayedTimer(repeat, ms);
+    return id;
+  }
+
+  function cancelTimer(id) {
+    var f = timerIds[id];
+    if (f == null) return;
+    clearTimerId(f, id);
+  }
+
+  function clearTimerId(f, id) {
+    f.$timerId = undefined;
+    delete timerIds[id];
+  }
+
+  function eventLoop(action) {
+    while (action) {
+      try {
+        action();
+      } catch (e) {
+        if (typeof onerror == "function") {
+          onerror(e, null, -1);
+        } else {
+          throw e;
+        }
+      }
+      action = nextEvent();
+    }
+  }
+
+  // Global properties. "self" refers to the global object, so adding a
+  // property to "self" defines a global variable.
+  self.dartMainRunner = function(main, args) {
+    // Initialize.
+    var action = function() { main(args); }
+    eventLoop(action);
+  };
+  self.setTimeout = addTimer;
+  self.clearTimeout = cancelTimer;
+  self.setInterval = addInterval;
+  self.clearInterval = cancelTimer;
+  self.scheduleImmediate = addTask;
+  self.self = self;
+})(self);
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/jsshell.js b/sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/jsshell.js
new file mode 100644
index 0000000..8f13bcc
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/jsshell.js
@@ -0,0 +1,19 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Javascript preamble, that lets the output of dart2js run on JSShell.
+
+(function(self) {
+  // Using strict mode to avoid accidentally defining global variables.
+  "use strict"; // Should be first statement of this function.
+
+  // Location (Uri.base)
+
+  var workingDirectory = environment["PWD"];
+  self.location = { href: "file://" + workingDirectory + "/" };
+
+  // Global properties. "self" refers to the global object, so adding a
+  // property to "self" defines a global variable.
+  self.self = self;
+})(this)
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/profile.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/profile.dart
new file mode 100644
index 0000000..d46f7f7
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/profile.dart
@@ -0,0 +1,135 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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 file supports profiling dynamic calls.
+part of dart._debugger;
+
+class _MethodStats {
+  final String typeName;
+  final String frame;
+  double count;
+
+  _MethodStats(this.typeName, this.frame) {
+    count = 0.0;
+  }
+}
+
+class _CallMethodRecord {
+  var jsError;
+  var type;
+
+  _CallMethodRecord(this.jsError, this.type);
+}
+
+/// Size for the random sample of dynamic calls.
+int _callRecordSampleSize = 5000;
+
+/// If the number of dynamic calls exceeds [_callRecordSampleSize] this list
+/// will represent a random sample of the dynamic calls made.
+List<_CallMethodRecord> _callMethodRecords = List();
+
+/// If the number of dynamic calls exceeds [_callRecordSampleSize] this value
+/// will be greater than [_callMethodRecords.length].
+int _totalCallRecords = 0;
+
+/// Minimum number of samples to consider a profile entry relevant.
+/// This could be set a lot higher. We set this value so users are not
+/// confused into thinking that a dynamic call that occurred once but was
+/// randomly included in the sample is relevant.
+num _minCount = 2;
+
+/// Cache mapping from raw stack frames to source mapped stack frames to
+/// speedup lookup of source map frames when running the profiler.
+/// The number of source map entries looked up makes caching more important
+/// in this case than for typical source map use cases.
+Map<String, String> _frameMappingCache = Map();
+
+List<List<Object>> getDynamicStats() {
+  // Process the accumulated method stats. This may be quite slow as processing
+  // stack traces is expensive. If there are performance blockers, we should
+  // switch to a sampling approach that caps the number of _callMethodRecords
+  // and uses random sampling to decide whether to add each additional record
+  // to the sample. Main change required is that we need to still show the total
+  // raw number of dynamic calls so that the magnitude of the dynamic call
+  // performance hit is clear to users.
+
+  Map<String, _MethodStats> callMethodStats = Map();
+  if (_callMethodRecords.length > 0) {
+    // Ratio between total record count and sampled records count.
+    var recordRatio = _totalCallRecords / _callMethodRecords.length;
+    for (var record in _callMethodRecords) {
+      String stackStr = JS<String>('!', '#.stack', record.jsError);
+      var frames = stackStr.split('\n');
+      // Skip first two lines as the first couple frames are from the dart
+      // runtime.
+      var src = frames
+          .skip(2)
+          .map((f) =>
+              _frameMappingCache.putIfAbsent(f, () => stackTraceMapper('\n$f')))
+          .firstWhere((f) => !f.startsWith('dart:'), orElse: () => '');
+
+      var actualTypeName = dart.typeName(record.type);
+      callMethodStats
+          .putIfAbsent(
+              "$actualTypeName <$src>", () => _MethodStats(actualTypeName, src))
+          .count += recordRatio;
+    }
+
+    // filter out all calls that did not occur at least _minCount times in the
+    // random sample if we are dealing with a random sample instead of a
+    // complete profile.
+    if (_totalCallRecords != _callMethodRecords.length) {
+      for (var k in callMethodStats.keys.toList()) {
+        var stats = callMethodStats[k];
+        var threshold = _minCount * recordRatio;
+        if (stats.count + 0.001 < threshold) {
+          callMethodStats.remove(k);
+        }
+      }
+    }
+  }
+  _callMethodRecords.clear();
+  _totalCallRecords = 0;
+  var keys = callMethodStats.keys.toList();
+
+  keys.sort(
+      (a, b) => callMethodStats[b].count.compareTo(callMethodStats[a].count));
+  List<List<Object>> ret = [];
+  for (var key in keys) {
+    var stats = callMethodStats[key];
+    ret.add([stats.typeName, stats.frame, stats.count.round()]);
+  }
+  return ret;
+}
+
+clearDynamicStats() {
+  _callMethodRecords.clear();
+}
+
+// We need to set this property while the sdk is only partially initialized
+// so we cannot use a regular Dart field.
+bool get _trackProfile => JS<bool>('!', 'dart.__trackProfile');
+
+trackCall(obj) {
+  if (JS<bool>('!', '!#', _trackProfile)) return;
+  int index = -1;
+  _totalCallRecords++;
+  if (_callMethodRecords.length == _callRecordSampleSize) {
+    // Ensure that each sample has an equal
+    // _callRecordSampleSize / _totalCallRecords chance of inclusion
+    // by choosing to include the new record in the sample the with the
+    // appropriate probability randomly evicting one of the existing records.
+    // Unfortunately we can't use the excellent Random.nextInt method defined
+    // by Dart from within this library.
+    index = JS<int>('!', 'Math.floor(Math.random() * #)', _totalCallRecords);
+    if (index >= _callMethodRecords.length) return; // don't sample
+  }
+  var record =
+      _CallMethodRecord(JS('', 'new Error()'), dart.getReifiedType(obj));
+  if (index == -1) {
+    _callMethodRecords.add(record);
+  } else {
+    _callMethodRecords[index] = record;
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/regexp_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/regexp_helper.dart
new file mode 100644
index 0000000..fadcda0
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/regexp_helper.dart
@@ -0,0 +1,283 @@
+// Copyright (c) 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 dart._js_helper;
+
+// Helper method used by internal libraries.
+regExpGetNative(JSSyntaxRegExp regexp) => regexp._nativeRegExp;
+
+/**
+ * Returns a native version of the RegExp with the global flag set.
+ *
+ * The RegExp's `lastIndex` property is zero when it is returned.
+ *
+ * The returned regexp is shared, and its `lastIndex` property may be
+ * modified by other uses, so the returned regexp must be used immediately
+ * when it's returned, with no user-provided code run in between.
+ */
+regExpGetGlobalNative(JSSyntaxRegExp regexp) {
+  var nativeRegexp = regexp._nativeGlobalVersion;
+  JS("void", "#.lastIndex = 0", nativeRegexp);
+  return nativeRegexp;
+}
+
+/**
+ * Computes the number of captures in a regexp.
+ *
+ * This currently involves creating a new RegExp object with a different
+ * source and running it against the empty string (the last part is usually
+ * fast).
+ *
+ * The JSSyntaxRegExp could cache the result, and set the cache any time
+ * it finds a match.
+ */
+int regExpCaptureCount(JSSyntaxRegExp regexp) {
+  var nativeAnchoredRegExp = regexp._nativeAnchoredVersion;
+  JSExtendableArray match =
+      JS('JSExtendableArray', "#.exec('')", nativeAnchoredRegExp);
+  // The native-anchored regexp always have one capture more than the original,
+  // and always matches the empty string.
+  return match.length - 2;
+}
+
+class JSSyntaxRegExp implements RegExp {
+  final String pattern;
+  final _nativeRegExp;
+  var _nativeGlobalRegExp;
+  var _nativeAnchoredRegExp;
+
+  String toString() =>
+      'RegExp/$pattern/' + JS<String>('!', '#.flags', _nativeRegExp);
+
+  JSSyntaxRegExp(String source,
+      {bool multiLine = false,
+      bool caseSensitive = true,
+      bool unicode = false,
+      bool dotAll = false})
+      : this.pattern = source,
+        this._nativeRegExp = makeNative(
+            source, multiLine, caseSensitive, unicode, dotAll, false);
+
+  get _nativeGlobalVersion {
+    if (_nativeGlobalRegExp != null) return _nativeGlobalRegExp;
+    return _nativeGlobalRegExp = makeNative(
+        pattern, _isMultiLine, _isCaseSensitive, _isUnicode, _isDotAll, true);
+  }
+
+  get _nativeAnchoredVersion {
+    if (_nativeAnchoredRegExp != null) return _nativeAnchoredRegExp;
+    // An "anchored version" of a regexp is created by adding "|()" to the
+    // source. This means that the regexp always matches at the first position
+    // that it tries, and you can see if the original regexp matched, or it
+    // was the added zero-width match that matched, by looking at the last
+    // capture. If it is a String, the match participated, otherwise it didn't.
+    return _nativeAnchoredRegExp = makeNative("$pattern|()", _isMultiLine,
+        _isCaseSensitive, _isUnicode, _isDotAll, true);
+  }
+
+  bool get _isMultiLine => JS("bool", "#.multiline", _nativeRegExp);
+  bool get _isCaseSensitive => JS("bool", "!#.ignoreCase", _nativeRegExp);
+  bool get _isUnicode => JS("bool", "#.unicode", _nativeRegExp);
+  bool get _isDotAll => JS("bool", "#.dotAll", _nativeRegExp);
+
+  static makeNative(@nullCheck String source, bool multiLine,
+      bool caseSensitive, bool unicode, bool dotAll, bool global) {
+    String m = multiLine ? 'm' : '';
+    String i = caseSensitive ? '' : 'i';
+    String u = unicode ? 'u' : '';
+    String s = dotAll ? 's' : '';
+    String g = global ? 'g' : '';
+    // We're using the JavaScript's try catch instead of the Dart one
+    // to avoid dragging in Dart runtime support just because of using
+    // RegExp.
+    var regexp = JS(
+        '',
+        '(function() {'
+            'try {'
+            'return new RegExp(#, # + # + # + # + #);'
+            '} catch (e) {'
+            'return e;'
+            '}'
+            '})()',
+        source,
+        m,
+        i,
+        u,
+        s,
+        g);
+    if (JS<bool>('!', '# instanceof RegExp', regexp)) return regexp;
+    // The returned value is the JavaScript exception. Turn it into a
+    // Dart exception.
+    String errorMessage = JS<String>('!', r'String(#)', regexp);
+    throw FormatException("Illegal RegExp pattern: $source, $errorMessage");
+  }
+
+  RegExpMatch firstMatch(@nullCheck String string) {
+    List m = JS('JSExtendableArray|Null', r'#.exec(#)', _nativeRegExp, string);
+    if (m == null) return null;
+    return _MatchImplementation(this, JSArray<String>.of(m));
+  }
+
+  @notNull
+  bool hasMatch(@nullCheck String string) {
+    return JS<bool>('!', r'#.test(#)', _nativeRegExp, string);
+  }
+
+  String stringMatch(String string) {
+    var match = firstMatch(string);
+    if (match != null) return match.group(0);
+    return null;
+  }
+
+  Iterable<RegExpMatch> allMatches(@nullCheck String string,
+      [@nullCheck int start = 0]) {
+    if (start < 0 || start > string.length) {
+      throw RangeError.range(start, 0, string.length);
+    }
+    return _AllMatchesIterable(this, string, start);
+  }
+
+  RegExpMatch _execGlobal(String string, int start) {
+    Object regexp = _nativeGlobalVersion;
+    JS("void", "#.lastIndex = #", regexp, start);
+    List match = JS("JSExtendableArray|Null", "#.exec(#)", regexp, string);
+    if (match == null) return null;
+    return _MatchImplementation(this, JSArray<String>.of(match));
+  }
+
+  RegExpMatch _execAnchored(String string, int start) {
+    Object regexp = _nativeAnchoredVersion;
+    JS("void", "#.lastIndex = #", regexp, start);
+    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.
+    if (match[match.length - 1] != null) return null;
+    match.length -= 1;
+    return _MatchImplementation(this, JSArray<String>.of(match));
+  }
+
+  RegExpMatch matchAsPrefix(String string, [int start = 0]) {
+    if (start < 0 || start > string.length) {
+      throw RangeError.range(start, 0, string.length);
+    }
+    return _execAnchored(string, start);
+  }
+
+  bool get isMultiLine => _isMultiLine;
+  bool get isCaseSensitive => _isCaseSensitive;
+  bool get isUnicode => _isUnicode;
+  bool get isDotAll => _isDotAll;
+}
+
+class _MatchImplementation implements RegExpMatch {
+  final Pattern pattern;
+  // Contains a JS RegExp match object.
+  // It is an Array of String values with extra "index" and "input" properties.
+  final List<String> _match;
+
+  _MatchImplementation(this.pattern, this._match) {
+    assert(JS("var", "#.input", _match) is String);
+    assert(JS("var", "#.index", _match) is int);
+  }
+
+  String get input => JS("String", "#.input", _match);
+  int get start => JS("int", "#.index", _match);
+  int get end => start + _match[0].length;
+
+  String group(int index) => _match[index];
+  String operator [](int index) => group(index);
+  int get groupCount => _match.length - 1;
+
+  List<String> groups(List<int> groups) {
+    List<String> out = [];
+    for (int i in groups) {
+      out.add(group(i));
+    }
+    return out;
+  }
+
+  String namedGroup(String name) {
+    var groups = JS('Object', '#.groups', _match);
+    if (groups != null) {
+      var result = JS('String|Null', '#[#]', groups, name);
+      if (result != null || JS<bool>('!', '# in #', name, groups)) {
+        return result;
+      }
+    }
+    throw ArgumentError.value(name, "name", "Not a capture group name");
+  }
+
+  Iterable<String> get groupNames {
+    var groups = JS('Object', '#.groups', _match);
+    if (groups != null) {
+      var keys = JSArray<String>.of(JS('', 'Object.keys(#)', groups));
+      return SubListIterable(keys, 0, null);
+    }
+    return Iterable.empty();
+  }
+}
+
+class _AllMatchesIterable extends IterableBase<RegExpMatch> {
+  final JSSyntaxRegExp _re;
+  final String _string;
+  final int _start;
+
+  _AllMatchesIterable(this._re, this._string, this._start);
+
+  Iterator<RegExpMatch> get iterator =>
+      _AllMatchesIterator(_re, _string, _start);
+}
+
+class _AllMatchesIterator implements Iterator<RegExpMatch> {
+  final JSSyntaxRegExp _regExp;
+  String _string;
+  int _nextIndex;
+  RegExpMatch _current;
+
+  _AllMatchesIterator(this._regExp, this._string, this._nextIndex);
+
+  RegExpMatch get current => _current;
+
+  static bool _isLeadSurrogate(int c) {
+    return c >= 0xd800 && c <= 0xdbff;
+  }
+
+  static bool _isTrailSurrogate(int c) {
+    return c >= 0xdc00 && c <= 0xdfff;
+  }
+
+  bool moveNext() {
+    if (_string == null) return false;
+    if (_nextIndex <= _string.length) {
+      var match = _regExp._execGlobal(_string, _nextIndex);
+      if (match != null) {
+        _current = match;
+        int nextIndex = match.end;
+        if (match.start == nextIndex) {
+          // Zero-width match. Advance by one more, unless the regexp
+          // is in unicode mode and it would put us within a surrogate
+          // pair. In that case, advance past the code point as a whole.
+          if (_regExp.isUnicode &&
+              _nextIndex + 1 < _string.length &&
+              _isLeadSurrogate(_string.codeUnitAt(_nextIndex)) &&
+              _isTrailSurrogate(_string.codeUnitAt(_nextIndex + 1))) {
+            nextIndex++;
+          }
+          nextIndex++;
+        }
+        _nextIndex = nextIndex;
+        return true;
+      }
+    }
+    _current = null;
+    _string = null; // Marks iteration as ended.
+    return false;
+  }
+}
+
+/** Find the first match of [regExp] in [string] at or after [start]. */
+RegExpMatch firstMatchAfter(JSSyntaxRegExp regExp, String string, int start) {
+  return regExp._execGlobal(string, start);
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/string_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/string_helper.dart
new file mode 100644
index 0000000..c1b5c18
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/string_helper.dart
@@ -0,0 +1,297 @@
+// Copyright (c) 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 dart._js_helper;
+
+@notNull
+int stringIndexOfStringUnchecked(receiver, other, startIndex) {
+  return JS<int>('!', '#.indexOf(#, #)', receiver, other, startIndex);
+}
+
+@notNull
+String substring1Unchecked(receiver, startIndex) {
+  return JS('!', '#.substring(#)', receiver, startIndex);
+}
+
+@notNull
+String substring2Unchecked(receiver, startIndex, endIndex) {
+  return JS('!', '#.substring(#, #)', receiver, startIndex, endIndex);
+}
+
+@notNull
+bool stringContainsStringUnchecked(receiver, other, startIndex) {
+  return stringIndexOfStringUnchecked(receiver, other, startIndex) >= 0;
+}
+
+class StringMatch implements Match {
+  const StringMatch(int this.start, String this.input, String this.pattern);
+
+  int get end => start + pattern.length;
+  String operator [](int g) => group(g);
+  int get groupCount => 0;
+
+  String group(int group_) {
+    if (group_ != 0) {
+      throw RangeError.value(group_);
+    }
+    return pattern;
+  }
+
+  List<String> groups(List<int> groups_) {
+    List<String> result = List<String>();
+    for (int g in groups_) {
+      result.add(group(g));
+    }
+    return result;
+  }
+
+  final int start;
+  final String input;
+  final String pattern;
+}
+
+Iterable<Match> allMatchesInStringUnchecked(
+    String pattern, String string, int startIndex) {
+  return _StringAllMatchesIterable(string, pattern, startIndex);
+}
+
+class _StringAllMatchesIterable extends Iterable<Match> {
+  final String _input;
+  final String _pattern;
+  final int _index;
+
+  _StringAllMatchesIterable(this._input, this._pattern, this._index);
+
+  Iterator<Match> get iterator =>
+      _StringAllMatchesIterator(_input, _pattern, _index);
+
+  Match get first {
+    int index = stringIndexOfStringUnchecked(_input, _pattern, _index);
+    if (index >= 0) {
+      return StringMatch(index, _input, _pattern);
+    }
+    throw IterableElementError.noElement();
+  }
+}
+
+class _StringAllMatchesIterator implements Iterator<Match> {
+  final String _input;
+  final String _pattern;
+  int _index;
+  Match _current;
+
+  _StringAllMatchesIterator(this._input, this._pattern, this._index);
+
+  bool moveNext() {
+    if (_index + _pattern.length > _input.length) {
+      _current = null;
+      return false;
+    }
+    var index = stringIndexOfStringUnchecked(_input, _pattern, _index);
+    if (index < 0) {
+      _index = _input.length + 1;
+      _current = null;
+      return false;
+    }
+    int end = index + _pattern.length;
+    _current = StringMatch(index, _input, _pattern);
+    // Empty match, don't start at same location again.
+    if (end == _index) end++;
+    _index = end;
+    return true;
+  }
+
+  Match get current => _current;
+}
+
+@notNull
+bool stringContainsUnchecked(
+    @notNull String receiver, @notNull other, int startIndex) {
+  if (other is String) {
+    return stringContainsStringUnchecked(receiver, other, startIndex);
+  } else if (other is JSSyntaxRegExp) {
+    return other.hasMatch(receiver.substring(startIndex));
+  } else {
+    var substr = receiver.substring(startIndex);
+    return other.allMatches(substr).isNotEmpty;
+  }
+}
+
+@notNull
+String stringReplaceJS(String receiver, replacer, String replacement) {
+  // The JavaScript String.replace method recognizes replacement
+  // patterns in the replacement string. Dart does not have that
+  // behavior.
+  replacement = JS<String>('!', r'#.replace(/\$/g, "$$$$")', replacement);
+  return JS<String>('!', r'#.replace(#, #)', receiver, replacer, replacement);
+}
+
+@notNull
+String stringReplaceFirstRE(@notNull String receiver, JSSyntaxRegExp regexp,
+    String replacement, int startIndex) {
+  var match = regexp._execGlobal(receiver, startIndex);
+  if (match == null) return receiver;
+  var start = match.start;
+  var end = match.end;
+  return stringReplaceRangeUnchecked(receiver, start, end, replacement);
+}
+
+/// Returns a string for a RegExp pattern that matches [string]. This is done by
+/// escaping all RegExp metacharacters.
+@notNull
+String quoteStringForRegExp(string) {
+  return JS<String>('!', r'#.replace(/[[\]{}()*+?.\\^$|]/g, "\\$&")', string);
+}
+
+@notNull
+String stringReplaceAllUnchecked(@notNull String receiver,
+    @nullCheck Pattern pattern, @nullCheck String replacement) {
+  if (pattern is String) {
+    if (pattern == "") {
+      if (receiver == "") {
+        return replacement;
+      } else {
+        StringBuffer result = StringBuffer();
+        int length = receiver.length;
+        result.write(replacement);
+        for (int i = 0; i < length; i++) {
+          result.write(receiver[i]);
+          result.write(replacement);
+        }
+        return result.toString();
+      }
+    } else {
+      return JS<String>(
+          '!', '#.split(#).join(#)', receiver, pattern, replacement);
+    }
+  } else if (pattern is JSSyntaxRegExp) {
+    var re = regExpGetGlobalNative(pattern);
+    return stringReplaceJS(receiver, re, replacement);
+  } else {
+    // TODO(floitsch): implement generic String.replace (with patterns).
+    throw "String.replaceAll(Pattern) UNIMPLEMENTED";
+  }
+}
+
+String _matchString(Match match) => match[0];
+String _stringIdentity(String string) => string;
+
+@notNull
+String stringReplaceAllFuncUnchecked(
+    String receiver,
+    @nullCheck Pattern pattern,
+    String onMatch(Match match),
+    String onNonMatch(String nonMatch)) {
+  if (onMatch == null) onMatch = _matchString;
+  if (onNonMatch == null) onNonMatch = _stringIdentity;
+  if (pattern is String) {
+    return stringReplaceAllStringFuncUnchecked(
+        receiver, pattern, onMatch, onNonMatch);
+  }
+  StringBuffer buffer = StringBuffer();
+  int startIndex = 0;
+  for (Match match in pattern.allMatches(receiver)) {
+    buffer.write(onNonMatch(receiver.substring(startIndex, match.start)));
+    buffer.write(onMatch(match));
+    startIndex = match.end;
+  }
+  buffer.write(onNonMatch(receiver.substring(startIndex)));
+  return buffer.toString();
+}
+
+@notNull
+String stringReplaceAllEmptyFuncUnchecked(String receiver,
+    String onMatch(Match match), String onNonMatch(String nonMatch)) {
+  // Pattern is the empty string.
+  StringBuffer buffer = StringBuffer();
+  int length = receiver.length;
+  int i = 0;
+  buffer.write(onNonMatch(""));
+  while (i < length) {
+    buffer.write(onMatch(StringMatch(i, receiver, "")));
+    // Special case to avoid splitting a surrogate pair.
+    int code = receiver.codeUnitAt(i);
+    if ((code & ~0x3FF) == 0xD800 && length > i + 1) {
+      // Leading surrogate;
+      code = receiver.codeUnitAt(i + 1);
+      if ((code & ~0x3FF) == 0xDC00) {
+        // Matching trailing surrogate.
+        buffer.write(onNonMatch(receiver.substring(i, i + 2)));
+        i += 2;
+        continue;
+      }
+    }
+    buffer.write(onNonMatch(receiver[i]));
+    i++;
+  }
+  buffer.write(onMatch(StringMatch(i, receiver, "")));
+  buffer.write(onNonMatch(""));
+  return buffer.toString();
+}
+
+@notNull
+String stringReplaceAllStringFuncUnchecked(String receiver, String pattern,
+    String onMatch(Match match), String onNonMatch(String nonMatch)) {
+  int patternLength = pattern.length;
+  if (patternLength == 0) {
+    return stringReplaceAllEmptyFuncUnchecked(receiver, onMatch, onNonMatch);
+  }
+  int length = receiver.length;
+  StringBuffer buffer = StringBuffer();
+  int startIndex = 0;
+  while (startIndex < length) {
+    int position = stringIndexOfStringUnchecked(receiver, pattern, startIndex);
+    if (position == -1) {
+      break;
+    }
+    buffer.write(onNonMatch(receiver.substring(startIndex, position)));
+    buffer.write(onMatch(StringMatch(position, receiver, pattern)));
+    startIndex = position + patternLength;
+  }
+  buffer.write(onNonMatch(receiver.substring(startIndex)));
+  return buffer.toString();
+}
+
+@notNull
+String stringReplaceFirstUnchecked(@notNull String receiver,
+    @nullCheck Pattern pattern, String replacement, int startIndex) {
+  if (pattern is String) {
+    int index = stringIndexOfStringUnchecked(receiver, pattern, startIndex);
+    if (index < 0) return receiver;
+    int end = index + pattern.length;
+    return stringReplaceRangeUnchecked(receiver, index, end, replacement);
+  }
+  if (pattern is JSSyntaxRegExp) {
+    return startIndex == 0
+        ? stringReplaceJS(receiver, regExpGetNative(pattern), replacement)
+        : stringReplaceFirstRE(receiver, pattern, replacement, startIndex);
+  }
+  Iterator<Match> matches = pattern.allMatches(receiver, startIndex).iterator;
+  if (!matches.moveNext()) return receiver;
+  Match match = matches.current;
+  return receiver.replaceRange(match.start, match.end, replacement);
+}
+
+@notNull
+String stringReplaceFirstMappedUnchecked(String receiver, Pattern pattern,
+    String replace(Match current), int startIndex) {
+  Iterator<Match> matches = pattern.allMatches(receiver, startIndex).iterator;
+  if (!matches.moveNext()) return receiver;
+  Match match = matches.current;
+  String replacement = "${replace(match)}";
+  return receiver.replaceRange(match.start, match.end, replacement);
+}
+
+@notNull
+String stringJoinUnchecked(array, separator) {
+  return JS<String>('!', r'#.join(#)', array, separator);
+}
+
+@notNull
+String stringReplaceRangeUnchecked(
+    String receiver, int start, int end, String replacement) {
+  String prefix = JS('!', '#.substring(0, #)', receiver, start);
+  String suffix = JS('!', '#.substring(#)', receiver, end);
+  return "$prefix$replacement$suffix";
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/.packages b/sdk_nnbd/lib/_internal/js_runtime/.packages
new file mode 100644
index 0000000..adf8b36
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/.packages
@@ -0,0 +1,2 @@
+# Generated by pub on 2015-12-07 17:08:11.724.
+js_runtime:lib/
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/annotations.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/annotations.dart
new file mode 100644
index 0000000..f53c5f3
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/annotations.dart
@@ -0,0 +1,18 @@
+// 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 _js_helper;
+
+/// Marks a class as native and defines its JavaScript name(s).
+class Native {
+  final String name;
+  const Native(this.name);
+}
+
+class _Patch {
+  const _Patch();
+}
+
+/// Annotation that marks the declaration as a patch.
+const _Patch patch = const _Patch();
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart
new file mode 100644
index 0000000..68bcbeb
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart
@@ -0,0 +1,694 @@
+// Copyright (c) 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.
+
+// Patch file for the dart:async library.
+
+import 'dart:_js_helper'
+    show
+        patch,
+        ExceptionAndStackTrace,
+        convertDartClosureToJS,
+        getTraceFromException,
+        requiresPreamble,
+        wrapException,
+        unwrapException;
+
+import 'dart:_foreign_helper' show JS, JS_GET_FLAG;
+
+import 'dart:_async_await_error_codes' as async_error_codes;
+
+import "dart:collection" show IterableBase;
+
+@patch
+class _AsyncRun {
+  @patch
+  static void _scheduleImmediate(void callback()) {
+    _scheduleImmediateClosure(callback);
+  }
+
+  // Lazily initialized.
+  static final Function _scheduleImmediateClosure =
+      _initializeScheduleImmediate();
+
+  static Function _initializeScheduleImmediate() {
+    requiresPreamble();
+    if (JS('', 'self.scheduleImmediate') != null) {
+      return _scheduleImmediateJsOverride;
+    }
+    if (JS('', 'self.MutationObserver') != null &&
+        JS('', 'self.document') != null) {
+      // Use mutationObservers.
+      var div = JS('', 'self.document.createElement("div")');
+      var span = JS('', 'self.document.createElement("span")');
+      var storedCallback;
+
+      internalCallback(_) {
+        var f = storedCallback;
+        storedCallback = null;
+        f();
+      }
+
+      var observer = JS('', 'new self.MutationObserver(#)',
+          convertDartClosureToJS(internalCallback, 1));
+      JS('', '#.observe(#, { childList: true })', observer, div);
+
+      return (void callback()) {
+        assert(storedCallback == null);
+        storedCallback = callback;
+        // Because of a broken shadow-dom polyfill we have to change the
+        // children instead a cheap property.
+        JS('', '#.firstChild ? #.removeChild(#): #.appendChild(#)', div, div,
+            span, div, span);
+      };
+    } else if (JS('', 'self.setImmediate') != null) {
+      return _scheduleImmediateWithSetImmediate;
+    }
+    // TODO(20055): We should use DOM promises when available.
+    return _scheduleImmediateWithTimer;
+  }
+
+  static void _scheduleImmediateJsOverride(void callback()) {
+    internalCallback() {
+      callback();
+    }
+
+    JS('void', 'self.scheduleImmediate(#)',
+        convertDartClosureToJS(internalCallback, 0));
+  }
+
+  static void _scheduleImmediateWithSetImmediate(void callback()) {
+    internalCallback() {
+      callback();
+    }
+
+    JS('void', 'self.setImmediate(#)',
+        convertDartClosureToJS(internalCallback, 0));
+  }
+
+  static void _scheduleImmediateWithTimer(void callback()) {
+    Timer._createTimer(Duration.zero, callback);
+  }
+}
+
+@patch
+class DeferredLibrary {
+  @patch
+  Future<Null> load() {
+    throw 'DeferredLibrary not supported. '
+        'please use the `import "lib.dart" deferred as lib` syntax.';
+  }
+}
+
+@patch
+class Timer {
+  @patch
+  static Timer _createTimer(Duration duration, void callback()) {
+    int milliseconds = duration.inMilliseconds;
+    if (milliseconds < 0) milliseconds = 0;
+    return new _TimerImpl(milliseconds, callback);
+  }
+
+  @patch
+  static Timer _createPeriodicTimer(
+      Duration duration, void callback(Timer timer)) {
+    int milliseconds = duration.inMilliseconds;
+    if (milliseconds < 0) milliseconds = 0;
+    return new _TimerImpl.periodic(milliseconds, callback);
+  }
+}
+
+class _TimerImpl implements Timer {
+  final bool _once;
+  int _handle;
+  int _tick = 0;
+
+  _TimerImpl(int milliseconds, void callback()) : _once = true {
+    if (_hasTimer()) {
+      void internalCallback() {
+        _handle = null;
+        this._tick = 1;
+        callback();
+      }
+
+      _handle = JS('int', 'self.setTimeout(#, #)',
+          convertDartClosureToJS(internalCallback, 0), milliseconds);
+    } else {
+      throw new UnsupportedError('`setTimeout()` not found.');
+    }
+  }
+
+  _TimerImpl.periodic(int milliseconds, void callback(Timer timer))
+      : _once = false {
+    if (_hasTimer()) {
+      int start = JS('int', 'Date.now()');
+      _handle = JS(
+          'int',
+          'self.setInterval(#, #)',
+          convertDartClosureToJS(() {
+            int tick = this._tick + 1;
+            if (milliseconds > 0) {
+              int duration = JS('int', 'Date.now()') - start;
+              if (duration > (tick + 1) * milliseconds) {
+                tick = duration ~/ milliseconds;
+              }
+            }
+            this._tick = tick;
+            callback(this);
+          }, 0),
+          milliseconds);
+    } else {
+      throw new UnsupportedError('Periodic timer.');
+    }
+  }
+
+  @override
+  bool get isActive => _handle != null;
+
+  @override
+  int get tick => _tick;
+
+  @override
+  void cancel() {
+    if (_hasTimer()) {
+      if (_handle == null) return;
+      if (_once) {
+        JS('void', 'self.clearTimeout(#)', _handle);
+      } else {
+        JS('void', 'self.clearInterval(#)', _handle);
+      }
+      _handle = null;
+    } else {
+      throw new UnsupportedError('Canceling a timer.');
+    }
+  }
+}
+
+bool _hasTimer() {
+  requiresPreamble();
+  return JS('', 'self.setTimeout') != null;
+}
+
+class _AsyncAwaitCompleter<T> implements Completer<T> {
+  final _future = new _Future<T>();
+  bool isSync;
+
+  _AsyncAwaitCompleter() : isSync = false;
+
+  void complete([FutureOr<T> value]) {
+    if (!isSync || value is Future<T>) {
+      _future._asyncComplete(value);
+    } else {
+      _future._completeWithValue(value);
+    }
+  }
+
+  void completeError(e, [st]) {
+    if (isSync) {
+      _future._completeError(e, st);
+    } else {
+      _future._asyncCompleteError(e, st);
+    }
+  }
+
+  Future<T> get future => _future;
+  bool get isCompleted => !_future._mayComplete;
+}
+
+/// Creates a Completer for an `async` function.
+///
+/// Used as part of the runtime support for the async/await transformation.
+Completer<T> _makeAsyncAwaitCompleter<T>() {
+  return new _AsyncAwaitCompleter<T>();
+}
+
+/// Initiates the computation of an `async` function and starts the body
+/// synchronously.
+///
+/// Used as part of the runtime support for the async/await transformation.
+///
+/// This function sets up the first call into the transformed [bodyFunction].
+/// Independently, it takes the [completer] and returns the future of the
+/// completer for convenience of the transformed code.
+dynamic _asyncStartSync(
+    _WrappedAsyncBody bodyFunction, _AsyncAwaitCompleter completer) {
+  bodyFunction(async_error_codes.SUCCESS, null);
+  completer.isSync = true;
+  return completer.future;
+}
+
+/// Performs the `await` operation of an `async` function.
+///
+/// Used as part of the runtime support for the async/await transformation.
+///
+/// Arranges for [bodyFunction] to be called when the future or value [object]
+/// is completed with a code [async_error_codes.SUCCESS] or
+/// [async_error_codes.ERROR] depending on the success of the future.
+dynamic _asyncAwait(dynamic object, _WrappedAsyncBody bodyFunction) {
+  _awaitOnObject(object, bodyFunction);
+}
+
+/// Completes the future of an `async` function.
+///
+/// Used as part of the runtime support for the async/await transformation.
+///
+/// This function is used when the `async` function returns (explicitly or
+/// implicitly).
+dynamic _asyncReturn(dynamic object, Completer completer) {
+  completer.complete(object);
+}
+
+/// Completes the future of an `async` function with an error.
+///
+/// Used as part of the runtime support for the async/await transformation.
+///
+/// This function is used when the `async` function re-throws an exception.
+dynamic _asyncRethrow(dynamic object, Completer completer) {
+  // The error is a js-error.
+  completer.completeError(
+      unwrapException(object), getTraceFromException(object));
+}
+
+/// Awaits on the given [object].
+///
+/// If the [object] is a Future, registers on it, otherwise wraps it into a
+/// future first.
+///
+/// The [bodyFunction] argument is the continuation that should be invoked
+/// when the future completes.
+void _awaitOnObject(object, _WrappedAsyncBody bodyFunction) {
+  Function thenCallback =
+      (result) => bodyFunction(async_error_codes.SUCCESS, result);
+
+  Function errorCallback = (dynamic error, StackTrace stackTrace) {
+    ExceptionAndStackTrace wrappedException =
+        new ExceptionAndStackTrace(error, stackTrace);
+    bodyFunction(async_error_codes.ERROR, wrappedException);
+  };
+
+  if (object is _Future) {
+    // We can skip the zone registration, since the bodyFunction is already
+    // registered (see [_wrapJsFunctionForAsync]).
+    object._thenAwait(thenCallback, errorCallback);
+  } else if (object is Future) {
+    object.then(thenCallback, onError: errorCallback);
+  } else {
+    _Future future = new _Future().._setValue(object);
+    // We can skip the zone registration, since the bodyFunction is already
+    // registered (see [_wrapJsFunctionForAsync]).
+    future._thenAwait(thenCallback, null);
+  }
+}
+
+typedef void _WrappedAsyncBody(int errorCode, dynamic result);
+
+_WrappedAsyncBody _wrapJsFunctionForAsync(dynamic /* js function */ function) {
+  var protected = JS(
+      '',
+      """
+        (function (fn, ERROR) {
+          // Invokes [function] with [errorCode] and [result].
+          //
+          // If (and as long as) the invocation throws, calls [function] again,
+          // with an error-code.
+          return function(errorCode, result) {
+            while (true) {
+              try {
+                fn(errorCode, result);
+                break;
+              } catch (error) {
+                result = error;
+                errorCode = ERROR;
+              }
+            }
+          }
+        })(#, #)""",
+      function,
+      async_error_codes.ERROR);
+
+  return Zone.current.registerBinaryCallback((int errorCode, dynamic result) {
+    JS('', '#(#, #)', protected, errorCode, result);
+  });
+}
+
+/// Implements the runtime support for async* functions.
+///
+/// Called by the transformed function for each original return, await, yield,
+/// yield* and before starting the function.
+///
+/// When the async* function wants to return it calls this function with
+/// [asyncBody] == [async_error_codes.SUCCESS], the asyncStarHelper takes this
+/// as signal to close the stream.
+///
+/// When the async* function wants to signal that an uncaught error was thrown,
+/// it calls this function with [asyncBody] == [async_error_codes.ERROR],
+/// the streamHelper takes this as signal to addError [object] to the
+/// [controller] and close it.
+///
+/// If the async* function wants to do a yield or yield*, it calls this function
+/// with [object] being an [IterationMarker].
+///
+/// In the case of a yield or yield*, if the stream subscription has been
+/// canceled, schedules [asyncBody] to be called with
+/// [async_error_codes.STREAM_WAS_CANCELED].
+///
+/// If [object] is a single-yield [IterationMarker], adds the value of the
+/// [IterationMarker] to the stream. If the stream subscription has been
+/// paused, return early. Otherwise schedule the helper function to be
+/// executed again.
+///
+/// If [object] is a yield-star [IterationMarker], starts listening to the
+/// yielded stream, and adds all events and errors to our own controller (taking
+/// care if the subscription has been paused or canceled) - when the sub-stream
+/// is done, schedules [asyncBody] again.
+///
+/// If the async* function wants to do an await it calls this function with
+/// [object] not an [IterationMarker].
+///
+/// If [object] is not a [Future], it is wrapped in a `Future.value`.
+/// The [asyncBody] is called on completion of the future (see [asyncHelper].
+void _asyncStarHelper(
+    dynamic object,
+    dynamic /* int | _WrappedAsyncBody */ bodyFunctionOrErrorCode,
+    _AsyncStarStreamController controller) {
+  if (identical(bodyFunctionOrErrorCode, async_error_codes.SUCCESS)) {
+    // This happens on return from the async* function.
+    if (controller.isCanceled) {
+      controller.cancelationFuture._completeWithValue(null);
+    } else {
+      controller.close();
+    }
+    return;
+  } else if (identical(bodyFunctionOrErrorCode, async_error_codes.ERROR)) {
+    // The error is a js-error.
+    if (controller.isCanceled) {
+      controller.cancelationFuture._completeError(
+          unwrapException(object), getTraceFromException(object));
+    } else {
+      controller.addError(
+          unwrapException(object), getTraceFromException(object));
+      controller.close();
+    }
+    return;
+  }
+
+  if (object is _IterationMarker) {
+    if (controller.isCanceled) {
+      bodyFunctionOrErrorCode(async_error_codes.STREAM_WAS_CANCELED, null);
+      return;
+    }
+    if (object.state == _IterationMarker.YIELD_SINGLE) {
+      controller.add(object.value);
+
+      scheduleMicrotask(() {
+        if (controller.isPaused) {
+          // We only suspend the thread inside the microtask in order to allow
+          // listeners on the output stream to pause in response to the just
+          // output value, and have the stream immediately stop producing.
+          controller.isSuspended = true;
+          return;
+        }
+        bodyFunctionOrErrorCode(null, async_error_codes.SUCCESS);
+      });
+      return;
+    } else if (object.state == _IterationMarker.YIELD_STAR) {
+      Stream stream = object.value;
+      // Errors of [stream] are passed though to the main stream. (see
+      // [AsyncStreamController.addStream]).
+      // TODO(sigurdm): The spec is not very clear here. Clarify with Gilad.
+      controller.addStream(stream).then((_) {
+        // No check for isPaused here because the spec 17.16.2 only
+        // demands checks *before* each element in [stream] not after the last
+        // one. On the other hand we check for isCanceled, as that check happens
+        // after insertion of each element.
+        int errorCode = controller.isCanceled
+            ? async_error_codes.STREAM_WAS_CANCELED
+            : async_error_codes.SUCCESS;
+        bodyFunctionOrErrorCode(errorCode, null);
+      });
+      return;
+    }
+  }
+
+  _awaitOnObject(object, bodyFunctionOrErrorCode);
+}
+
+Stream _streamOfController(_AsyncStarStreamController controller) {
+  return controller.stream;
+}
+
+/// A wrapper around a [StreamController] that keeps track of the state of
+/// the execution of an async* function.
+/// It can be in 1 of 3 states:
+///
+/// - running/scheduled
+/// - suspended
+/// - canceled
+///
+/// If yielding while the subscription is paused it will become suspended. And
+/// only resume after the subscription is resumed or canceled.
+class _AsyncStarStreamController<T> {
+  StreamController<T> controller;
+  Stream get stream => controller.stream;
+
+  /// True when the async* function has yielded while being paused.
+  /// When true execution will only resume after a `onResume` or `onCancel`
+  /// event.
+  bool isSuspended = false;
+
+  bool get isPaused => controller.isPaused;
+
+  _Future cancelationFuture = null;
+
+  /// True after the StreamSubscription has been cancelled.
+  /// When this is true, errors thrown from the async* body should go to the
+  /// [cancelationFuture] instead of adding them to [controller], and
+  /// returning from the async function should complete [cancelationFuture].
+  bool get isCanceled => cancelationFuture != null;
+
+  add(event) => controller.add(event);
+
+  addStream(Stream<T> stream) {
+    return controller.addStream(stream, cancelOnError: false);
+  }
+
+  addError(error, stackTrace) => controller.addError(error, stackTrace);
+
+  close() => controller.close();
+
+  _AsyncStarStreamController(_WrappedAsyncBody body) {
+    _resumeBody() {
+      scheduleMicrotask(() {
+        body(async_error_codes.SUCCESS, null);
+      });
+    }
+
+    controller = new StreamController<T>(onListen: () {
+      _resumeBody();
+    }, onResume: () {
+      // Only schedule again if the async* function actually is suspended.
+      // Resume directly instead of scheduling, so that the sequence
+      // `pause-resume-pause` will result in one extra event produced.
+      if (isSuspended) {
+        isSuspended = false;
+        _resumeBody();
+      }
+    }, onCancel: () {
+      // If the async* is finished we ignore cancel events.
+      if (!controller.isClosed) {
+        cancelationFuture = new _Future();
+        if (isSuspended) {
+          // Resume the suspended async* function to run finalizers.
+          isSuspended = false;
+          scheduleMicrotask(() {
+            body(async_error_codes.STREAM_WAS_CANCELED, null);
+          });
+        }
+        return cancelationFuture;
+      }
+    });
+  }
+}
+
+/// Creates a stream controller for an `async*` function.
+///
+/// Used as part of the runtime support for the async/await transformation.
+_makeAsyncStarStreamController<T>(_WrappedAsyncBody body) {
+  return new _AsyncStarStreamController<T>(body);
+}
+
+class _IterationMarker {
+  static const YIELD_SINGLE = 0;
+  static const YIELD_STAR = 1;
+  static const ITERATION_ENDED = 2;
+  static const UNCAUGHT_ERROR = 3;
+
+  final value;
+  final int state;
+
+  const _IterationMarker._(this.state, this.value);
+
+  static yieldStar(dynamic /* Iterable or Stream */ values) {
+    return new _IterationMarker._(YIELD_STAR, values);
+  }
+
+  static endOfIteration() {
+    return const _IterationMarker._(ITERATION_ENDED, null);
+  }
+
+  static yieldSingle(dynamic value) {
+    return new _IterationMarker._(YIELD_SINGLE, value);
+  }
+
+  static uncaughtError(dynamic error) {
+    return new _IterationMarker._(UNCAUGHT_ERROR, error);
+  }
+
+  toString() => "IterationMarker($state, $value)";
+}
+
+class _SyncStarIterator<T> implements Iterator<T> {
+  // _SyncStarIterator handles stepping a sync* generator body state machine.
+  //
+  // It also handles the stepping over 'nested' iterators to flatten yield*
+  // statements. For non-sync* iterators, [_nestedIterator] contains the
+  // iterator. We delegate to [_nestedIterator] when it is not `null`.
+  //
+  // For nested sync* iterators, [this] iterator acts on behalf of the innermost
+  // nested sync* iterator. The current state machine is suspended on a stack
+  // until the inner state machine ends.
+
+  // The state machine for the innermost _SyncStarIterator.
+  dynamic _body;
+
+  // The current value, unless iterating a non-sync* nested iterator.
+  T _current = null;
+
+  // This is the nested iterator when iterating a yield* of a non-sync iterator.
+  // TODO(32956): In strong-mode, yield* takes an Iterable<T> (possibly checked
+  // with an implicit downcast), so change type to Iterator<T>.
+  Iterator _nestedIterator = null;
+
+  // Stack of suspended state machines when iterating a yield* of a sync*
+  // iterator.
+  List _suspendedBodies = null;
+
+  _SyncStarIterator(this._body);
+
+  T get current {
+    if (_nestedIterator == null) return _current;
+    return _nestedIterator.current;
+  }
+
+  _runBody() {
+    // TODO(sra): Find a way to hard-wire SUCCESS and ERROR codes.
+    return JS(
+        '',
+        '''
+        // Invokes [body] with [errorCode] and [result].
+        //
+        // If (and as long as) the invocation throws, calls [function] again,
+        // with an error-code.
+        (function(body, SUCCESS, ERROR) {
+          var errorValue, errorCode = SUCCESS;
+          while (true) {
+            try {
+              return body(errorCode, errorValue);
+            } catch (error) {
+              errorValue = error;
+              errorCode = ERROR;
+            }
+          }
+        })(#, #, #)''',
+        _body,
+        async_error_codes.SUCCESS,
+        async_error_codes.ERROR);
+  }
+
+  bool moveNext() {
+    while (true) {
+      if (_nestedIterator != null) {
+        if (_nestedIterator.moveNext()) {
+          return true;
+        } else {
+          _nestedIterator = null;
+        }
+      }
+      var value = _runBody();
+      if (value is _IterationMarker) {
+        int state = value.state;
+        if (state == _IterationMarker.ITERATION_ENDED) {
+          if (_suspendedBodies == null || _suspendedBodies.isEmpty) {
+            _current = null;
+            // Rely on [_body] to repeatedly return `ITERATION_ENDED`.
+            return false;
+          }
+          // Resume the innermost suspended iterator.
+          _body = _suspendedBodies.removeLast();
+          continue;
+        } else if (state == _IterationMarker.UNCAUGHT_ERROR) {
+          // Rely on [_body] to repeatedly return `UNCAUGHT_ERROR`.
+          // This is a wrapped exception, so we use JavaScript throw to throw
+          // it.
+          JS('', 'throw #', value.value);
+        } else {
+          assert(state == _IterationMarker.YIELD_STAR);
+          Iterator inner = value.value.iterator;
+          if (inner is _SyncStarIterator) {
+            // Suspend the current state machine and start acting on behalf of
+            // the nested state machine.
+            //
+            // TODO(sra): Recognize "tail yield*" statements and avoid
+            // suspending the current body when all it will do is step without
+            // effect to ITERATION_ENDED.
+            (_suspendedBodies ??= []).add(_body);
+            _body = inner._body;
+            continue;
+          } else {
+            _nestedIterator = inner;
+            // TODO(32956): Change to the following when strong-mode is the only
+            // option:
+            //
+            //     _nestedIterator = JS<Iterator<T>>('','#', inner);
+            continue;
+          }
+        }
+      } else {
+        // TODO(32956): Remove this test.
+        _current = JS<T>('', '#', value);
+        return true;
+      }
+    }
+    return false; // TODO(sra): Fix type inference so that this is not needed.
+  }
+}
+
+/// Creates an Iterable for a `sync*` function.
+///
+/// Used as part of the runtime support for the async/await transformation.
+_SyncStarIterable<T> _makeSyncStarIterable<T>(body) {
+  return new _SyncStarIterable<T>(body);
+}
+
+/// An Iterable corresponding to a sync* method.
+///
+/// Each invocation of a sync* method will return a new instance of this class.
+class _SyncStarIterable<T> extends IterableBase<T> {
+  // This is a function that will return a helper function that does the
+  // iteration of the sync*.
+  //
+  // Each invocation should give a body with fresh state.
+  final dynamic /* js function */ _outerHelper;
+
+  _SyncStarIterable(this._outerHelper);
+
+  Iterator<T> get iterator =>
+      new _SyncStarIterator<T>(JS('', '#()', _outerHelper));
+}
+
+@patch
+void _rethrow(Object error, StackTrace stackTrace) {
+  error = wrapException(error);
+  JS('void', '#.stack = #', error, stackTrace.toString());
+  JS('void', 'throw #', error);
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/cli_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/cli_patch.dart
new file mode 100644
index 0000000..6921e60
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/cli_patch.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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:_js_helper' show patch;
+
+@patch
+void _waitForEvent(int timeoutMillis) {
+  throw new UnsupportedError("waitForEvent");
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart
new file mode 100644
index 0000000..300d490
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart
@@ -0,0 +1,1727 @@
+// 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.
+
+// Patch file for dart:collection classes.
+import 'dart:_foreign_helper' show JS;
+import 'dart:_js_helper'
+    show
+        fillLiteralMap,
+        fillLiteralSet,
+        InternalMap,
+        NoInline,
+        NoSideEffects,
+        NoThrows,
+        patch,
+        JsLinkedHashMap,
+        LinkedHashMapCell,
+        LinkedHashMapKeyIterable,
+        LinkedHashMapKeyIterator;
+
+import 'dart:_internal' hide Symbol;
+
+const _USE_ES6_MAPS = const bool.fromEnvironment("dart2js.use.es6.maps");
+
+const int _mask30 = 0x3fffffff; // Low 30 bits.
+
+@patch
+class HashMap<K, V> {
+  @patch
+  factory HashMap(
+      {bool equals(K key1, K key2),
+      int hashCode(K key),
+      bool isValidKey(potentialKey)}) {
+    if (isValidKey == null) {
+      if (hashCode == null) {
+        if (equals == null) {
+          return new _HashMap<K, V>();
+        }
+        hashCode = _defaultHashCode;
+      } else {
+        if (identical(identityHashCode, hashCode) &&
+            identical(identical, equals)) {
+          return new _IdentityHashMap<K, V>();
+        }
+        if (equals == null) {
+          equals = _defaultEquals;
+        }
+      }
+    } else {
+      if (hashCode == null) {
+        hashCode = _defaultHashCode;
+      }
+      if (equals == null) {
+        equals = _defaultEquals;
+      }
+    }
+    return new _CustomHashMap<K, V>(equals, hashCode, isValidKey);
+  }
+
+  @patch
+  factory HashMap.identity() = _IdentityHashMap<K, V>;
+}
+
+class _HashMap<K, V> extends MapBase<K, V> implements HashMap<K, V> {
+  int _length = 0;
+
+  // The hash map contents are divided into three parts: one part for
+  // string keys, one for numeric keys, and one for the rest. String
+  // and numeric keys map directly to their values, but the rest of
+  // the entries are stored in bucket lists of the form:
+  //
+  //    [key-0, value-0, key-1, value-1, ...]
+  //
+  // where all keys in the same bucket share the same hash code.
+  var _strings;
+  var _nums;
+  var _rest;
+
+  // When iterating over the hash map, it is very convenient to have a
+  // list of all the keys. We cache that on the instance and clear the
+  // the cache whenever the key set changes. This is also used to
+  // guard against concurrent modifications.
+  List _keys;
+
+  _HashMap();
+
+  int get length => _length;
+  bool get isEmpty => _length == 0;
+  bool get isNotEmpty => !isEmpty;
+
+  Iterable<K> get keys {
+    return new _HashMapKeyIterable<K>(this);
+  }
+
+  Iterable<V> get values {
+    return new MappedIterable<K, V>(keys, (each) => this[each]);
+  }
+
+  bool containsKey(Object key) {
+    if (_isStringKey(key)) {
+      var strings = _strings;
+      return (strings == null) ? false : _hasTableEntry(strings, key);
+    } else if (_isNumericKey(key)) {
+      var nums = _nums;
+      return (nums == null) ? false : _hasTableEntry(nums, key);
+    } else {
+      return _containsKey(key);
+    }
+  }
+
+  bool _containsKey(Object key) {
+    var rest = _rest;
+    if (rest == null) return false;
+    var bucket = _getBucket(rest, key);
+    return _findBucketIndex(bucket, key) >= 0;
+  }
+
+  bool containsValue(Object value) {
+    return _computeKeys().any((each) => this[each] == value);
+  }
+
+  void addAll(Map<K, V> other) {
+    other.forEach((K key, V value) {
+      this[key] = value;
+    });
+  }
+
+  V operator [](Object key) {
+    if (_isStringKey(key)) {
+      var strings = _strings;
+      return JS('', '#', strings == null ? null : _getTableEntry(strings, key));
+    } else if (_isNumericKey(key)) {
+      var nums = _nums;
+      return JS('', '#', nums == null ? null : _getTableEntry(nums, key));
+    } else {
+      return _get(key);
+    }
+  }
+
+  V _get(Object key) {
+    var rest = _rest;
+    if (rest == null) return null;
+    var bucket = _getBucket(rest, key);
+    int index = _findBucketIndex(bucket, key);
+    return (index < 0) ? null : JS('', '#[#]', bucket, index + 1);
+  }
+
+  void operator []=(K key, V value) {
+    if (_isStringKey(key)) {
+      var strings = _strings;
+      if (strings == null) _strings = strings = _newHashTable();
+      _addHashTableEntry(strings, key, value);
+    } else if (_isNumericKey(key)) {
+      var nums = _nums;
+      if (nums == null) _nums = nums = _newHashTable();
+      _addHashTableEntry(nums, key, value);
+    } else {
+      _set(key, value);
+    }
+  }
+
+  void _set(K key, V value) {
+    var rest = _rest;
+    if (rest == null) _rest = rest = _newHashTable();
+    var hash = _computeHashCode(key);
+    var bucket = JS('var', '#[#]', rest, hash);
+    if (bucket == null) {
+      _setTableEntry(rest, hash, JS('var', '[#, #]', key, value));
+      _length++;
+      _keys = null;
+    } else {
+      int index = _findBucketIndex(bucket, key);
+      if (index >= 0) {
+        JS('void', '#[#] = #', bucket, index + 1, value);
+      } else {
+        JS('void', '#.push(#, #)', bucket, key, value);
+        _length++;
+        _keys = null;
+      }
+    }
+  }
+
+  V putIfAbsent(K key, V ifAbsent()) {
+    if (containsKey(key)) return this[key];
+    V value = ifAbsent();
+    this[key] = value;
+    return value;
+  }
+
+  V remove(Object key) {
+    if (_isStringKey(key)) {
+      return _removeHashTableEntry(_strings, key);
+    } else if (_isNumericKey(key)) {
+      return _removeHashTableEntry(_nums, key);
+    } else {
+      return _remove(key);
+    }
+  }
+
+  V _remove(Object key) {
+    var rest = _rest;
+    if (rest == null) return null;
+    var bucket = _getBucket(rest, key);
+    int index = _findBucketIndex(bucket, key);
+    if (index < 0) return null;
+    // TODO(kasperl): Consider getting rid of the bucket list when
+    // the length reaches zero.
+    _length--;
+    _keys = null;
+    // Use splice to remove the two [key, value] elements at the
+    // index and return the value.
+    return JS('var', '#.splice(#, 2)[1]', bucket, index);
+  }
+
+  void clear() {
+    if (_length > 0) {
+      _strings = _nums = _rest = _keys = null;
+      _length = 0;
+    }
+  }
+
+  void forEach(void action(K key, V value)) {
+    List keys = _computeKeys();
+    for (int i = 0, length = keys.length; i < length; i++) {
+      var key = JS('var', '#[#]', keys, i);
+      action(key, this[key]);
+      if (JS('bool', '# !== #', keys, _keys)) {
+        throw new ConcurrentModificationError(this);
+      }
+    }
+  }
+
+  List _computeKeys() {
+    if (_keys != null) return _keys;
+    List result = new List(_length);
+    int index = 0;
+
+    // Add all string keys to the list.
+    var strings = _strings;
+    if (strings != null) {
+      var names = JS('var', 'Object.getOwnPropertyNames(#)', strings);
+      int entries = JS('int', '#.length', names);
+      for (int i = 0; i < entries; i++) {
+        String key = JS('String', '#[#]', names, i);
+        JS('void', '#[#] = #', result, index, key);
+        index++;
+      }
+    }
+
+    // Add all numeric keys to the list.
+    var nums = _nums;
+    if (nums != null) {
+      var names = JS('var', 'Object.getOwnPropertyNames(#)', nums);
+      int entries = JS('int', '#.length', names);
+      for (int i = 0; i < entries; i++) {
+        // Object.getOwnPropertyNames returns a list of strings, so we
+        // have to convert the keys back to numbers (+).
+        num key = JS('num', '+#[#]', names, i);
+        JS('void', '#[#] = #', result, index, key);
+        index++;
+      }
+    }
+
+    // Add all the remaining keys to the list.
+    var rest = _rest;
+    if (rest != null) {
+      var names = JS('var', 'Object.getOwnPropertyNames(#)', rest);
+      int entries = JS('int', '#.length', names);
+      for (int i = 0; i < entries; i++) {
+        var key = JS('String', '#[#]', names, i);
+        var bucket = JS('var', '#[#]', rest, key);
+        int length = JS('int', '#.length', bucket);
+        for (int i = 0; i < length; i += 2) {
+          var key = JS('var', '#[#]', bucket, i);
+          JS('void', '#[#] = #', result, index, key);
+          index++;
+        }
+      }
+    }
+    assert(index == _length);
+    return _keys = result;
+  }
+
+  void _addHashTableEntry(var table, K key, V value) {
+    if (!_hasTableEntry(table, key)) {
+      _length++;
+      _keys = null;
+    }
+    _setTableEntry(table, key, value);
+  }
+
+  V _removeHashTableEntry(var table, Object key) {
+    if (table != null && _hasTableEntry(table, key)) {
+      V value = _getTableEntry(table, key);
+      _deleteTableEntry(table, key);
+      _length--;
+      _keys = null;
+      return value;
+    } else {
+      return null;
+    }
+  }
+
+  static bool _isStringKey(var key) {
+    return key is String && key != '__proto__';
+  }
+
+  static bool _isNumericKey(var key) {
+    // Only treat unsigned 30-bit integers as numeric keys. This way,
+    // we avoid converting them to strings when we use them as keys in
+    // the JavaScript hash table object.
+    return key is num && JS('bool', '(# & #) === #', key, _mask30, key);
+  }
+
+  int _computeHashCode(var key) {
+    // We force the hash codes to be unsigned 30-bit integers to avoid
+    // issues with problematic keys like '__proto__'. Another option
+    // would be to throw an exception if the hash code isn't a number.
+    return JS('int', '# & #', key.hashCode, _mask30);
+  }
+
+  static bool _hasTableEntry(var table, var key) {
+    var entry = JS('var', '#[#]', table, key);
+    // We take care to only store non-null entries in the table, so we
+    // can check if the table has an entry for the given key with a
+    // simple null check.
+    return entry != null;
+  }
+
+  static _getTableEntry(var table, var key) {
+    var entry = JS('var', '#[#]', table, key);
+    // We store the table itself as the entry to signal that it really
+    // is a null value, so we have to map back to null here.
+    return JS('bool', '# === #', entry, table) ? null : entry;
+  }
+
+  static void _setTableEntry(var table, var key, var value) {
+    // We only store non-null entries in the table, so we have to
+    // change null values to refer to the table itself. Such values
+    // will be recognized and mapped back to null on access.
+    if (value == null) {
+      // Do not update [value] with [table], otherwise our
+      // optimizations could be confused by this opaque object being
+      // now used for more things than storing and fetching from it.
+      JS('void', '#[#] = #', table, key, table);
+    } else {
+      JS('void', '#[#] = #', table, key, value);
+    }
+  }
+
+  static void _deleteTableEntry(var table, var key) {
+    JS('void', 'delete #[#]', table, key);
+  }
+
+  List _getBucket(var table, var key) {
+    var hash = _computeHashCode(key);
+    return JS('var', '#[#]', table, hash);
+  }
+
+  int _findBucketIndex(var bucket, var key) {
+    if (bucket == null) return -1;
+    int length = JS('int', '#.length', bucket);
+    for (int i = 0; i < length; i += 2) {
+      if (JS('var', '#[#]', bucket, i) == key) return i;
+    }
+    return -1;
+  }
+
+  static _newHashTable() {
+    // Create a new JavaScript object to be used as a hash table. Use
+    // Object.create to avoid the properties on Object.prototype
+    // showing up as entries.
+    var table = JS('var', 'Object.create(null)');
+    // Attempt to force the hash table into 'dictionary' mode by
+    // adding a property to it and deleting it again.
+    var temporaryKey = '<non-identifier-key>';
+    _setTableEntry(table, temporaryKey, table);
+    _deleteTableEntry(table, temporaryKey);
+    return table;
+  }
+}
+
+class _IdentityHashMap<K, V> extends _HashMap<K, V> {
+  int _computeHashCode(var key) {
+    // We force the hash codes to be unsigned 30-bit integers to avoid
+    // issues with problematic keys like '__proto__'. Another option
+    // would be to throw an exception if the hash code isn't a number.
+    return JS('int', '# & #', identityHashCode(key), _mask30);
+  }
+
+  int _findBucketIndex(var bucket, var key) {
+    if (bucket == null) return -1;
+    int length = JS('int', '#.length', bucket);
+    for (int i = 0; i < length; i += 2) {
+      if (identical(JS('var', '#[#]', bucket, i), key)) return i;
+    }
+    return -1;
+  }
+}
+
+class _CustomHashMap<K, V> extends _HashMap<K, V> {
+  final _Equality<K> _equals;
+  final _Hasher<K> _hashCode;
+  final _Predicate _validKey;
+
+  _CustomHashMap(this._equals, this._hashCode, bool validKey(potentialKey))
+      : _validKey = (validKey != null) ? validKey : ((v) => v is K);
+
+  V operator [](Object key) {
+    if (!_validKey(key)) return null;
+    return super._get(key);
+  }
+
+  void operator []=(K key, V value) {
+    super._set(key, value);
+  }
+
+  bool containsKey(Object key) {
+    if (!_validKey(key)) return false;
+    return super._containsKey(key);
+  }
+
+  V remove(Object key) {
+    if (!_validKey(key)) return null;
+    return super._remove(key);
+  }
+
+  int _computeHashCode(var key) {
+    // We force the hash codes to be unsigned 30-bit integers to avoid
+    // issues with problematic keys like '__proto__'. Another option
+    // would be to throw an exception if the hash code isn't a number.
+    return JS('int', '# & #', _hashCode(key), _mask30);
+  }
+
+  int _findBucketIndex(var bucket, var key) {
+    if (bucket == null) return -1;
+    int length = JS('int', '#.length', bucket);
+    for (int i = 0; i < length; i += 2) {
+      if (_equals(JS('var', '#[#]', bucket, i), key)) return i;
+    }
+    return -1;
+  }
+}
+
+class _HashMapKeyIterable<E> extends EfficientLengthIterable<E> {
+  final _map;
+  _HashMapKeyIterable(this._map);
+
+  int get length => _map._length;
+  bool get isEmpty => _map._length == 0;
+
+  Iterator<E> get iterator {
+    return new _HashMapKeyIterator<E>(_map, _map._computeKeys());
+  }
+
+  bool contains(Object element) {
+    return _map.containsKey(element);
+  }
+
+  void forEach(void f(E element)) {
+    List keys = _map._computeKeys();
+    for (int i = 0, length = JS('int', '#.length', keys); i < length; i++) {
+      f(JS('var', '#[#]', keys, i));
+      if (JS('bool', '# !== #', keys, _map._keys)) {
+        throw new ConcurrentModificationError(_map);
+      }
+    }
+  }
+}
+
+class _HashMapKeyIterator<E> implements Iterator<E> {
+  final _map;
+  final List _keys;
+  int _offset = 0;
+  E _current;
+
+  _HashMapKeyIterator(this._map, this._keys);
+
+  E get current => _current;
+
+  bool moveNext() {
+    var keys = _keys;
+    int offset = _offset;
+    if (JS('bool', '# !== #', keys, _map._keys)) {
+      throw new ConcurrentModificationError(_map);
+    } else if (offset >= JS('int', '#.length', keys)) {
+      _current = null;
+      return false;
+    } else {
+      _current = JS('var', '#[#]', keys, offset);
+      // TODO(kasperl): For now, we have to tell the type inferrer to
+      // treat the result of doing offset + 1 as an int. Otherwise, we
+      // get unnecessary bailout code.
+      _offset = JS('int', '#', offset + 1);
+      return true;
+    }
+  }
+}
+
+@patch
+class LinkedHashMap<K, V> {
+  @patch
+  factory LinkedHashMap(
+      {bool equals(K key1, K key2),
+      int hashCode(K key),
+      bool isValidKey(potentialKey)}) {
+    if (isValidKey == null) {
+      if (hashCode == null) {
+        if (equals == null) {
+          return new JsLinkedHashMap<K, V>.es6();
+        }
+        hashCode = _defaultHashCode;
+      } else {
+        if (identical(identityHashCode, hashCode) &&
+            identical(identical, equals)) {
+          return new _LinkedIdentityHashMap<K, V>.es6();
+        }
+        if (equals == null) {
+          equals = _defaultEquals;
+        }
+      }
+    } else {
+      if (hashCode == null) {
+        hashCode = _defaultHashCode;
+      }
+      if (equals == null) {
+        equals = _defaultEquals;
+      }
+    }
+    return new _LinkedCustomHashMap<K, V>(equals, hashCode, isValidKey);
+  }
+
+  @patch
+  factory LinkedHashMap.identity() = _LinkedIdentityHashMap<K, V>.es6;
+
+  // Private factory constructor called by generated code for map literals.
+  @pragma('dart2js:noInline')
+  factory LinkedHashMap._literal(List keyValuePairs) {
+    return fillLiteralMap(keyValuePairs, new JsLinkedHashMap<K, V>.es6());
+  }
+
+  // Private factory constructor called by generated code for map literals.
+  @pragma('dart2js:noThrows')
+  @pragma('dart2js:noInline')
+  @pragma('dart2js:noSideEffects')
+  factory LinkedHashMap._empty() {
+    return new JsLinkedHashMap<K, V>.es6();
+  }
+
+  // Private factory static function called by generated code for map literals.
+  // This version is for map literals without type parameters.
+  @pragma('dart2js:noThrows')
+  @pragma('dart2js:noInline')
+  @pragma('dart2js:noSideEffects')
+  static _makeEmpty() => new JsLinkedHashMap();
+
+  // Private factory static function called by generated code for map literals.
+  // This version is for map literals without type parameters.
+  @pragma('dart2js:noInline')
+  static _makeLiteral(keyValuePairs) =>
+      fillLiteralMap(keyValuePairs, new JsLinkedHashMap());
+}
+
+class _LinkedIdentityHashMap<K, V> extends JsLinkedHashMap<K, V> {
+  static bool get _supportsEs6Maps {
+    return JS('returns:bool;depends:none;effects:none;throws:never;gvn:true',
+        'typeof Map != "undefined"');
+  }
+
+  factory _LinkedIdentityHashMap.es6() {
+    return (_USE_ES6_MAPS && _LinkedIdentityHashMap._supportsEs6Maps)
+        ? new _Es6LinkedIdentityHashMap<K, V>()
+        : new _LinkedIdentityHashMap<K, V>();
+  }
+
+  _LinkedIdentityHashMap();
+
+  int internalComputeHashCode(var key) {
+    // We force the hash codes to be unsigned 30-bit integers to avoid
+    // issues with problematic keys like '__proto__'. Another option
+    // would be to throw an exception if the hash code isn't a number.
+    return JS('int', '# & #', identityHashCode(key), _mask30);
+  }
+
+  int internalFindBucketIndex(var bucket, var key) {
+    if (bucket == null) return -1;
+    int length = JS('int', '#.length', bucket);
+    for (int i = 0; i < length; i++) {
+      LinkedHashMapCell cell = JS('var', '#[#]', bucket, i);
+      if (identical(cell.hashMapCellKey, key)) return i;
+    }
+    return -1;
+  }
+}
+
+class _Es6LinkedIdentityHashMap<K, V> extends _LinkedIdentityHashMap<K, V>
+    implements InternalMap {
+  final _map;
+  int _modifications = 0;
+
+  _Es6LinkedIdentityHashMap() : _map = JS('var', 'new Map()');
+
+  int get length => JS('int', '#.size', _map);
+  bool get isEmpty => length == 0;
+  bool get isNotEmpty => !isEmpty;
+
+  Iterable<K> get keys => new _Es6MapIterable<K>(this, true);
+
+  Iterable<V> get values => new _Es6MapIterable<V>(this, false);
+
+  bool containsKey(Object key) {
+    return JS('bool', '#.has(#)', _map, key);
+  }
+
+  bool containsValue(Object value) {
+    return values.any((each) => each == value);
+  }
+
+  void addAll(Map<K, V> other) {
+    other.forEach((K key, V value) {
+      this[key] = value;
+    });
+  }
+
+  V operator [](Object key) {
+    return JS('var', '#.get(#)', _map, key);
+  }
+
+  void operator []=(K key, V value) {
+    JS('var', '#.set(#, #)', _map, key, value);
+    _modified();
+  }
+
+  V putIfAbsent(K key, V ifAbsent()) {
+    if (containsKey(key)) return this[key];
+    V value = ifAbsent();
+    this[key] = value;
+    return value;
+  }
+
+  V remove(Object key) {
+    V value = this[key];
+    JS('bool', '#.delete(#)', _map, key);
+    _modified();
+    return value;
+  }
+
+  void clear() {
+    JS('void', '#.clear()', _map);
+    _modified();
+  }
+
+  void forEach(void action(K key, V value)) {
+    var jsEntries = JS('var', '#.entries()', _map);
+    int modifications = _modifications;
+    while (true) {
+      var next = JS('var', '#.next()', jsEntries);
+      bool done = JS('bool', '#.done', next);
+      if (done) break;
+      var entry = JS('var', '#.value', next);
+      var key = JS('var', '#[0]', entry);
+      var value = JS('var', '#[1]', entry);
+      action(key, value);
+      if (modifications != _modifications) {
+        throw new ConcurrentModificationError(this);
+      }
+    }
+  }
+
+  void _modified() {
+    // Value cycles after 2^30 modifications so that modification counts are
+    // always unboxed (Smi) values. Modification detection will be missed if you
+    // make exactly some multiple of 2^30 modifications between advances of an
+    // iterator.
+    _modifications = _mask30 & (_modifications + 1);
+  }
+}
+
+class _Es6MapIterable<E> extends EfficientLengthIterable<E> {
+  final _map;
+  final bool _isKeys;
+
+  _Es6MapIterable(this._map, this._isKeys);
+
+  int get length => _map.length;
+  bool get isEmpty => _map.isEmpty;
+
+  Iterator<E> get iterator =>
+      new _Es6MapIterator<E>(_map, _map._modifications, _isKeys);
+
+  bool contains(Object element) => _map.containsKey(element);
+
+  void forEach(void f(E element)) {
+    var jsIterator;
+    if (_isKeys) {
+      jsIterator = JS('var', '#.keys()', _map._map);
+    } else {
+      jsIterator = JS('var', '#.values()', _map._map);
+    }
+    int modifications = _map._modifications;
+    while (true) {
+      var next = JS('var', '#.next()', jsIterator);
+      bool done = JS('bool', '#.done', next);
+      if (done) break;
+      var value = JS('var', '#.value', next);
+      f(value);
+      if (modifications != _map._modifications) {
+        throw new ConcurrentModificationError(_map);
+      }
+    }
+  }
+}
+
+class _Es6MapIterator<E> implements Iterator<E> {
+  final _map;
+  final int _modifications;
+  final bool _isKeys;
+  var _jsIterator;
+  var _next;
+  E _current;
+  bool _done;
+
+  _Es6MapIterator(this._map, this._modifications, this._isKeys) {
+    if (_isKeys) {
+      _jsIterator = JS('var', '#.keys()', _map._map);
+    } else {
+      _jsIterator = JS('var', '#.values()', _map._map);
+    }
+    _done = false;
+  }
+
+  E get current => _current;
+
+  bool moveNext() {
+    if (_modifications != _map._modifications) {
+      throw new ConcurrentModificationError(_map);
+    }
+    if (_done) return false;
+    _next = JS('var', '#.next()', _jsIterator);
+    bool done = JS('bool', '#.done', _next);
+    if (done) {
+      _current = null;
+      _done = true;
+      return false;
+    } else {
+      _current = JS('var', '#.value', _next);
+      return true;
+    }
+  }
+}
+
+// TODO(floitsch): use ES6 maps when available.
+class _LinkedCustomHashMap<K, V> extends JsLinkedHashMap<K, V> {
+  final _Equality<K> _equals;
+  final _Hasher<K> _hashCode;
+  final _Predicate _validKey;
+
+  _LinkedCustomHashMap(
+      this._equals, this._hashCode, bool validKey(potentialKey))
+      : _validKey = (validKey != null) ? validKey : ((v) => v is K);
+
+  V operator [](Object key) {
+    if (!_validKey(key)) return null;
+    return super.internalGet(key);
+  }
+
+  void operator []=(K key, V value) {
+    super.internalSet(key, value);
+  }
+
+  bool containsKey(Object key) {
+    if (!_validKey(key)) return false;
+    return super.internalContainsKey(key);
+  }
+
+  V remove(Object key) {
+    if (!_validKey(key)) return null;
+    return super.internalRemove(key);
+  }
+
+  int internalComputeHashCode(var key) {
+    // We force the hash codes to be unsigned 30-bit integers to avoid
+    // issues with problematic keys like '__proto__'. Another option
+    // would be to throw an exception if the hash code isn't a number.
+    return JS('int', '# & #', _hashCode(key), _mask30);
+  }
+
+  int internalFindBucketIndex(var bucket, var key) {
+    if (bucket == null) return -1;
+    int length = JS('int', '#.length', bucket);
+    for (int i = 0; i < length; i++) {
+      LinkedHashMapCell cell = JS('var', '#[#]', bucket, i);
+      if (_equals(cell.hashMapCellKey, key)) return i;
+    }
+    return -1;
+  }
+}
+
+@patch
+class HashSet<E> {
+  @patch
+  factory HashSet(
+      {bool equals(E e1, E e2),
+      int hashCode(E e),
+      bool isValidKey(potentialKey)}) {
+    if (isValidKey == null) {
+      if (hashCode == null) {
+        if (equals == null) {
+          return new _HashSet<E>();
+        }
+        hashCode = _defaultHashCode;
+      } else {
+        if (identical(identityHashCode, hashCode) &&
+            identical(identical, equals)) {
+          return new _IdentityHashSet<E>();
+        }
+        if (equals == null) {
+          equals = _defaultEquals;
+        }
+      }
+    } else {
+      if (hashCode == null) {
+        hashCode = _defaultHashCode;
+      }
+      if (equals == null) {
+        equals = _defaultEquals;
+      }
+    }
+    return new _CustomHashSet<E>(equals, hashCode, isValidKey);
+  }
+
+  @patch
+  factory HashSet.identity() = _IdentityHashSet<E>;
+}
+
+class _HashSet<E> extends _SetBase<E> implements HashSet<E> {
+  int _length = 0;
+
+  // The hash set contents are divided into three parts: one part for
+  // string elements, one for numeric elements, and one for the
+  // rest. String and numeric elements map directly to a sentinel
+  // value, but the rest of the entries are stored in bucket lists of
+  // the form:
+  //
+  //    [element-0, element-1, element-2, ...]
+  //
+  // where all elements in the same bucket share the same hash code.
+  var _strings;
+  var _nums;
+  var _rest;
+
+  // When iterating over the hash set, it is very convenient to have a
+  // list of all the elements. We cache that on the instance and clear
+  // the cache whenever the set changes. This is also used to
+  // guard against concurrent modifications.
+  List _elements;
+
+  _HashSet();
+
+  Set<E> _newSet() => new _HashSet<E>();
+  Set<R> _newSimilarSet<R>() => new _HashSet<R>();
+
+  // Iterable.
+  Iterator<E> get iterator {
+    return new _HashSetIterator<E>(this, _computeElements());
+  }
+
+  int get length => _length;
+  bool get isEmpty => _length == 0;
+  bool get isNotEmpty => !isEmpty;
+
+  bool contains(Object object) {
+    if (_isStringElement(object)) {
+      var strings = _strings;
+      return (strings == null) ? false : _hasTableEntry(strings, object);
+    } else if (_isNumericElement(object)) {
+      var nums = _nums;
+      return (nums == null) ? false : _hasTableEntry(nums, object);
+    } else {
+      return _contains(object);
+    }
+  }
+
+  bool _contains(Object object) {
+    var rest = _rest;
+    if (rest == null) return false;
+    var bucket = _getBucket(rest, object);
+    return _findBucketIndex(bucket, object) >= 0;
+  }
+
+  E lookup(Object object) {
+    if (_isStringElement(object) || _isNumericElement(object)) {
+      return this.contains(object) ? object : null;
+    }
+    return _lookup(object);
+  }
+
+  E _lookup(Object object) {
+    var rest = _rest;
+    if (rest == null) return null;
+    var bucket = _getBucket(rest, object);
+    var index = _findBucketIndex(bucket, object);
+    if (index < 0) return null;
+    return bucket[index];
+  }
+
+  // Collection.
+  bool add(E element) {
+    if (_isStringElement(element)) {
+      var strings = _strings;
+      if (strings == null) _strings = strings = _newHashTable();
+      return _addHashTableEntry(strings, element);
+    } else if (_isNumericElement(element)) {
+      var nums = _nums;
+      if (nums == null) _nums = nums = _newHashTable();
+      return _addHashTableEntry(nums, element);
+    } else {
+      return _add(element);
+    }
+  }
+
+  bool _add(E element) {
+    var rest = _rest;
+    if (rest == null) _rest = rest = _newHashTable();
+    var hash = _computeHashCode(element);
+    var bucket = JS('var', '#[#]', rest, hash);
+    if (bucket == null) {
+      _setTableEntry(rest, hash, JS('var', '[#]', element));
+    } else {
+      int index = _findBucketIndex(bucket, element);
+      if (index >= 0) return false;
+      JS('void', '#.push(#)', bucket, element);
+    }
+    _length++;
+    _elements = null;
+    return true;
+  }
+
+  void addAll(Iterable<E> objects) {
+    for (E each in objects) {
+      add(each);
+    }
+  }
+
+  bool remove(Object object) {
+    if (_isStringElement(object)) {
+      return _removeHashTableEntry(_strings, object);
+    } else if (_isNumericElement(object)) {
+      return _removeHashTableEntry(_nums, object);
+    } else {
+      return _remove(object);
+    }
+  }
+
+  bool _remove(Object object) {
+    var rest = _rest;
+    if (rest == null) return false;
+    var bucket = _getBucket(rest, object);
+    int index = _findBucketIndex(bucket, object);
+    if (index < 0) return false;
+    // TODO(kasperl): Consider getting rid of the bucket list when
+    // the length reaches zero.
+    _length--;
+    _elements = null;
+    // TODO(kasperl): It would probably be faster to move the
+    // element to the end and reduce the length of the bucket list.
+    JS('void', '#.splice(#, 1)', bucket, index);
+    return true;
+  }
+
+  void clear() {
+    if (_length > 0) {
+      _strings = _nums = _rest = _elements = null;
+      _length = 0;
+    }
+  }
+
+  List _computeElements() {
+    if (_elements != null) return _elements;
+    List result = new List(_length);
+    int index = 0;
+
+    // Add all string elements to the list.
+    var strings = _strings;
+    if (strings != null) {
+      var names = JS('var', 'Object.getOwnPropertyNames(#)', strings);
+      int entries = JS('int', '#.length', names);
+      for (int i = 0; i < entries; i++) {
+        String element = JS('String', '#[#]', names, i);
+        JS('void', '#[#] = #', result, index, element);
+        index++;
+      }
+    }
+
+    // Add all numeric elements to the list.
+    var nums = _nums;
+    if (nums != null) {
+      var names = JS('var', 'Object.getOwnPropertyNames(#)', nums);
+      int entries = JS('int', '#.length', names);
+      for (int i = 0; i < entries; i++) {
+        // Object.getOwnPropertyNames returns a list of strings, so we
+        // have to convert the elements back to numbers (+).
+        num element = JS('num', '+#[#]', names, i);
+        JS('void', '#[#] = #', result, index, element);
+        index++;
+      }
+    }
+
+    // Add all the remaining elements to the list.
+    var rest = _rest;
+    if (rest != null) {
+      var names = JS('var', 'Object.getOwnPropertyNames(#)', rest);
+      int entries = JS('int', '#.length', names);
+      for (int i = 0; i < entries; i++) {
+        var entry = JS('String', '#[#]', names, i);
+        var bucket = JS('var', '#[#]', rest, entry);
+        int length = JS('int', '#.length', bucket);
+        for (int i = 0; i < length; i++) {
+          JS('void', '#[#] = #[#]', result, index, bucket, i);
+          index++;
+        }
+      }
+    }
+    assert(index == _length);
+    return _elements = result;
+  }
+
+  bool _addHashTableEntry(var table, E element) {
+    if (_hasTableEntry(table, element)) return false;
+    _setTableEntry(table, element, 0);
+    _length++;
+    _elements = null;
+    return true;
+  }
+
+  bool _removeHashTableEntry(var table, Object element) {
+    if (table != null && _hasTableEntry(table, element)) {
+      _deleteTableEntry(table, element);
+      _length--;
+      _elements = null;
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  static bool _isStringElement(var element) {
+    return element is String && element != '__proto__';
+  }
+
+  static bool _isNumericElement(var element) {
+    // Only treat unsigned 30-bit integers as numeric elements. This
+    // way, we avoid converting them to strings when we use them as
+    // keys in the JavaScript hash table object.
+    return element is num &&
+        JS('bool', '(# & #) === #', element, _mask30, element);
+  }
+
+  int _computeHashCode(var element) {
+    // We force the hash codes to be unsigned 30-bit integers to avoid
+    // issues with problematic elements like '__proto__'. Another
+    // option would be to throw an exception if the hash code isn't a
+    // number.
+    return JS('int', '# & #', element.hashCode, _mask30);
+  }
+
+  static bool _hasTableEntry(var table, var key) {
+    var entry = JS('var', '#[#]', table, key);
+    // We take care to only store non-null entries in the table, so we
+    // can check if the table has an entry for the given key with a
+    // simple null check.
+    return entry != null;
+  }
+
+  static void _setTableEntry(var table, var key, var value) {
+    assert(value != null);
+    JS('void', '#[#] = #', table, key, value);
+  }
+
+  static void _deleteTableEntry(var table, var key) {
+    JS('void', 'delete #[#]', table, key);
+  }
+
+  List _getBucket(var table, var element) {
+    var hash = _computeHashCode(element);
+    return JS('var', '#[#]', table, hash);
+  }
+
+  int _findBucketIndex(var bucket, var element) {
+    if (bucket == null) return -1;
+    int length = JS('int', '#.length', bucket);
+    for (int i = 0; i < length; i++) {
+      if (JS('var', '#[#]', bucket, i) == element) return i;
+    }
+    return -1;
+  }
+
+  static _newHashTable() {
+    // Create a new JavaScript object to be used as a hash table. Use
+    // Object.create to avoid the properties on Object.prototype
+    // showing up as entries.
+    var table = JS('var', 'Object.create(null)');
+    // Attempt to force the hash table into 'dictionary' mode by
+    // adding a property to it and deleting it again.
+    var temporaryKey = '<non-identifier-key>';
+    _setTableEntry(table, temporaryKey, table);
+    _deleteTableEntry(table, temporaryKey);
+    return table;
+  }
+}
+
+class _IdentityHashSet<E> extends _HashSet<E> {
+  Set<E> _newSet() => new _IdentityHashSet<E>();
+  Set<R> _newSimilarSet<R>() => new _IdentityHashSet<R>();
+
+  int _computeHashCode(var key) {
+    // We force the hash codes to be unsigned 30-bit integers to avoid
+    // issues with problematic keys like '__proto__'. Another option
+    // would be to throw an exception if the hash code isn't a number.
+    return JS('int', '# & #', identityHashCode(key), _mask30);
+  }
+
+  int _findBucketIndex(var bucket, var element) {
+    if (bucket == null) return -1;
+    int length = JS('int', '#.length', bucket);
+    for (int i = 0; i < length; i++) {
+      if (identical(JS('var', '#[#]', bucket, i), element)) return i;
+    }
+    return -1;
+  }
+}
+
+class _CustomHashSet<E> extends _HashSet<E> {
+  _Equality<E> _equality;
+  _Hasher<E> _hasher;
+  _Predicate _validKey;
+  _CustomHashSet(this._equality, this._hasher, bool validKey(potentialKey))
+      : _validKey = (validKey != null) ? validKey : ((x) => x is E);
+
+  Set<E> _newSet() => new _CustomHashSet<E>(_equality, _hasher, _validKey);
+  Set<R> _newSimilarSet<R>() => new _HashSet<R>();
+
+  int _findBucketIndex(var bucket, var element) {
+    if (bucket == null) return -1;
+    int length = JS('int', '#.length', bucket);
+    for (int i = 0; i < length; i++) {
+      if (_equality(JS('var', '#[#]', bucket, i), element)) return i;
+    }
+    return -1;
+  }
+
+  int _computeHashCode(var element) {
+    // We force the hash codes to be unsigned 30-bit integers to avoid
+    // issues with problematic elements like '__proto__'. Another
+    // option would be to throw an exception if the hash code isn't a
+    // number.
+    return JS('int', '# & #', _hasher(element), _mask30);
+  }
+
+  bool add(E object) => super._add(object);
+
+  bool contains(Object object) {
+    if (!_validKey(object)) return false;
+    return super._contains(object);
+  }
+
+  E lookup(Object object) {
+    if (!_validKey(object)) return null;
+    return super._lookup(object);
+  }
+
+  bool remove(Object object) {
+    if (!_validKey(object)) return false;
+    return super._remove(object);
+  }
+}
+
+// TODO(kasperl): Share this code with _HashMapKeyIterator<E>?
+class _HashSetIterator<E> implements Iterator<E> {
+  final _set;
+  final List _elements;
+  int _offset = 0;
+  E _current;
+
+  _HashSetIterator(this._set, this._elements);
+
+  E get current => _current;
+
+  bool moveNext() {
+    var elements = _elements;
+    int offset = _offset;
+    if (JS('bool', '# !== #', elements, _set._elements)) {
+      throw new ConcurrentModificationError(_set);
+    } else if (offset >= JS('int', '#.length', elements)) {
+      _current = null;
+      return false;
+    } else {
+      _current = JS('var', '#[#]', elements, offset);
+      // TODO(kasperl): For now, we have to tell the type inferrer to
+      // treat the result of doing offset + 1 as an int. Otherwise, we
+      // get unnecessary bailout code.
+      _offset = JS('int', '#', offset + 1);
+      return true;
+    }
+  }
+}
+
+@patch
+class LinkedHashSet<E> {
+  @patch
+  factory LinkedHashSet(
+      {bool equals(E e1, E e2),
+      int hashCode(E e),
+      bool isValidKey(potentialKey)}) {
+    if (isValidKey == null) {
+      if (hashCode == null) {
+        if (equals == null) {
+          return new _LinkedHashSet<E>();
+        }
+        hashCode = _defaultHashCode;
+      } else {
+        if (identical(identityHashCode, hashCode) &&
+            identical(identical, equals)) {
+          return new _LinkedIdentityHashSet<E>();
+        }
+        if (equals == null) {
+          equals = _defaultEquals;
+        }
+      }
+    } else {
+      if (hashCode == null) {
+        hashCode = _defaultHashCode;
+      }
+      if (equals == null) {
+        equals = _defaultEquals;
+      }
+    }
+    return new _LinkedCustomHashSet<E>(equals, hashCode, isValidKey);
+  }
+
+  @patch
+  factory LinkedHashSet.identity() = _LinkedIdentityHashSet<E>;
+
+  // Private factory constructor called by generated code for set literals.
+  @pragma('dart2js:noThrows')
+  @pragma('dart2js:noInline')
+  @pragma('dart2js:noSideEffects')
+  factory LinkedHashSet._empty() => new _LinkedHashSet<E>();
+
+  // Private factory constructor called by generated code for set literals.
+  @pragma('dart2js:noInline')
+  factory LinkedHashSet._literal(List values) =>
+      fillLiteralSet(values, new _LinkedHashSet<E>());
+
+  // Private factory static function called by generated code for set literals.
+  // This version is for set literals without type parameters.
+  @pragma('dart2js:noThrows')
+  @pragma('dart2js:noInline')
+  @pragma('dart2js:noSideEffects')
+  static _makeEmpty() => new _LinkedHashSet();
+
+  // Private factory static function called by generated code for set literals.
+  // This version is for set literals without type parameters.
+  @pragma('dart2js:noInline')
+  static _makeLiteral(List values) =>
+      fillLiteralSet(values, new _LinkedHashSet());
+}
+
+class _LinkedHashSet<E> extends _SetBase<E> implements LinkedHashSet<E> {
+  int _length = 0;
+
+  // The hash set contents are divided into three parts: one part for
+  // string elements, one for numeric elements, and one for the
+  // rest. String and numeric elements map directly to their linked
+  // cells, but the rest of the entries are stored in bucket lists of
+  // the form:
+  //
+  //    [cell-0, cell-1, ...]
+  //
+  // where all elements in the same bucket share the same hash code.
+  var _strings;
+  var _nums;
+  var _rest;
+
+  // The elements are stored in cells that are linked together
+  // to form a double linked list.
+  _LinkedHashSetCell _first;
+  _LinkedHashSetCell _last;
+
+  // We track the number of modifications done to the element set to
+  // be able to throw when the set is modified while being iterated
+  // over.
+  int _modifications = 0;
+
+  _LinkedHashSet();
+
+  Set<E> _newSet() => new _LinkedHashSet<E>();
+  Set<R> _newSimilarSet<R>() => new _LinkedHashSet<R>();
+
+  void _unsupported(String operation) {
+    throw 'LinkedHashSet: unsupported $operation';
+  }
+
+  // Iterable.
+  Iterator<E> get iterator {
+    return new _LinkedHashSetIterator(this, _modifications);
+  }
+
+  int get length => _length;
+  bool get isEmpty => _length == 0;
+  bool get isNotEmpty => !isEmpty;
+
+  bool contains(Object object) {
+    if (_isStringElement(object)) {
+      var strings = _strings;
+      if (strings == null) return false;
+      _LinkedHashSetCell cell = _getTableEntry(strings, object);
+      return cell != null;
+    } else if (_isNumericElement(object)) {
+      var nums = _nums;
+      if (nums == null) return false;
+      _LinkedHashSetCell cell = _getTableEntry(nums, object);
+      return cell != null;
+    } else {
+      return _contains(object);
+    }
+  }
+
+  bool _contains(Object object) {
+    var rest = _rest;
+    if (rest == null) return false;
+    var bucket = _getBucket(rest, object);
+    return _findBucketIndex(bucket, object) >= 0;
+  }
+
+  E lookup(Object object) {
+    if (_isStringElement(object) || _isNumericElement(object)) {
+      return this.contains(object) ? object : null;
+    } else {
+      return _lookup(object);
+    }
+  }
+
+  E _lookup(Object object) {
+    var rest = _rest;
+    if (rest == null) return null;
+    var bucket = _getBucket(rest, object);
+    var index = _findBucketIndex(bucket, object);
+    if (index < 0) return null;
+    return bucket[index]._element;
+  }
+
+  void forEach(void action(E element)) {
+    _LinkedHashSetCell cell = _first;
+    int modifications = _modifications;
+    while (cell != null) {
+      action(cell._element);
+      if (modifications != _modifications) {
+        throw new ConcurrentModificationError(this);
+      }
+      cell = cell._next;
+    }
+  }
+
+  E get first {
+    if (_first == null) throw new StateError("No elements");
+    return _first._element;
+  }
+
+  E get last {
+    if (_last == null) throw new StateError("No elements");
+    return _last._element;
+  }
+
+  // Collection.
+  bool add(E element) {
+    if (_isStringElement(element)) {
+      var strings = _strings;
+      if (strings == null) _strings = strings = _newHashTable();
+      return _addHashTableEntry(strings, element);
+    } else if (_isNumericElement(element)) {
+      var nums = _nums;
+      if (nums == null) _nums = nums = _newHashTable();
+      return _addHashTableEntry(nums, element);
+    } else {
+      return _add(element);
+    }
+  }
+
+  bool _add(E element) {
+    var rest = _rest;
+    if (rest == null) _rest = rest = _newHashTable();
+    var hash = _computeHashCode(element);
+    var bucket = JS('var', '#[#]', rest, hash);
+    if (bucket == null) {
+      _LinkedHashSetCell cell = _newLinkedCell(element);
+      _setTableEntry(rest, hash, JS('var', '[#]', cell));
+    } else {
+      int index = _findBucketIndex(bucket, element);
+      if (index >= 0) return false;
+      _LinkedHashSetCell cell = _newLinkedCell(element);
+      JS('void', '#.push(#)', bucket, cell);
+    }
+    return true;
+  }
+
+  bool remove(Object object) {
+    if (_isStringElement(object)) {
+      return _removeHashTableEntry(_strings, object);
+    } else if (_isNumericElement(object)) {
+      return _removeHashTableEntry(_nums, object);
+    } else {
+      return _remove(object);
+    }
+  }
+
+  bool _remove(Object object) {
+    var rest = _rest;
+    if (rest == null) return false;
+    var bucket = _getBucket(rest, object);
+    int index = _findBucketIndex(bucket, object);
+    if (index < 0) return false;
+    // Use splice to remove the [cell] element at the index and
+    // unlink it.
+    _LinkedHashSetCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index);
+    _unlinkCell(cell);
+    return true;
+  }
+
+  void removeWhere(bool test(E element)) {
+    _filterWhere(test, true);
+  }
+
+  void retainWhere(bool test(E element)) {
+    _filterWhere(test, false);
+  }
+
+  void _filterWhere(bool test(E element), bool removeMatching) {
+    _LinkedHashSetCell cell = _first;
+    while (cell != null) {
+      E element = cell._element;
+      _LinkedHashSetCell next = cell._next;
+      int modifications = _modifications;
+      bool shouldRemove = (removeMatching == test(element));
+      if (modifications != _modifications) {
+        throw new ConcurrentModificationError(this);
+      }
+      if (shouldRemove) remove(element);
+      cell = next;
+    }
+  }
+
+  void clear() {
+    if (_length > 0) {
+      _strings = _nums = _rest = _first = _last = null;
+      _length = 0;
+      _modified();
+    }
+  }
+
+  bool _addHashTableEntry(var table, E element) {
+    _LinkedHashSetCell cell = _getTableEntry(table, element);
+    if (cell != null) return false;
+    _setTableEntry(table, element, _newLinkedCell(element));
+    return true;
+  }
+
+  bool _removeHashTableEntry(var table, Object element) {
+    if (table == null) return false;
+    _LinkedHashSetCell cell = _getTableEntry(table, element);
+    if (cell == null) return false;
+    _unlinkCell(cell);
+    _deleteTableEntry(table, element);
+    return true;
+  }
+
+  void _modified() {
+    // Value cycles after 2^30 modifications. If you keep hold of an
+    // iterator for that long, you might miss a modification
+    // detection, and iteration can go sour. Don't do that.
+    _modifications = _mask30 & (_modifications + 1);
+  }
+
+  // Create a new cell and link it in as the last one in the list.
+  _LinkedHashSetCell _newLinkedCell(E element) {
+    _LinkedHashSetCell cell = new _LinkedHashSetCell(element);
+    if (_first == null) {
+      _first = _last = cell;
+    } else {
+      _LinkedHashSetCell last = _last;
+      cell._previous = last;
+      _last = last._next = cell;
+    }
+    _length++;
+    _modified();
+    return cell;
+  }
+
+  // Unlink the given cell from the linked list of cells.
+  void _unlinkCell(_LinkedHashSetCell cell) {
+    _LinkedHashSetCell previous = cell._previous;
+    _LinkedHashSetCell next = cell._next;
+    if (previous == null) {
+      assert(cell == _first);
+      _first = next;
+    } else {
+      previous._next = next;
+    }
+    if (next == null) {
+      assert(cell == _last);
+      _last = previous;
+    } else {
+      next._previous = previous;
+    }
+    _length--;
+    _modified();
+  }
+
+  static bool _isStringElement(var element) {
+    return element is String && element != '__proto__';
+  }
+
+  static bool _isNumericElement(var element) {
+    // Only treat unsigned 30-bit integers as numeric elements. This
+    // way, we avoid converting them to strings when we use them as
+    // keys in the JavaScript hash table object.
+    return element is num &&
+        JS('bool', '(# & #) === #', element, _mask30, element);
+  }
+
+  int _computeHashCode(var element) {
+    // We force the hash codes to be unsigned 30-bit integers to avoid
+    // issues with problematic elements like '__proto__'. Another
+    // option would be to throw an exception if the hash code isn't a
+    // number.
+    return JS('int', '# & #', element.hashCode, _mask30);
+  }
+
+  static _getTableEntry(var table, var key) {
+    return JS('var', '#[#]', table, key);
+  }
+
+  static void _setTableEntry(var table, var key, var value) {
+    assert(value != null);
+    JS('void', '#[#] = #', table, key, value);
+  }
+
+  static void _deleteTableEntry(var table, var key) {
+    JS('void', 'delete #[#]', table, key);
+  }
+
+  List _getBucket(var table, var element) {
+    var hash = _computeHashCode(element);
+    return JS('var', '#[#]', table, hash);
+  }
+
+  int _findBucketIndex(var bucket, var element) {
+    if (bucket == null) return -1;
+    int length = JS('int', '#.length', bucket);
+    for (int i = 0; i < length; i++) {
+      _LinkedHashSetCell cell = JS('var', '#[#]', bucket, i);
+      if (cell._element == element) return i;
+    }
+    return -1;
+  }
+
+  static _newHashTable() {
+    // Create a new JavaScript object to be used as a hash table. Use
+    // Object.create to avoid the properties on Object.prototype
+    // showing up as entries.
+    var table = JS('var', 'Object.create(null)');
+    // Attempt to force the hash table into 'dictionary' mode by
+    // adding a property to it and deleting it again.
+    var temporaryKey = '<non-identifier-key>';
+    _setTableEntry(table, temporaryKey, table);
+    _deleteTableEntry(table, temporaryKey);
+    return table;
+  }
+}
+
+class _LinkedIdentityHashSet<E> extends _LinkedHashSet<E> {
+  Set<E> _newSet() => new _LinkedIdentityHashSet<E>();
+  Set<R> _newSimilarSet<R>() => new _LinkedIdentityHashSet<R>();
+
+  int _computeHashCode(var key) {
+    // We force the hash codes to be unsigned 30-bit integers to avoid
+    // issues with problematic keys like '__proto__'. Another option
+    // would be to throw an exception if the hash code isn't a number.
+    return JS('int', '# & #', identityHashCode(key), _mask30);
+  }
+
+  int _findBucketIndex(var bucket, var element) {
+    if (bucket == null) return -1;
+    int length = JS('int', '#.length', bucket);
+    for (int i = 0; i < length; i++) {
+      _LinkedHashSetCell cell = JS('var', '#[#]', bucket, i);
+      if (identical(cell._element, element)) return i;
+    }
+    return -1;
+  }
+}
+
+class _LinkedCustomHashSet<E> extends _LinkedHashSet<E> {
+  _Equality<E> _equality;
+  _Hasher<E> _hasher;
+  _Predicate _validKey;
+  _LinkedCustomHashSet(
+      this._equality, this._hasher, bool validKey(potentialKey))
+      : _validKey = (validKey != null) ? validKey : ((x) => x is E);
+
+  Set<E> _newSet() =>
+      new _LinkedCustomHashSet<E>(_equality, _hasher, _validKey);
+  Set<R> _newSimilarSet<R>() => new _LinkedHashSet<R>();
+
+  int _findBucketIndex(var bucket, var element) {
+    if (bucket == null) return -1;
+    int length = JS('int', '#.length', bucket);
+    for (int i = 0; i < length; i++) {
+      _LinkedHashSetCell cell = JS('var', '#[#]', bucket, i);
+      if (_equality(cell._element, element)) return i;
+    }
+    return -1;
+  }
+
+  int _computeHashCode(var element) {
+    // We force the hash codes to be unsigned 30-bit integers to avoid
+    // issues with problematic elements like '__proto__'. Another
+    // option would be to throw an exception if the hash code isn't a
+    // number.
+    return JS('int', '# & #', _hasher(element), _mask30);
+  }
+
+  bool add(E element) => super._add(element);
+
+  bool contains(Object object) {
+    if (!_validKey(object)) return false;
+    return super._contains(object);
+  }
+
+  E lookup(Object object) {
+    if (!_validKey(object)) return null;
+    return super._lookup(object);
+  }
+
+  bool remove(Object object) {
+    if (!_validKey(object)) return false;
+    return super._remove(object);
+  }
+
+  bool containsAll(Iterable<Object> elements) {
+    for (Object element in elements) {
+      if (!_validKey(element) || !this.contains(element)) return false;
+    }
+    return true;
+  }
+
+  void removeAll(Iterable<Object> elements) {
+    for (Object element in elements) {
+      if (_validKey(element)) {
+        super._remove(element);
+      }
+    }
+  }
+}
+
+class _LinkedHashSetCell {
+  final _element;
+
+  _LinkedHashSetCell _next;
+  _LinkedHashSetCell _previous;
+
+  _LinkedHashSetCell(this._element);
+}
+
+// TODO(kasperl): Share this code with LinkedHashMapKeyIterator<E>?
+class _LinkedHashSetIterator<E> implements Iterator<E> {
+  final _set;
+  final int _modifications;
+  _LinkedHashSetCell _cell;
+  E _current;
+
+  _LinkedHashSetIterator(this._set, this._modifications) {
+    _cell = _set._first;
+  }
+
+  E get current => _current;
+
+  bool moveNext() {
+    if (_modifications != _set._modifications) {
+      throw new ConcurrentModificationError(_set);
+    } else if (_cell == null) {
+      _current = null;
+      return false;
+    } else {
+      _current = _cell._element;
+      _cell = _cell._next;
+      return true;
+    }
+  }
+}
+
+@patch
+abstract class _SplayTree<K, Node extends _SplayTreeNode<K>> {
+  @patch
+  Node _splayMin(Node node) {
+    Node current = node;
+    while (current.left != null) {
+      Node left = current.left;
+      current.left = left.right;
+      left.right = current;
+      current = left;
+    }
+    return current;
+  }
+
+  @patch
+  Node _splayMax(Node node) {
+    Node current = node;
+    while (current.right != null) {
+      Node right = current.right;
+      current.right = right.left;
+      right.left = current;
+      current = right;
+    }
+    return current;
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/constant_map.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/constant_map.dart
new file mode 100644
index 0000000..f7c7936
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/constant_map.dart
@@ -0,0 +1,222 @@
+// Copyright (c) 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 _js_helper;
+
+class ConstantMapView<K, V> extends UnmodifiableMapView<K, V>
+    implements ConstantMap<K, V> {
+  ConstantMapView(Map<K, V> base) : super(base);
+}
+
+abstract class ConstantMap<K, V> implements Map<K, V> {
+  // Used to create unmodifiable maps from other maps.
+  factory ConstantMap.from(Map other) {
+    List keys = new List<K>.from(other.keys);
+    bool allStrings = true;
+    for (var k in keys) {
+      if (k is! String) {
+        allStrings = false;
+        break;
+      }
+    }
+    if (allStrings) {
+      bool containsProto = false;
+      var protoValue = null;
+      var object = JS('=Object', '{}');
+      int length = 0;
+      for (var k in keys) {
+        V v = other[k];
+        if (k != '__proto__') {
+          if (!jsHasOwnProperty(object, k)) length++;
+          JS('void', '#[#] = #', object, k, v);
+        } else {
+          containsProto = true;
+          protoValue = v;
+        }
+      }
+      if (containsProto) {
+        length++;
+        return new ConstantProtoMap<K, V>._(length, object, keys, protoValue);
+      }
+      return new ConstantStringMap<K, V>._(length, object, keys);
+    }
+    // TODO(lrn): Make a proper unmodifiable map implementation.
+    return new ConstantMapView<K, V>(new Map.from(other));
+  }
+
+  const ConstantMap._();
+
+  Map<RK, RV> cast<RK, RV>() => Map.castFrom<K, V, RK, RV>(this);
+  bool get isEmpty => length == 0;
+
+  bool get isNotEmpty => !isEmpty;
+
+  String toString() => MapBase.mapToString(this);
+
+  static Null _throwUnmodifiable() {
+    throw new UnsupportedError('Cannot modify unmodifiable Map');
+  }
+
+  void operator []=(K key, V val) => _throwUnmodifiable();
+  V putIfAbsent(K key, V ifAbsent()) => _throwUnmodifiable();
+  V remove(Object key) => _throwUnmodifiable();
+  void clear() => _throwUnmodifiable();
+  void addAll(Map<K, V> other) => _throwUnmodifiable();
+
+  Iterable<MapEntry<K, V>> get entries sync* {
+    for (var key in keys) yield new MapEntry<K, V>(key, this[key]);
+  }
+
+  void addEntries(Iterable<MapEntry<K, V>> entries) {
+    for (var entry in entries) this[entry.key] = entry.value;
+  }
+
+  Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> transform(K key, V value)) {
+    var result = <K2, V2>{};
+    this.forEach((K key, V value) {
+      var entry = transform(key, value);
+      result[entry.key] = entry.value;
+    });
+    return result;
+  }
+
+  V update(K key, V update(V value), {V ifAbsent()}) {
+    _throwUnmodifiable();
+  }
+
+  void updateAll(V update(K key, V value)) {
+    _throwUnmodifiable();
+  }
+
+  void removeWhere(bool test(K key, V value)) {
+    _throwUnmodifiable();
+  }
+}
+
+class ConstantStringMap<K, V> extends ConstantMap<K, V> {
+  // This constructor is not used for actual compile-time constants.
+  // The instantiation of constant maps is shortcut by the compiler.
+  const ConstantStringMap._(this._length, this._jsObject, this._keys)
+      : super._();
+
+  // TODO(18131): Ensure type inference knows the precise types of the fields.
+  final int _length;
+  // A constant map is backed by a JavaScript object.
+  final _jsObject;
+  final List<K> _keys;
+
+  int get length => JS('JSUInt31', '#', _length);
+  List<K> get _keysArray => JS('JSUnmodifiableArray', '#', _keys);
+
+  bool containsValue(Object needle) {
+    return values.any((V value) => value == needle);
+  }
+
+  bool containsKey(Object key) {
+    if (key is! String) return false;
+    if ('__proto__' == key) return false;
+    return jsHasOwnProperty(_jsObject, key);
+  }
+
+  V operator [](Object key) {
+    if (!containsKey(key)) return null;
+    return JS('', '#', _fetch(key));
+  }
+
+  // [_fetch] is the indexer for keys for which `containsKey(key)` is true.
+  _fetch(key) => jsPropertyAccess(_jsObject, key);
+
+  void forEach(void f(K key, V value)) {
+    // Use a JS 'cast' to get efficient loop.  Type inference doesn't get this
+    // since constant map representation is chosen after type inference and the
+    // instantiation is shortcut by the compiler.
+    var keys = _keysArray;
+    for (int i = 0; i < keys.length; i++) {
+      var key = keys[i];
+      f(key, _fetch(key));
+    }
+  }
+
+  Iterable<K> get keys {
+    return new _ConstantMapKeyIterable<K>(this);
+  }
+
+  Iterable<V> get values {
+    return new MappedIterable<K, V>(_keysArray, (key) => _fetch(key));
+  }
+}
+
+class ConstantProtoMap<K, V> extends ConstantStringMap<K, V> {
+  // This constructor is not used.  The instantiation is shortcut by the
+  // compiler. It is here to make the uninitialized final fields legal.
+  ConstantProtoMap._(length, jsObject, keys, this._protoValue)
+      : super._(length, jsObject, keys);
+
+  final V _protoValue;
+
+  bool containsKey(Object key) {
+    if (key is! String) return false;
+    if ('__proto__' == key) return true;
+    return jsHasOwnProperty(_jsObject, key);
+  }
+
+  _fetch(key) =>
+      '__proto__' == key ? _protoValue : jsPropertyAccess(_jsObject, key);
+}
+
+class _ConstantMapKeyIterable<K> extends Iterable<K> {
+  ConstantStringMap<K, dynamic> _map;
+  _ConstantMapKeyIterable(this._map);
+
+  Iterator<K> get iterator => _map._keysArray.iterator;
+
+  int get length => _map._keysArray.length;
+}
+
+class GeneralConstantMap<K, V> extends ConstantMap<K, V> {
+  // This constructor is not used.  The instantiation is shortcut by the
+  // compiler. It is here to make the uninitialized final fields legal.
+  GeneralConstantMap(this._jsData) : super._();
+
+  // [_jsData] holds a key-value pair list.
+  final _jsData;
+
+  // We cannot create the backing map on creation since hashCode interceptors
+  // have not been defined when constants are created.
+  Map<K, V> _getMap() {
+    LinkedHashMap<K, V> backingMap = JS('LinkedHashMap|Null', r'#.$map', this);
+    if (backingMap == null) {
+      backingMap = new JsLinkedHashMap<K, V>();
+      fillLiteralMap(_jsData, backingMap);
+      JS('', r'#.$map = #', this, backingMap);
+    }
+    return backingMap;
+  }
+
+  bool containsValue(Object needle) {
+    return _getMap().containsValue(needle);
+  }
+
+  bool containsKey(Object key) {
+    return _getMap().containsKey(key);
+  }
+
+  V operator [](Object key) {
+    return _getMap()[key];
+  }
+
+  void forEach(void f(K key, V value)) {
+    _getMap().forEach(f);
+  }
+
+  Iterable<K> get keys {
+    return _getMap().keys;
+  }
+
+  Iterable<V> get values {
+    return _getMap().values;
+  }
+
+  int get length => _getMap().length;
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart
new file mode 100644
index 0000000..fa6a0b0
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart
@@ -0,0 +1,502 @@
+// 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.
+
+// Patch file for dart:convert library.
+
+import 'dart:_js_helper' show argumentErrorValue, patch;
+import 'dart:_foreign_helper' show JS;
+import 'dart:_interceptors' show JSArray, JSExtendableArray;
+import 'dart:_internal' show MappedIterable, ListIterable;
+import 'dart:collection' show LinkedHashMap, MapBase;
+import 'dart:_native_typed_data' show NativeUint8List;
+
+/// Parses [json] and builds the corresponding parsed JSON value.
+///
+/// Parsed JSON values Nare of the types [num], [String], [bool], [Null],
+/// [List]s of parsed JSON values or [Map]s from [String] to parsed
+/// JSON values.
+///
+/// The optional [reviver] function, if provided, is called once for each object
+/// or list property parsed. The arguments are the property name ([String]) or
+/// list index ([int]), and the value is the parsed value.  The return value of
+/// the reviver will be used as the value of that property instead of the parsed
+/// value.  The top level value is passed to the reviver with the empty string
+/// as a key.
+///
+/// Throws [FormatException] if the input is not valid JSON text.
+@patch
+_parseJson(String source, reviver(key, value)) {
+  if (source is! String) throw argumentErrorValue(source);
+
+  var parsed;
+  try {
+    parsed = JS('=Object|JSExtendableArray|Null|bool|num|String',
+        'JSON.parse(#)', source);
+  } catch (e) {
+    throw new FormatException(JS('String', 'String(#)', e));
+  }
+
+  if (reviver == null) {
+    return _convertJsonToDartLazy(parsed);
+  } else {
+    return _convertJsonToDart(parsed, reviver);
+  }
+}
+
+/// Walks the raw JavaScript value [json], replacing JavaScript Objects with
+/// Maps. [json] is expected to be freshly allocated so elements can be replaced
+/// in-place.
+_convertJsonToDart(json, reviver(key, value)) {
+  assert(reviver != null);
+  walk(e) {
+    // JavaScript null, string, number, bool are in the correct representation.
+    if (JS('bool', '# == null', e) || JS('bool', 'typeof # != "object"', e)) {
+      return e;
+    }
+
+    // This test is needed to avoid identifying '{"__proto__":[]}' as an Array.
+    // TODO(sra): Replace this test with cheaper '#.constructor === Array' when
+    // bug 621 below is fixed.
+    if (JS('bool', 'Object.getPrototypeOf(#) === Array.prototype', e)) {
+      // In-place update of the elements since JS Array is a Dart List.
+      for (int i = 0; i < JS('int', '#.length', e); i++) {
+        // Use JS indexing to avoid range checks.  We know this is the only
+        // reference to the list, but the compiler will likely never be able to
+        // tell that this instance of the list cannot have its length changed by
+        // the reviver even though it later will be passed to the reviver at the
+        // outer level.
+        var item = JS('', '#[#]', e, i);
+        JS('', '#[#]=#', e, i, reviver(i, walk(item)));
+      }
+      return e;
+    }
+
+    // Otherwise it is a plain object, so copy to a JSON map, so we process
+    // and revive all entries recursively.
+    _JsonMap map = new _JsonMap(e);
+    var processed = map._processed;
+    List<String> keys = map._computeKeys();
+    for (int i = 0; i < keys.length; i++) {
+      String key = keys[i];
+      var revived = reviver(key, walk(JS('', '#[#]', e, key)));
+      JS('', '#[#]=#', processed, key, revived);
+    }
+
+    // Update the JSON map structure so future access is cheaper.
+    map._original = processed; // Don't keep two objects around.
+    return map;
+  }
+
+  return reviver(null, walk(json));
+}
+
+_convertJsonToDartLazy(object) {
+  // JavaScript null and undefined are represented as null.
+  if (object == null) return null;
+
+  // JavaScript string, number, bool already has the correct representation.
+  if (JS('bool', 'typeof # != "object"', object)) {
+    return object;
+  }
+
+  // This test is needed to avoid identifying '{"__proto__":[]}' as an array.
+  // TODO(sra): Replace this test with cheaper '#.constructor === Array' when
+  // bug https://code.google.com/p/v8/issues/detail?id=621 is fixed.
+  if (JS('bool', 'Object.getPrototypeOf(#) !== Array.prototype', object)) {
+    return new _JsonMap(object);
+  }
+
+  // Update the elements in place since JS arrays are Dart lists.
+  for (int i = 0; i < JS('int', '#.length', object); i++) {
+    // Use JS indexing to avoid range checks.  We know this is the only
+    // reference to the list, but the compiler will likely never be able to
+    // tell that this instance of the list cannot have its length changed by
+    // the reviver even though it later will be passed to the reviver at the
+    // outer level.
+    var item = JS('', '#[#]', object, i);
+    JS('', '#[#]=#', object, i, _convertJsonToDartLazy(item));
+  }
+  return object;
+}
+
+class _JsonMap extends MapBase<String, dynamic> {
+  // The original JavaScript object remains unchanged until
+  // the map is eventually upgraded, in which case we null it
+  // out to reclaim the memory used by it.
+  var _original;
+
+  // We keep track of the map entries that we have already
+  // processed by adding them to a separate JavaScript object.
+  var _processed = _newJavaScriptObject();
+
+  // If the data slot isn't null, it represents either the list
+  // of keys (for non-upgraded JSON maps) or the upgraded map.
+  var _data = null;
+
+  _JsonMap(this._original);
+
+  operator [](key) {
+    if (_isUpgraded) {
+      return _upgradedMap[key];
+    } else if (key is! String) {
+      return null;
+    } else {
+      var result = _getProperty(_processed, key);
+      if (_isUnprocessed(result)) result = _process(key);
+      return result;
+    }
+  }
+
+  int get length => _isUpgraded ? _upgradedMap.length : _computeKeys().length;
+
+  bool get isEmpty => length == 0;
+  bool get isNotEmpty => length > 0;
+
+  Iterable<String> get keys {
+    if (_isUpgraded) return _upgradedMap.keys;
+    return new _JsonMapKeyIterable(this);
+  }
+
+  Iterable get values {
+    if (_isUpgraded) return _upgradedMap.values;
+    return new MappedIterable(_computeKeys(), (each) => this[each]);
+  }
+
+  operator []=(key, value) {
+    if (_isUpgraded) {
+      _upgradedMap[key] = value;
+    } else if (containsKey(key)) {
+      var processed = _processed;
+      _setProperty(processed, key, value);
+      var original = _original;
+      if (!identical(original, processed)) {
+        _setProperty(original, key, null); // Reclaim memory.
+      }
+    } else {
+      _upgrade()[key] = value;
+    }
+  }
+
+  void addAll(Map<String, dynamic> other) {
+    other.forEach((key, value) {
+      this[key] = value;
+    });
+  }
+
+  bool containsValue(value) {
+    if (_isUpgraded) return _upgradedMap.containsValue(value);
+    List<String> keys = _computeKeys();
+    for (int i = 0; i < keys.length; i++) {
+      String key = keys[i];
+      if (this[key] == value) return true;
+    }
+    return false;
+  }
+
+  bool containsKey(key) {
+    if (_isUpgraded) return _upgradedMap.containsKey(key);
+    if (key is! String) return false;
+    return _hasProperty(_original, key);
+  }
+
+  putIfAbsent(key, ifAbsent()) {
+    if (containsKey(key)) return this[key];
+    var value = ifAbsent();
+    this[key] = value;
+    return value;
+  }
+
+  remove(Object key) {
+    if (!_isUpgraded && !containsKey(key)) return null;
+    return _upgrade().remove(key);
+  }
+
+  void clear() {
+    if (_isUpgraded) {
+      _upgradedMap.clear();
+    } else {
+      if (_data != null) {
+        // Clear the list of keys to make sure we force
+        // a concurrent modification error if anyone is
+        // currently iterating over it.
+        _data.clear();
+      }
+      _original = _processed = null;
+      _data = {};
+    }
+  }
+
+  void forEach(void f(String key, value)) {
+    if (_isUpgraded) return _upgradedMap.forEach(f);
+    List<String> keys = _computeKeys();
+    for (int i = 0; i < keys.length; i++) {
+      String key = keys[i];
+
+      // Compute the value under the assumption that the property
+      // is present but potentially not processed.
+      var value = _getProperty(_processed, key);
+      if (_isUnprocessed(value)) {
+        value = _convertJsonToDartLazy(_getProperty(_original, key));
+        _setProperty(_processed, key, value);
+      }
+
+      // Do the callback.
+      f(key, value);
+
+      // Check if invoking the callback function changed
+      // the key set. If so, throw an exception.
+      if (!identical(keys, _data)) {
+        throw new ConcurrentModificationError(this);
+      }
+    }
+  }
+
+  // ------------------------------------------
+  // Private helper methods.
+  // ------------------------------------------
+
+  bool get _isUpgraded => _processed == null;
+
+  Map<String, dynamic> get _upgradedMap {
+    assert(_isUpgraded);
+    // 'cast' the union type to LinkedHashMap.  It would be even better if we
+    // could 'cast' to the implementation type, since LinkedHashMap includes
+    // _JsonMap.
+    return JS('LinkedHashMap', '#', _data);
+  }
+
+  List<String> _computeKeys() {
+    assert(!_isUpgraded);
+    List keys = _data;
+    if (keys == null) {
+      keys = _data = new JSArray<String>.typed(_getPropertyNames(_original));
+    }
+    return JS('JSExtendableArray', '#', keys);
+  }
+
+  Map<String, dynamic> _upgrade() {
+    if (_isUpgraded) return _upgradedMap;
+
+    // Copy all the (key, value) pairs to a freshly allocated
+    // linked hash map thus preserving the ordering.
+    var result = <String, dynamic>{};
+    List<String> keys = _computeKeys();
+    for (int i = 0; i < keys.length; i++) {
+      String key = keys[i];
+      result[key] = this[key];
+    }
+
+    // We only upgrade when we need to extend the map, so we can
+    // safely force a concurrent modification error in case
+    // someone is iterating over the map here.
+    if (keys.isEmpty) {
+      keys.add(null);
+    } else {
+      keys.clear();
+    }
+
+    // Clear out the associated JavaScript objects and mark the
+    // map as having been upgraded.
+    _original = _processed = null;
+    _data = result;
+    assert(_isUpgraded);
+    return result;
+  }
+
+  _process(String key) {
+    if (!_hasProperty(_original, key)) return null;
+    var result = _convertJsonToDartLazy(_getProperty(_original, key));
+    return _setProperty(_processed, key, result);
+  }
+
+  // ------------------------------------------
+  // Private JavaScript helper methods.
+  // ------------------------------------------
+
+  static bool _hasProperty(object, String key) =>
+      JS('bool', 'Object.prototype.hasOwnProperty.call(#,#)', object, key);
+  static _getProperty(object, String key) => JS('', '#[#]', object, key);
+  static _setProperty(object, String key, value) =>
+      JS('', '#[#]=#', object, key, value);
+  static List _getPropertyNames(object) =>
+      JS('JSExtendableArray', 'Object.keys(#)', object);
+  static bool _isUnprocessed(object) =>
+      JS('bool', 'typeof(#)=="undefined"', object);
+  static _newJavaScriptObject() => JS('=Object', 'Object.create(null)');
+}
+
+class _JsonMapKeyIterable extends ListIterable<String> {
+  final _JsonMap _parent;
+
+  _JsonMapKeyIterable(this._parent);
+
+  int get length => _parent.length;
+
+  String elementAt(int index) {
+    return _parent._isUpgraded
+        ? _parent.keys.elementAt(index)
+        : _parent._computeKeys()[index];
+  }
+
+  /// Although [ListIterable] defines its own iterator, we return the iterator
+  /// of the underlying list [_keys] in order to propagate
+  /// [ConcurrentModificationError]s.
+  Iterator<String> get iterator {
+    return _parent._isUpgraded
+        ? _parent.keys.iterator
+        : _parent._computeKeys().iterator;
+  }
+
+  /// Delegate to [parent.containsKey] to ensure the performance expected
+  /// from [Map.keys.containsKey].
+  bool contains(Object key) => _parent.containsKey(key);
+}
+
+@patch
+class JsonDecoder {
+  @patch
+  StringConversionSink startChunkedConversion(Sink<Object> sink) {
+    return new _JsonDecoderSink(_reviver, sink);
+  }
+}
+
+/// Implements the chunked conversion from a JSON string to its corresponding
+/// object.
+///
+/// The sink only creates one object, but its input can be chunked.
+// TODO(floitsch): don't accumulate everything before starting to decode.
+class _JsonDecoderSink extends _StringSinkConversionSink {
+  final Function(Object key, Object value) _reviver;
+  final Sink<Object> _sink;
+
+  _JsonDecoderSink(this._reviver, this._sink) : super(new StringBuffer(''));
+
+  void close() {
+    super.close();
+    StringBuffer buffer = _stringSink;
+    String accumulated = buffer.toString();
+    buffer.clear();
+    Object decoded = _parseJson(accumulated, _reviver);
+    _sink.add(decoded);
+    _sink.close();
+  }
+}
+
+@patch
+class Utf8Decoder {
+  @patch
+  Converter<List<int>, T> fuse<T>(Converter<String, T> next) {
+    return super.fuse(next);
+  }
+
+  @patch
+  static String _convertIntercepted(
+      bool allowMalformed, List<int> codeUnits, int start, int end) {
+    // Test `codeUnits is NativeUint8List`. Dart's NativeUint8List is
+    // implemented by JavaScript's Uint8Array.
+    if (JS('bool', '# instanceof Uint8Array', codeUnits)) {
+      // JS 'cast' to avoid a downcast equivalent to the is-check we hand-coded.
+      NativeUint8List casted = JS('NativeUint8List', '#', codeUnits);
+      return _convertInterceptedUint8List(allowMalformed, casted, start, end);
+    }
+    return null; // This call was not intercepted.
+  }
+
+  static String _convertInterceptedUint8List(
+      bool allowMalformed, NativeUint8List codeUnits, int start, int end) {
+    if (allowMalformed) {
+      // TextDecoder with option {fatal: false} does not produce the same result
+      // as [Utf8Decoder]. It disagrees on the number of `U+FFFD` (REPLACEMENT
+      // CHARACTER) generated for some malformed sequences. We could use
+      // TextDecoder with option {fatal: true}, catch the error, and re-try
+      // without acceleration. That turns out to be extremely slow (the Error
+      // captures a stack trace).
+      // TODO(31370): Bring Utf8Decoder into alignment with TextDecoder.
+      // TODO(sra): If we can't do that, can we detect valid input fast enough
+      // to use a check like the [_unsafe] check below?
+      return null;
+    }
+
+    var decoder = _decoder;
+    if (decoder == null) return null;
+    if (0 == start && end == null) {
+      return _useTextDecoderChecked(decoder, codeUnits);
+    }
+
+    int length = codeUnits.length;
+    end = RangeError.checkValidRange(start, end, length);
+
+    if (0 == start && end == codeUnits.length) {
+      return _useTextDecoderChecked(decoder, codeUnits);
+    }
+
+    return _useTextDecoderChecked(decoder,
+        JS('NativeUint8List', '#.subarray(#, #)', codeUnits, start, end));
+  }
+
+  static String _useTextDecoderChecked(decoder, NativeUint8List codeUnits) {
+    if (_unsafe(codeUnits)) return null;
+    return _useTextDecoderUnchecked(decoder, codeUnits);
+  }
+
+  static String _useTextDecoderUnchecked(decoder, NativeUint8List codeUnits) {
+    // If the input is malformed, catch the exception and return `null` to fall
+    // back on unintercepted decoder. The fallback will either succeed in
+    // decoding, or report the problem better than TextDecoder.
+    try {
+      return JS('String', '#.decode(#)', decoder, codeUnits);
+    } catch (e) {}
+    return null;
+  }
+
+  /// Returns `true` if [codeUnits] contains problematic encodings.
+  ///
+  /// TextDecoder behaves differently to [Utf8Encoder] when the input encodes a
+  /// surrogate (U+D800 through U+DFFF). TextDecoder considers the surrogate to
+  /// be an encoding error and, depending on the `fatal` option, either throws
+  /// and Error or encodes the surrogate as U+FFFD. [Utf8Decoder] does not
+  /// consider the surrogate to be an error and returns the code unit encoded by
+  /// the surrogate.
+  ///
+  /// Throwing an `Error` captures the stack, whoch makes it so expensive that
+  /// it is worth checking the input for surrogates and avoiding TextDecoder in
+  /// this case.
+  static bool _unsafe(NativeUint8List codeUnits) {
+    // Surrogates encode as (hex) ED Ax xx or ED Bx xx.
+    int limit = codeUnits.length - 2;
+    for (int i = 0; i < limit; i++) {
+      int unit1 = codeUnits[i];
+      if (unit1 == 0xED) {
+        int unit2 = codeUnits[i + 1];
+        if ((unit2 & 0xE0) == 0xA0) return true;
+      }
+    }
+    return false;
+  }
+
+  // TextDecoder is not defined on some browsers and on the stand-alone d8 and
+  // jsshell engines. Use a lazy initializer to do feature detection once.
+  static final _decoder = _makeDecoder();
+  static _makeDecoder() {
+    try {
+      // Use `{fatal: true}`. 'fatal' does not correspond exactly to
+      // `!allowMalformed`: TextDecoder rejects unpaired surrogates which
+      // [Utf8Decoder] accepts.  In non-fatal mode, TextDecoder translates
+      // unpaired surrogates to REPLACEMENT CHARACTER (U+FFFD) whereas
+      // [Utf8Decoder] leaves the surrogate intact.
+      return JS('', 'new TextDecoder("utf-8", {fatal: true})');
+    } catch (e) {}
+    return null;
+  }
+}
+
+@patch
+int _scanOneByteCharacters(List<int> units, int from, int endIndex) {
+  final to = endIndex;
+  for (var i = from; i < to; i++) {
+    final unit = units[i];
+    if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
+  }
+  return to - from;
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart
new file mode 100644
index 0000000..c655fc2
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart
@@ -0,0 +1,2928 @@
+// Copyright (c) 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.
+
+// Patch file for dart:core classes.
+import "dart:_internal" hide Symbol, LinkedList, LinkedListEntry;
+import "dart:_internal" as _symbol_dev;
+import 'dart:_interceptors';
+import 'dart:_js_helper'
+    show
+        checkInt,
+        Closure,
+        ConstantMap,
+        getRuntimeType,
+        JsLinkedHashMap,
+        jsonEncodeNative,
+        JSSyntaxRegExp,
+        NoInline,
+        objectHashCode,
+        patch,
+        Primitives,
+        quoteStringForRegExp,
+        stringJoinUnchecked,
+        getTraceFromException,
+        RuntimeError;
+
+import 'dart:_foreign_helper' show JS, JS_GET_FLAG;
+
+import 'dart:_native_typed_data' show NativeUint8List;
+
+import "dart:convert" show Encoding, utf8;
+
+import 'dart:typed_data' show Endian, Uint8List, Uint16List;
+
+String _symbolToString(Symbol symbol) => _symbol_dev.Symbol.getName(symbol);
+
+Map<String, dynamic> _symbolMapToStringMap(Map<Symbol, dynamic> map) {
+  if (map == null) return null;
+  var result = new Map<String, dynamic>();
+  map.forEach((Symbol key, value) {
+    result[_symbolToString(key)] = value;
+  });
+  return result;
+}
+
+@patch
+int identityHashCode(Object object) => objectHashCode(object);
+
+// Patch for Object implementation.
+@patch
+class Object {
+  @patch
+  bool operator ==(other) => identical(this, other);
+
+  @patch
+  int get hashCode => Primitives.objectHashCode(this);
+
+  @patch
+  String toString() => Primitives.objectToHumanReadableString(this);
+
+  @patch
+  dynamic noSuchMethod(Invocation invocation) {
+    throw new NoSuchMethodError(this, invocation.memberName,
+        invocation.positionalArguments, invocation.namedArguments);
+  }
+
+  @patch
+  Type get runtimeType => getRuntimeType(this);
+}
+
+@patch
+class Null {
+  @patch
+  int get hashCode => super.hashCode;
+}
+
+// Patch for Function implementation.
+@patch
+class Function {
+  @patch
+  static apply(Function function, List positionalArguments,
+      [Map<Symbol, dynamic> namedArguments]) {
+    return Primitives.applyFunction(
+        function,
+        positionalArguments,
+        // Use this form so that if namedArguments is always null, we can
+        // tree-shake _symbolMapToStringMap.
+        namedArguments == null ? null : _symbolMapToStringMap(namedArguments));
+  }
+}
+
+// Patch for Expando implementation.
+@patch
+class Expando<T> {
+  static const String _EXPANDO_PROPERTY_NAME = 'expando\$values';
+
+  // Incremented to make unique keys.
+  static int _keyCount = 0;
+
+  // Stores either a JS WeakMap or a "unique" string key.
+  final Object _jsWeakMapOrKey;
+
+  @patch
+  Expando([String name])
+      : this.name = name,
+        _jsWeakMapOrKey = JS('bool', 'typeof WeakMap == "function"')
+            ? JS('=Object|Null', 'new WeakMap()')
+            : _createKey();
+
+  @patch
+  T operator [](Object object) {
+    if (_jsWeakMapOrKey is! String) {
+      _checkType(object); // WeakMap doesn't check on reading, only writing.
+      return JS('', '#.get(#)', _jsWeakMapOrKey, object);
+    }
+    return _getFromObject(_jsWeakMapOrKey, object);
+  }
+
+  @patch
+  void operator []=(Object object, T value) {
+    if (_jsWeakMapOrKey is! String) {
+      JS('void', '#.set(#, #)', _jsWeakMapOrKey, object, value);
+    } else {
+      _setOnObject(_jsWeakMapOrKey, object, value);
+    }
+  }
+
+  static Object _getFromObject(String key, Object object) {
+    var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME);
+    return (values == null) ? null : Primitives.getProperty(values, key);
+  }
+
+  static void _setOnObject(String key, Object object, Object value) {
+    var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME);
+    if (values == null) {
+      values = new Object();
+      Primitives.setProperty(object, _EXPANDO_PROPERTY_NAME, values);
+    }
+    Primitives.setProperty(values, key, value);
+  }
+
+  static String _createKey() => "expando\$key\$${_keyCount++}";
+
+  static _checkType(object) {
+    if (object == null || object is bool || object is num || object is String) {
+      throw new ArgumentError.value(object,
+          "Expandos are not allowed on strings, numbers, booleans or null");
+    }
+  }
+}
+
+@patch
+class int {
+  @patch
+  static int parse(String source,
+      {int radix, @deprecated int onError(String source)}) {
+    int value = tryParse(source, radix: radix);
+    if (value != null) return value;
+    if (onError != null) return onError(source);
+    throw new FormatException(source);
+  }
+
+  @patch
+  static int tryParse(String source, {int radix}) {
+    return Primitives.parseInt(source, radix);
+  }
+}
+
+@patch
+class double {
+  @patch
+  static double parse(String source,
+      [@deprecated double onError(String source)]) {
+    double value = tryParse(source);
+    if (value != null) return value;
+    if (onError != null) return onError(source);
+    throw new FormatException('Invalid double', source);
+  }
+
+  @patch
+  static double tryParse(String source) {
+    return Primitives.parseDouble(source);
+  }
+}
+
+@patch
+class BigInt implements Comparable<BigInt> {
+  @patch
+  static BigInt get zero => _BigIntImpl.zero;
+  @patch
+  static BigInt get one => _BigIntImpl.one;
+  @patch
+  static BigInt get two => _BigIntImpl.two;
+
+  @patch
+  static BigInt parse(String source, {int radix}) =>
+      _BigIntImpl.parse(source, radix: radix);
+
+  @patch
+  static BigInt tryParse(String source, {int radix}) =>
+      _BigIntImpl._tryParse(source, radix: radix);
+
+  @patch
+  factory BigInt.from(num value) = _BigIntImpl.from;
+}
+
+@patch
+class Error {
+  @patch
+  static String _objectToString(Object object) {
+    // Closures all have useful and safe toString methods.
+    if (object is Closure) return object.toString();
+    return Primitives.objectToHumanReadableString(object);
+  }
+
+  @patch
+  static String _stringToSafeString(String string) {
+    return jsonEncodeNative(string);
+  }
+
+  @patch
+  StackTrace get stackTrace => Primitives.extractStackTrace(this);
+}
+
+@patch
+class FallThroughError {
+  @patch
+  FallThroughError._create(String url, int line);
+
+  @patch
+  String toString() => super.toString();
+}
+
+@patch
+class AbstractClassInstantiationError {
+  @patch
+  String toString() => "Cannot instantiate abstract class: '$_className'";
+}
+
+// Patch for DateTime implementation.
+@patch
+class DateTime {
+  @patch
+  DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
+      {bool isUtc: false})
+      // `0 + millisecondsSinceEpoch` forces the inferred result to be non-null.
+      : this._withValue(0 + millisecondsSinceEpoch, isUtc: isUtc);
+
+  @patch
+  DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch,
+      {bool isUtc: false})
+      : this._withValue(
+            _microsecondInRoundedMilliseconds(microsecondsSinceEpoch),
+            isUtc: isUtc);
+
+  @patch
+  DateTime._internal(int year, int month, int day, int hour, int minute,
+      int second, int millisecond, int microsecond, bool isUtc)
+      // checkBool is manually inlined here because dart2js doesn't inline it
+      // and [isUtc] is usually a constant.
+      : this.isUtc = isUtc is bool
+            ? isUtc
+            : throw new ArgumentError.value(isUtc, 'isUtc'),
+        _value = checkInt(Primitives.valueFromDecomposedDate(
+            year,
+            month,
+            day,
+            hour,
+            minute,
+            second,
+            millisecond + _microsecondInRoundedMilliseconds(microsecond),
+            isUtc));
+
+  @patch
+  DateTime._now()
+      : isUtc = false,
+        _value = Primitives.dateNow();
+
+  /// Rounds the given [microsecond] to the nearest milliseconds value.
+  ///
+  /// For example, invoked with argument `2600` returns `3`.
+  static int _microsecondInRoundedMilliseconds(int microsecond) {
+    return (microsecond / 1000).round();
+  }
+
+  @patch
+  static int _brokenDownDateToValue(int year, int month, int day, int hour,
+      int minute, int second, int millisecond, int microsecond, bool isUtc) {
+    return Primitives.valueFromDecomposedDate(
+        year,
+        month,
+        day,
+        hour,
+        minute,
+        second,
+        millisecond + _microsecondInRoundedMilliseconds(microsecond),
+        isUtc);
+  }
+
+  @patch
+  String get timeZoneName {
+    if (isUtc) return "UTC";
+    return Primitives.getTimeZoneName(this);
+  }
+
+  @patch
+  Duration get timeZoneOffset {
+    if (isUtc) return new Duration();
+    return new Duration(minutes: Primitives.getTimeZoneOffsetInMinutes(this));
+  }
+
+  @patch
+  DateTime add(Duration duration) {
+    return new DateTime._withValue(_value + duration.inMilliseconds,
+        isUtc: isUtc);
+  }
+
+  @patch
+  DateTime subtract(Duration duration) {
+    return new DateTime._withValue(_value - duration.inMilliseconds,
+        isUtc: isUtc);
+  }
+
+  @patch
+  Duration difference(DateTime other) {
+    return new Duration(milliseconds: _value - other._value);
+  }
+
+  @patch
+  int get millisecondsSinceEpoch => _value;
+
+  @patch
+  int get microsecondsSinceEpoch => 1000 * _value;
+
+  @patch
+  int get year => Primitives.getYear(this);
+
+  @patch
+  int get month => Primitives.getMonth(this);
+
+  @patch
+  int get day => Primitives.getDay(this);
+
+  @patch
+  int get hour => Primitives.getHours(this);
+
+  @patch
+  int get minute => Primitives.getMinutes(this);
+
+  @patch
+  int get second => Primitives.getSeconds(this);
+
+  @patch
+  int get millisecond => Primitives.getMilliseconds(this);
+
+  @patch
+  int get microsecond => 0;
+
+  @patch
+  int get weekday => Primitives.getWeekday(this);
+
+  @patch
+  bool operator ==(dynamic other) =>
+      other is DateTime &&
+      _value == other.millisecondsSinceEpoch &&
+      isUtc == other.isUtc;
+
+  @patch
+  bool isBefore(DateTime other) => _value < other.millisecondsSinceEpoch;
+
+  @patch
+  bool isAfter(DateTime other) => _value > other.millisecondsSinceEpoch;
+
+  @patch
+  bool isAtSameMomentAs(DateTime other) =>
+      _value == other.millisecondsSinceEpoch;
+
+  @patch
+  int compareTo(DateTime other) =>
+      _value.compareTo(other.millisecondsSinceEpoch);
+}
+
+// Patch for Stopwatch implementation.
+@patch
+class Stopwatch {
+  @patch
+  static void _initTicker() {
+    Primitives.initTicker();
+    _frequency = Primitives.timerFrequency;
+  }
+
+  @patch
+  static int _now() => Primitives.timerTicks();
+
+  @patch
+  int get elapsedMicroseconds {
+    int ticks = elapsedTicks;
+    if (_frequency == 1000000) return ticks;
+    assert(_frequency == 1000);
+    return ticks * 1000;
+  }
+
+  @patch
+  int get elapsedMilliseconds {
+    int ticks = elapsedTicks;
+    if (_frequency == 1000) return ticks;
+    assert(_frequency == 1000000);
+    return ticks ~/ 1000;
+  }
+}
+
+// Patch for List implementation.
+@patch
+class List<E> {
+  @patch
+  factory List([int length]) = JSArray<E>.list;
+
+  @patch
+  factory List.filled(int length, E fill, {bool growable: false}) {
+    List result = growable
+        ? new JSArray<E>.growable(length)
+        : new JSArray<E>.fixed(length);
+    if (length != 0 && fill != null) {
+      for (int i = 0; i < result.length; i++) {
+        result[i] = fill;
+      }
+    }
+    return result;
+  }
+
+  @patch
+  factory List.from(Iterable elements, {bool growable: true}) {
+    List<E> list = <E>[];
+    for (E e in elements) {
+      list.add(e);
+    }
+    if (growable) return list;
+    return makeListFixedLength(list);
+  }
+
+  @patch
+  factory List.unmodifiable(Iterable elements) {
+    List result = new List<E>.from(elements, growable: false);
+    return makeFixedListUnmodifiable(result);
+  }
+}
+
+@patch
+class Map<K, V> {
+  @patch
+  factory Map.unmodifiable(Map other) = ConstantMap<K, V>.from;
+
+  @patch
+  factory Map() = JsLinkedHashMap<K, V>.es6;
+}
+
+@patch
+class String {
+  @patch
+  factory String.fromCharCodes(Iterable<int> charCodes,
+      [int start = 0, int end]) {
+    if (charCodes is JSArray) {
+      JSArray<int> array = charCodes;
+      return _stringFromJSArray(array, start, end);
+    }
+    if (charCodes is NativeUint8List) {
+      return _stringFromUint8List(charCodes, start, end);
+    }
+    return _stringFromIterable(charCodes, start, end);
+  }
+
+  @patch
+  factory String.fromCharCode(int charCode) {
+    return Primitives.stringFromCharCode(charCode);
+  }
+
+  static String _stringFromJSArray(List list, int start, int endOrNull) {
+    int len = list.length;
+    int end = RangeError.checkValidRange(start, endOrNull, len);
+    if (start > 0 || end < len) {
+      list = list.sublist(start, end);
+    }
+    return Primitives.stringFromCharCodes(list);
+  }
+
+  static String _stringFromUint8List(
+      NativeUint8List charCodes, int start, int endOrNull) {
+    int len = charCodes.length;
+    int end = RangeError.checkValidRange(start, endOrNull, len);
+    return Primitives.stringFromNativeUint8List(charCodes, start, end);
+  }
+
+  static String _stringFromIterable(
+      Iterable<int> charCodes, int start, int end) {
+    if (start < 0) throw new RangeError.range(start, 0, charCodes.length);
+    if (end != null && end < start) {
+      throw new RangeError.range(end, start, charCodes.length);
+    }
+    var it = charCodes.iterator;
+    for (int i = 0; i < start; i++) {
+      if (!it.moveNext()) {
+        throw new RangeError.range(start, 0, i);
+      }
+    }
+    var list = [];
+    if (end == null) {
+      while (it.moveNext()) list.add(it.current);
+    } else {
+      for (int i = start; i < end; i++) {
+        if (!it.moveNext()) {
+          throw new RangeError.range(end, start, i);
+        }
+        list.add(it.current);
+      }
+    }
+    return Primitives.stringFromCharCodes(list);
+  }
+}
+
+@patch
+class bool {
+  @patch
+  int get hashCode => super.hashCode;
+}
+
+@patch
+class RegExp {
+  @pragma('dart2js:noInline')
+  @patch
+  factory RegExp(String source,
+          {bool multiLine: false,
+          bool caseSensitive: true,
+          bool unicode: false,
+          bool dotAll: false}) =>
+      new JSSyntaxRegExp(source,
+          multiLine: multiLine,
+          caseSensitive: caseSensitive,
+          unicode: unicode,
+          dotAll: dotAll);
+
+  @patch
+  static String escape(String text) => quoteStringForRegExp(text);
+}
+
+// Patch for 'identical' function.
+@pragma(
+    'dart2js:noInline') // No inlining since we recognize the call in optimizer.
+@patch
+bool identical(Object a, Object b) {
+  return JS('bool', '(# == null ? # == null : # === #)', a, b, a, b);
+}
+
+@patch
+class StringBuffer {
+  String _contents;
+
+  @patch
+  StringBuffer([Object content = ""]) : _contents = '$content';
+
+  @patch
+  int get length => _contents.length;
+
+  @patch
+  void write(Object obj) {
+    _writeString('$obj');
+  }
+
+  @patch
+  void writeCharCode(int charCode) {
+    _writeString(new String.fromCharCode(charCode));
+  }
+
+  @patch
+  void writeAll(Iterable objects, [String separator = ""]) {
+    _contents = _writeAll(_contents, objects, separator);
+  }
+
+  @patch
+  void writeln([Object obj = ""]) {
+    _writeString('$obj\n');
+  }
+
+  @patch
+  void clear() {
+    _contents = "";
+  }
+
+  @patch
+  String toString() => Primitives.flattenString(_contents);
+
+  void _writeString(str) {
+    _contents = Primitives.stringConcatUnchecked(_contents, str);
+  }
+
+  static String _writeAll(String string, Iterable objects, String separator) {
+    Iterator iterator = objects.iterator;
+    if (!iterator.moveNext()) return string;
+    if (separator.isEmpty) {
+      do {
+        string = _writeOne(string, iterator.current);
+      } while (iterator.moveNext());
+    } else {
+      string = _writeOne(string, iterator.current);
+      while (iterator.moveNext()) {
+        string = _writeOne(string, separator);
+        string = _writeOne(string, iterator.current);
+      }
+    }
+    return string;
+  }
+
+  static String _writeOne(String string, Object obj) {
+    return Primitives.stringConcatUnchecked(string, '$obj');
+  }
+}
+
+@patch
+class NoSuchMethodError {
+  final Object _receiver;
+  final Symbol _memberName;
+  final List _arguments;
+  final Map<Symbol, dynamic> _namedArguments;
+  final List _existingArgumentNames;
+
+  @patch
+  NoSuchMethodError.withInvocation(Object receiver, Invocation invocation)
+      : this(receiver, invocation.memberName, invocation.positionalArguments,
+            invocation.namedArguments);
+
+  @patch
+  NoSuchMethodError(Object receiver, Symbol memberName,
+      List positionalArguments, Map<Symbol, dynamic> namedArguments,
+      [List existingArgumentNames = null])
+      : _receiver = receiver,
+        _memberName = memberName,
+        _arguments = positionalArguments,
+        _namedArguments = namedArguments,
+        _existingArgumentNames = existingArgumentNames;
+
+  @patch
+  String toString() {
+    StringBuffer sb = new StringBuffer('');
+    String comma = '';
+    if (_arguments != null) {
+      for (var argument in _arguments) {
+        sb.write(comma);
+        sb.write(Error.safeToString(argument));
+        comma = ', ';
+      }
+    }
+    if (_namedArguments != null) {
+      _namedArguments.forEach((Symbol key, var value) {
+        sb.write(comma);
+        sb.write(_symbolToString(key));
+        sb.write(": ");
+        sb.write(Error.safeToString(value));
+        comma = ', ';
+      });
+    }
+    String memberName = _symbolToString(_memberName);
+    String receiverText = Error.safeToString(_receiver);
+    String actualParameters = '$sb';
+    if (_existingArgumentNames == null) {
+      return "NoSuchMethodError: method not found: '$memberName'\n"
+          "Receiver: ${receiverText}\n"
+          "Arguments: [$actualParameters]";
+    } else {
+      String formalParameters = _existingArgumentNames.join(', ');
+      return "NoSuchMethodError: incorrect number of arguments passed to "
+          "method named '$memberName'\n"
+          "Receiver: ${receiverText}\n"
+          "Tried calling: $memberName($actualParameters)\n"
+          "Found: $memberName($formalParameters)";
+    }
+  }
+}
+
+class _CompileTimeError extends Error {
+  final String _errorMsg;
+  // TODO(sigmund): consider calling `JS('', 'debugger')`.
+  _CompileTimeError(this._errorMsg);
+  String toString() => _errorMsg;
+}
+
+@patch
+class Uri {
+  @patch
+  static Uri get base {
+    String uri = Primitives.currentUri();
+    if (uri != null) return Uri.parse(uri);
+    throw new UnsupportedError("'Uri.base' is not supported");
+  }
+}
+
+@patch
+class _Uri {
+  @patch
+  static bool get _isWindows => _isWindowsCached;
+
+  static final bool _isWindowsCached = JS(
+      'bool',
+      'typeof process != "undefined" && '
+          'Object.prototype.toString.call(process) == "[object process]" && '
+          'process.platform == "win32"');
+
+  // Matches a String that _uriEncodes to itself regardless of the kind of
+  // component.  This corresponds to [_unreservedTable], i.e. characters that
+  // are not encoded by any encoding table.
+  static final RegExp _needsNoEncoding = new RegExp(r'^[\-\.0-9A-Z_a-z~]*$');
+
+  /// This is the internal implementation of JavaScript's encodeURI function.
+  /// It encodes all characters in the string [text] except for those
+  /// that appear in [canonicalTable], and returns the escaped string.
+  @patch
+  static String _uriEncode(List<int> canonicalTable, String text,
+      Encoding encoding, bool spaceToPlus) {
+    if (identical(encoding, utf8) && _needsNoEncoding.hasMatch(text)) {
+      return text;
+    }
+
+    // Encode the string into bytes then generate an ASCII only string
+    // by percent encoding selected bytes.
+    StringBuffer result = new StringBuffer('');
+    var bytes = encoding.encode(text);
+    for (int i = 0; i < bytes.length; i++) {
+      int byte = bytes[i];
+      if (byte < 128 &&
+          ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) {
+        result.writeCharCode(byte);
+      } else if (spaceToPlus && byte == _SPACE) {
+        result.write('+');
+      } else {
+        const String hexDigits = '0123456789ABCDEF';
+        result.write('%');
+        result.write(hexDigits[(byte >> 4) & 0x0f]);
+        result.write(hexDigits[byte & 0x0f]);
+      }
+    }
+    return result.toString();
+  }
+}
+
+bool _hasErrorStackProperty = JS('bool', 'new Error().stack != void 0');
+
+@patch
+class StackTrace {
+  @patch
+  @pragma('dart2js:noInline')
+  static StackTrace get current {
+    if (_hasErrorStackProperty) {
+      return getTraceFromException(JS('', 'new Error()'));
+    }
+    // Fallback if new Error().stack does not exist.
+    // Currently only required for IE 11.
+    try {
+      throw '';
+    } catch (_, stackTrace) {
+      return stackTrace;
+    }
+  }
+}
+
+// Called from kernel generated code.
+_malformedTypeError(message) => new RuntimeError(message);
+
+// Called from kernel generated code.
+_genericNoSuchMethod(receiver, memberName, positionalArguments, namedArguments,
+    existingArguments) {
+  return new NoSuchMethodError(
+      receiver, memberName, positionalArguments, namedArguments);
+}
+
+// Called from kernel generated code.
+_unresolvedConstructorError(receiver, memberName, positionalArguments,
+    namedArguments, existingArguments) {
+  // TODO(sra): Generate an error that reads:
+  //
+  //     No constructor '$memberName' declared in class '$receiver'.
+
+  return new NoSuchMethodError(
+      receiver, memberName, positionalArguments, namedArguments);
+}
+
+// Called from kernel generated code.
+_unresolvedStaticGetterError(receiver, memberName, positionalArguments,
+    namedArguments, existingArguments) {
+  // TODO(sra): Generate customized message.
+  return new NoSuchMethodError(
+      receiver, memberName, positionalArguments, namedArguments);
+}
+
+// Called from kernel generated code.
+_unresolvedStaticSetterError(receiver, memberName, positionalArguments,
+    namedArguments, existingArguments) {
+  // TODO(sra): Generate customized message.
+  return new NoSuchMethodError(
+      receiver, memberName, positionalArguments, namedArguments);
+}
+
+// Called from kernel generated code.
+_unresolvedStaticMethodError(receiver, memberName, positionalArguments,
+    namedArguments, existingArguments) {
+  // TODO(sra): Generate customized message.
+  return new NoSuchMethodError(
+      receiver, memberName, positionalArguments, namedArguments);
+}
+
+// Called from kernel generated code.
+_unresolvedTopLevelGetterError(receiver, memberName, positionalArguments,
+    namedArguments, existingArguments) {
+  // TODO(sra): Generate customized message.
+  return new NoSuchMethodError(
+      receiver, memberName, positionalArguments, namedArguments);
+}
+
+// Called from kernel generated code.
+_unresolvedTopLevelSetterError(receiver, memberName, positionalArguments,
+    namedArguments, existingArguments) {
+  // TODO(sra): Generate customized message.
+  return new NoSuchMethodError(
+      receiver, memberName, positionalArguments, namedArguments);
+}
+
+// Called from kernel generated code.
+_unresolvedTopLevelMethodError(receiver, memberName, positionalArguments,
+    namedArguments, existingArguments) {
+  // TODO(sra): Generate customized message.
+  return new NoSuchMethodError(
+      receiver, memberName, positionalArguments, namedArguments);
+}
+
+/// Used by Fasta to report a runtime error when a final field with an
+/// initializer is also initialized in a generative constructor.
+///
+/// Note: in strong mode, this is a compile-time error and this class becomes
+/// obsolete.
+class _DuplicatedFieldInitializerError extends Error {
+  final String _name;
+
+  _DuplicatedFieldInitializerError(this._name);
+
+  toString() => "Error: field '$_name' is already initialized.";
+}
+
+// TODO(sra): The rest of this core_patch.dart source should reside in an
+// included part file instead of being inlined. However, part files are not
+// properly supported here.
+
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.core;
+
+int _max(int a, int b) => a > b ? a : b;
+int _min(int a, int b) => a < b ? a : b;
+
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+ * Copyright (c) 2003-2005  Tom Wu
+ * Copyright (c) 2012 Adam Singer (adam@solvr.io)
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following condition applies:
+ *
+ * All redistributions must retain an intact copy of this copyright notice
+ * and disclaimer.
+ */
+
+/// An implementation for the arbitrarily large integer.
+///
+/// The integer number is represented by a sign, an array of 16-bit unsigned
+/// integers in little endian format, and a number of used digits in that array.
+class _BigIntImpl implements BigInt {
+  // Bits per digit.
+  static const int _digitBits = 16;
+  static const int _digitBase = 1 << _digitBits;
+  static const int _digitMask = (1 << _digitBits) - 1;
+
+  static final _BigIntImpl zero = new _BigIntImpl._fromInt(0);
+  static final _BigIntImpl one = new _BigIntImpl._fromInt(1);
+  static final _BigIntImpl two = new _BigIntImpl._fromInt(2);
+
+  static final _BigIntImpl _minusOne = -one;
+  static final _BigIntImpl _bigInt10000 = new _BigIntImpl._fromInt(10000);
+
+  // Result cache for last _divRem call.
+  // Result cache for last _divRem call.
+  static Uint16List _lastDividendDigits;
+  static int _lastDividendUsed;
+  static Uint16List _lastDivisorDigits;
+  static int _lastDivisorUsed;
+  static Uint16List _lastQuoRemDigits;
+  static int _lastQuoRemUsed;
+  static int _lastRemUsed;
+  static int _lastRem_nsh;
+
+  /// Whether this bigint is negative.
+  final bool _isNegative;
+
+  /// The unsigned digits of this bigint.
+  ///
+  /// The least significant digit is in slot 0.
+  /// The list may have more digits than needed. That is, `_digits.length` may
+  /// be strictly greater than `_used`.
+  final Uint16List _digits;
+
+  /// The number of used entries in [_digits].
+  ///
+  /// To avoid reallocating [Uint16List]s, lists that are too big are not
+  /// replaced.
+  final int _used;
+
+  /// Parses [source] as a, possibly signed, integer literal and returns its
+  /// value.
+  ///
+  /// The [source] must be a non-empty sequence of base-[radix] digits,
+  /// optionally prefixed with a minus or plus sign ('-' or '+').
+  ///
+  /// The [radix] must be in the range 2..36. The digits used are
+  /// first the decimal digits 0..9, and then the letters 'a'..'z' with
+  /// values 10 through 35. Also accepts upper-case letters with the same
+  /// values as the lower-case ones.
+  ///
+  /// If no [radix] is given then it defaults to 10. In this case, the [source]
+  /// digits may also start with `0x`, in which case the number is interpreted
+  /// as a hexadecimal literal, which effectively means that the `0x` is ignored
+  /// and the radix is instead set to 16.
+  ///
+  /// For any int `n` and radix `r`, it is guaranteed that
+  /// `n == int.parse(n.toRadixString(r), radix: r)`.
+  ///
+  /// Throws a [FormatException] if the [source] is not a valid integer literal,
+  /// optionally prefixed by a sign.
+  static _BigIntImpl parse(String source, {int radix}) {
+    var result = _tryParse(source, radix: radix);
+    if (result == null) {
+      throw new FormatException("Could not parse BigInt", source);
+    }
+    return result;
+  }
+
+  /// Parses a decimal bigint literal.
+  ///
+  /// The [source] must not contain leading or trailing whitespace.
+  static _BigIntImpl _parseDecimal(String source, bool isNegative) {
+    const _0 = 48;
+
+    int part = 0;
+    _BigIntImpl result = zero;
+    // Read in the source 4 digits at a time.
+    // The first part may have a few leading virtual '0's to make the remaining
+    // parts all have exactly 4 digits.
+    int digitInPartCount = 4 - source.length.remainder(4);
+    if (digitInPartCount == 4) digitInPartCount = 0;
+    for (int i = 0; i < source.length; i++) {
+      part = part * 10 + source.codeUnitAt(i) - _0;
+      if (++digitInPartCount == 4) {
+        result = result * _bigInt10000 + new _BigIntImpl._fromInt(part);
+        part = 0;
+        digitInPartCount = 0;
+      }
+    }
+    if (isNegative) return -result;
+    return result;
+  }
+
+  /// Returns the value of a given source digit.
+  ///
+  /// Source digits between "0" and "9" (inclusive) return their decimal value.
+  ///
+  /// Source digits between "a" and "z", or "A" and "Z" (inclusive) return
+  /// 10 + their position in the ASCII alphabet.
+  ///
+  /// The incoming [codeUnit] must be an ASCII code-unit.
+  static int _codeUnitToRadixValue(int codeUnit) {
+    // We know that the characters must be ASCII as otherwise the
+    // regexp wouldn't have matched. Lowercasing by doing `| 0x20` is thus
+    // guaranteed to be a safe operation, since it preserves digits
+    // and lower-cases ASCII letters.
+    const int _0 = 48;
+    const int _9 = 57;
+    const int _a = 97;
+    if (_0 <= codeUnit && codeUnit <= _9) return codeUnit - _0;
+    codeUnit |= 0x20;
+    var result = codeUnit - _a + 10;
+    return result;
+  }
+
+  /// Parses the given [source] string, starting at [startPos], as a hex
+  /// literal.
+  ///
+  /// If [isNegative] is true, negates the result before returning it.
+  ///
+  /// The [source] (substring) must be a valid hex literal.
+  static _BigIntImpl _parseHex(String source, int startPos, bool isNegative) {
+    int hexDigitsPerChunk = _digitBits ~/ 4;
+    int sourceLength = source.length - startPos;
+    int chunkCount = (sourceLength / hexDigitsPerChunk).ceil();
+    var digits = new Uint16List(chunkCount);
+
+    int lastDigitLength = sourceLength - (chunkCount - 1) * hexDigitsPerChunk;
+    int digitIndex = digits.length - 1;
+    int i = startPos;
+    int chunk = 0;
+    for (int j = 0; j < lastDigitLength; j++) {
+      var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i++));
+      if (digitValue >= 16) return null;
+      chunk = chunk * 16 + digitValue;
+    }
+    digits[digitIndex--] = chunk;
+
+    while (i < source.length) {
+      chunk = 0;
+      for (int j = 0; j < hexDigitsPerChunk; j++) {
+        var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i++));
+        if (digitValue >= 16) return null;
+        chunk = chunk * 16 + digitValue;
+      }
+      digits[digitIndex--] = chunk;
+    }
+    if (digits.length == 1 && digits[0] == 0) return zero;
+    return new _BigIntImpl._(isNegative, digits.length, digits);
+  }
+
+  /// Parses the given [source] as a [radix] literal.
+  ///
+  /// The [source] will be checked for invalid characters. If it is invalid,
+  /// this function returns `null`.
+  static _BigIntImpl _parseRadix(String source, int radix, bool isNegative) {
+    var result = zero;
+    var base = new _BigIntImpl._fromInt(radix);
+    for (int i = 0; i < source.length; i++) {
+      var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i));
+      if (digitValue >= radix) return null;
+      result = result * base + new _BigIntImpl._fromInt(digitValue);
+    }
+    if (isNegative) return -result;
+    return result;
+  }
+
+  /// Tries to parse the given [source] as a [radix] literal.
+  ///
+  /// Returns the parsed big integer, or `null` if it failed.
+  ///
+  /// If the [radix] is `null` accepts decimal literals or `0x` hex literals.
+  static _BigIntImpl _tryParse(String source, {int radix}) {
+    if (source == "") return null;
+
+    var re = new RegExp(r'^\s*([+-]?)((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$',
+        caseSensitive: false);
+    var match = re.firstMatch(source);
+    int signIndex = 1;
+    int hexIndex = 3;
+    int decimalIndex = 4;
+    int nonDecimalHexIndex = 5;
+    if (match == null) return null;
+
+    bool isNegative = match[signIndex] == "-";
+
+    String decimalMatch = match[decimalIndex];
+    String hexMatch = match[hexIndex];
+    String nonDecimalMatch = match[nonDecimalHexIndex];
+
+    if (radix == null) {
+      if (decimalMatch != null) {
+        // Cannot fail because we know that the digits are all decimal.
+        return _parseDecimal(decimalMatch, isNegative);
+      }
+      if (hexMatch != null) {
+        // Cannot fail because we know that the digits are all hex.
+        return _parseHex(hexMatch, 2, isNegative);
+      }
+      return null;
+    }
+
+    if (radix is! int) {
+      throw new ArgumentError.value(radix, 'radix', 'is not an integer');
+    }
+    if (radix < 2 || radix > 36) {
+      throw new RangeError.range(radix, 2, 36, 'radix');
+    }
+    if (radix == 10 && decimalMatch != null) {
+      return _parseDecimal(decimalMatch, isNegative);
+    }
+    if (radix == 16 && (decimalMatch != null || nonDecimalMatch != null)) {
+      return _parseHex(decimalMatch ?? nonDecimalMatch, 0, isNegative);
+    }
+
+    return _parseRadix(
+        decimalMatch ?? nonDecimalMatch ?? hexMatch, radix, isNegative);
+  }
+
+  /// Finds the amount significant digits in the provided [digits] array.
+  static int _normalize(int used, Uint16List digits) {
+    while (used > 0 && digits[used - 1] == 0) used--;
+    return 0 + used; // force inferred result to be non-null.
+  }
+
+  /// Factory returning an instance initialized with the given field values.
+  /// If the [digits] array contains leading 0s, the [used] value is adjusted
+  /// accordingly. The [digits] array is not modified.
+  _BigIntImpl._(bool isNegative, int used, Uint16List digits)
+      : this._normalized(isNegative, _normalize(used, digits), digits);
+
+  _BigIntImpl._normalized(bool isNegative, this._used, this._digits)
+      : _isNegative = _used == 0 ? false : isNegative;
+
+  /// Whether this big integer is zero.
+  bool get _isZero => _used == 0;
+
+  /// Allocates an array of the given [length] and copies the [digits] in the
+  /// range [from] to [to-1], starting at index 0, followed by leading zero
+  /// digits.
+  static Uint16List _cloneDigits(
+      Uint16List digits, int from, int to, int length) {
+    var resultDigits = new Uint16List(length);
+    var n = to - from;
+    for (var i = 0; i < n; i++) {
+      resultDigits[i] = digits[from + i];
+    }
+    return resultDigits;
+  }
+
+  /// Allocates a big integer from the provided [value] number.
+  factory _BigIntImpl.from(num value) {
+    if (value == 0) return zero;
+    if (value == 1) return one;
+    if (value == 2) return two;
+
+    // Given this order dart2js will use the `_fromInt` for smaller value and
+    // then use the bit-manipulating `_fromDouble` for all other values.
+    if (value.abs() < 0x100000000)
+      return new _BigIntImpl._fromInt(value.toInt());
+    if (value is double) return new _BigIntImpl._fromDouble(value);
+    return new _BigIntImpl._fromInt(value);
+  }
+
+  factory _BigIntImpl._fromInt(int value) {
+    bool isNegative = value < 0;
+    assert(_digitBits == 16);
+    if (isNegative) {
+      // Handle the min 64-bit value differently, since its negation is not
+      // positive.
+      const int minInt64 = -0x80000000 * 0x100000000;
+      if (value == minInt64) {
+        var digits = new Uint16List(4);
+        digits[3] = 0x8000;
+        return new _BigIntImpl._(true, 4, digits);
+      }
+      value = -value;
+    }
+    if (value < _digitBase) {
+      var digits = new Uint16List(1);
+      digits[0] = value;
+      return new _BigIntImpl._(isNegative, 1, digits);
+    }
+    if (value <= 0xFFFFFFFF) {
+      var digits = new Uint16List(2);
+      digits[0] = value & _digitMask;
+      digits[1] = value >> _digitBits;
+      return new _BigIntImpl._(isNegative, 2, digits);
+    }
+
+    var bits = value.bitLength;
+    var digits = new Uint16List((bits - 1) ~/ _digitBits + 1);
+    var i = 0;
+    while (value != 0) {
+      digits[i++] = value & _digitMask;
+      value = value ~/ _digitBase;
+    }
+    return new _BigIntImpl._(isNegative, digits.length, digits);
+  }
+
+  /// An 8-byte Uint8List we can reuse for [_fromDouble] to avoid generating
+  /// garbage.
+  static final Uint8List _bitsForFromDouble = new Uint8List(8);
+
+  factory _BigIntImpl._fromDouble(double value) {
+    const int exponentBias = 1075;
+
+    if (value.isNaN || value.isInfinite) {
+      throw new ArgumentError("Value must be finite: $value");
+    }
+    bool isNegative = value < 0;
+    if (isNegative) value = -value;
+
+    value = value.floorToDouble();
+    if (value == 0) return zero;
+
+    var bits = _bitsForFromDouble;
+    for (int i = 0; i < 8; i++) {
+      bits[i] = 0;
+    }
+    bits.buffer.asByteData().setFloat64(0, value, Endian.little);
+    // The exponent is in bits 53..63.
+    var biasedExponent = (bits[7] << 4) + (bits[6] >> 4);
+    var exponent = biasedExponent - exponentBias;
+
+    assert(_digitBits == 16);
+    // The significant bits are in 0 .. 52.
+    var unshiftedDigits = new Uint16List(4);
+    unshiftedDigits[0] = (bits[1] << 8) + bits[0];
+    unshiftedDigits[1] = (bits[3] << 8) + bits[2];
+    unshiftedDigits[2] = (bits[5] << 8) + bits[4];
+    // Don't forget to add the hidden bit.
+    unshiftedDigits[3] = 0x10 | (bits[6] & 0xF);
+
+    var unshiftedBig = new _BigIntImpl._normalized(false, 4, unshiftedDigits);
+    _BigIntImpl absResult = unshiftedBig;
+    if (exponent < 0) {
+      absResult = unshiftedBig >> -exponent;
+    } else if (exponent > 0) {
+      absResult = unshiftedBig << exponent;
+    }
+    if (isNegative) return -absResult;
+    return absResult;
+  }
+
+  /// Return the negative value of this integer.
+  ///
+  /// The result of negating an integer always has the opposite sign, except
+  /// for zero, which is its own negation.
+  _BigIntImpl operator -() {
+    if (_used == 0) return this;
+    return new _BigIntImpl._(!_isNegative, _used, _digits);
+  }
+
+  /// Returns the absolute value of this integer.
+  ///
+  /// For any integer `x`, the result is the same as `x < 0 ? -x : x`.
+  _BigIntImpl abs() => _isNegative ? -this : this;
+
+  /// Returns this << n *_DIGIT_BITS.
+  _BigIntImpl _dlShift(int n) {
+    final used = _used;
+    if (used == 0) {
+      return zero;
+    }
+    final resultUsed = used + n;
+    final digits = _digits;
+    final resultDigits = new Uint16List(resultUsed);
+    for (int i = used - 1; i >= 0; i--) {
+      resultDigits[i + n] = digits[i];
+    }
+    return new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+  }
+
+  /// Same as [_dlShift] but works on the decomposed big integers.
+  ///
+  /// Returns `resultUsed`.
+  ///
+  /// `resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n*_DIGIT_BITS`.
+  static int _dlShiftDigits(
+      Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+    if (xUsed == 0) {
+      return 0;
+    }
+    if (n == 0 && identical(resultDigits, xDigits)) {
+      return xUsed;
+    }
+    final resultUsed = xUsed + n;
+    for (int i = xUsed - 1; i >= 0; i--) {
+      resultDigits[i + n] = xDigits[i];
+    }
+    for (int i = n - 1; i >= 0; i--) {
+      resultDigits[i] = 0;
+    }
+    return resultUsed;
+  }
+
+  /// Returns `this >> n*_DIGIT_BITS`.
+  _BigIntImpl _drShift(int n) {
+    final used = _used;
+    if (used == 0) {
+      return zero;
+    }
+    final resultUsed = used - n;
+    if (resultUsed <= 0) {
+      return _isNegative ? _minusOne : zero;
+    }
+    final digits = _digits;
+    final resultDigits = new Uint16List(resultUsed);
+    for (var i = n; i < used; i++) {
+      resultDigits[i - n] = digits[i];
+    }
+    final result = new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+    if (_isNegative) {
+      // Round down if any bit was shifted out.
+      for (var i = 0; i < n; i++) {
+        if (digits[i] != 0) {
+          return result - one;
+        }
+      }
+    }
+    return result;
+  }
+
+  /// Shifts the digits of [xDigits] into the right place in [resultDigits].
+  ///
+  /// `resultDigits[ds..xUsed+ds] = xDigits[0..xUsed-1] << (n % _DIGIT_BITS)`
+  ///   where `ds = n ~/ _DIGIT_BITS`
+  ///
+  /// Does *not* clear digits below ds.
+  static void _lsh(
+      Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+    assert(xUsed > 0);
+    final digitShift = n ~/ _digitBits;
+    final bitShift = n % _digitBits;
+    final carryBitShift = _digitBits - bitShift;
+    final bitMask = (1 << carryBitShift) - 1;
+    var carry = 0;
+    for (int i = xUsed - 1; i >= 0; i--) {
+      final digit = xDigits[i];
+      resultDigits[i + digitShift + 1] = (digit >> carryBitShift) | carry;
+      carry = (digit & bitMask) << bitShift;
+    }
+    resultDigits[digitShift] = carry;
+  }
+
+  /// Shift the bits of this integer to the left by [shiftAmount].
+  ///
+  /// Shifting to the left makes the number larger, effectively multiplying
+  /// the number by `pow(2, shiftIndex)`.
+  ///
+  /// There is no limit on the size of the result. It may be relevant to
+  /// limit intermediate values by using the "and" operator with a suitable
+  /// mask.
+  ///
+  /// It is an error if [shiftAmount] is negative.
+  _BigIntImpl operator <<(int shiftAmount) {
+    if (shiftAmount < 0) {
+      throw new ArgumentError("shift-amount must be posititve $shiftAmount");
+    }
+    if (_isZero) return this;
+    final digitShift = shiftAmount ~/ _digitBits;
+    final bitShift = shiftAmount % _digitBits;
+    if (bitShift == 0) {
+      return _dlShift(digitShift);
+    }
+    var resultUsed = _used + digitShift + 1;
+    var resultDigits = new Uint16List(resultUsed);
+    _lsh(_digits, _used, shiftAmount, resultDigits);
+    return new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+  }
+
+  // resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n.
+  // Returns resultUsed.
+  static int _lShiftDigits(
+      Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+    final digitsShift = n ~/ _digitBits;
+    final bitShift = n % _digitBits;
+    if (bitShift == 0) {
+      return _dlShiftDigits(xDigits, xUsed, digitsShift, resultDigits);
+    }
+    var resultUsed = xUsed + digitsShift + 1;
+    _lsh(xDigits, xUsed, n, resultDigits);
+    var i = digitsShift;
+    while (--i >= 0) {
+      resultDigits[i] = 0;
+    }
+    if (resultDigits[resultUsed - 1] == 0) {
+      resultUsed--; // Clamp result.
+    }
+    return resultUsed;
+  }
+
+  // resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] >> n.
+  static void _rsh(
+      Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+    assert(xUsed > 0);
+    final digitsShift = n ~/ _digitBits;
+    final bitShift = n % _digitBits;
+    final carryBitShift = _digitBits - bitShift;
+    final bitMask = (1 << bitShift) - 1;
+    var carry = xDigits[digitsShift] >> bitShift;
+    final last = xUsed - digitsShift - 1;
+    for (var i = 0; i < last; i++) {
+      final digit = xDigits[i + digitsShift + 1];
+      resultDigits[i] = ((digit & bitMask) << carryBitShift) | carry;
+      carry = digit >> bitShift;
+    }
+    resultDigits[last] = carry;
+  }
+
+  /// Shift the bits of this integer to the right by [shiftAmount].
+  ///
+  /// Shifting to the right makes the number smaller and drops the least
+  /// significant bits, effectively doing an integer division by
+  /// `pow(2, shiftIndex)`.
+  ///
+  /// It is an error if [shiftAmount] is negative.
+  _BigIntImpl operator >>(int shiftAmount) {
+    if (shiftAmount < 0) {
+      throw new ArgumentError("shift-amount must be posititve $shiftAmount");
+    }
+    if (_isZero) return this;
+    final digitShift = shiftAmount ~/ _digitBits;
+    final bitShift = shiftAmount % _digitBits;
+    if (bitShift == 0) {
+      return _drShift(digitShift);
+    }
+    final used = _used;
+    final resultUsed = used - digitShift;
+    if (resultUsed <= 0) {
+      return _isNegative ? _minusOne : zero;
+    }
+    final digits = _digits;
+    final resultDigits = new Uint16List(resultUsed);
+    _rsh(digits, used, shiftAmount, resultDigits);
+    final result = new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+    if (_isNegative) {
+      // Round down if any bit was shifted out.
+      if ((digits[digitShift] & ((1 << bitShift) - 1)) != 0) {
+        return result - one;
+      }
+      for (var i = 0; i < digitShift; i++) {
+        if (digits[i] != 0) {
+          return result - one;
+        }
+      }
+    }
+    return result;
+  }
+
+  /// Compares this to [other] taking the absolute value of both operands.
+  ///
+  /// Returns 0 if abs(this) == abs(other); a positive number if
+  /// abs(this) > abs(other); and a negative number if abs(this) < abs(other).
+  int _absCompare(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    return _compareDigits(_digits, _used, other._digits, other._used);
+  }
+
+  /// Compares this to `other`.
+  ///
+  /// Returns a negative number if `this` is less than `other`, zero if they are
+  /// equal, and a positive number if `this` is greater than `other`.
+  int compareTo(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (_isNegative == other._isNegative) {
+      var result = _absCompare(other);
+      // Use 0 - result to avoid negative zero in JavaScript.
+      return _isNegative ? 0 - result : result;
+    }
+    return _isNegative ? -1 : 1;
+  }
+
+  /// Compares `digits[0..used-1]` with `otherDigits[0..otherUsed-1]`.
+  ///
+  /// Returns 0 if equal; a positive number if larger;
+  /// and a negative number if smaller.
+  static int _compareDigits(
+      Uint16List digits, int used, Uint16List otherDigits, int otherUsed) {
+    var result = used - otherUsed;
+    if (result == 0) {
+      for (int i = used - 1; i >= 0; i--) {
+        result = digits[i] - otherDigits[i];
+        if (result != 0) return result;
+      }
+    }
+    return result;
+  }
+
+  // resultDigits[0..used] = digits[0..used-1] + otherDigits[0..otherUsed-1].
+  // used >= otherUsed > 0.
+  static void _absAdd(Uint16List digits, int used, Uint16List otherDigits,
+      int otherUsed, Uint16List resultDigits) {
+    assert(used >= otherUsed && otherUsed > 0);
+    var carry = 0;
+    for (var i = 0; i < otherUsed; i++) {
+      carry += digits[i] + otherDigits[i];
+      resultDigits[i] = carry & _digitMask;
+      carry >>= _digitBits;
+    }
+    for (var i = otherUsed; i < used; i++) {
+      carry += digits[i];
+      resultDigits[i] = carry & _digitMask;
+      carry >>= _digitBits;
+    }
+    resultDigits[used] = carry;
+  }
+
+  // resultDigits[0..used-1] = digits[0..used-1] - otherDigits[0..otherUsed-1].
+  // used >= otherUsed > 0.
+  static void _absSub(Uint16List digits, int used, Uint16List otherDigits,
+      int otherUsed, Uint16List resultDigits) {
+    assert(used >= otherUsed && otherUsed > 0);
+
+    var carry = 0;
+    for (var i = 0; i < otherUsed; i++) {
+      carry += digits[i] - otherDigits[i];
+      resultDigits[i] = carry & _digitMask;
+      // Dart2js only supports unsigned shifts.
+      // Since the carry can only be -1 or 0 use this hack.
+      carry = 0 - ((carry >> _digitBits) & 1);
+    }
+    for (var i = otherUsed; i < used; i++) {
+      carry += digits[i];
+      resultDigits[i] = carry & _digitMask;
+      // Dart2js only supports unsigned shifts.
+      // Since the carry can only be -1 or 0 use this hack.
+      carry = 0 - ((carry >> _digitBits) & 1);
+    }
+  }
+
+  /// Returns `abs(this) + abs(other)` with sign set according to [isNegative].
+  _BigIntImpl _absAddSetSign(_BigIntImpl other, bool isNegative) {
+    var used = _used;
+    var otherUsed = other._used;
+    if (used < otherUsed) {
+      return other._absAddSetSign(this, isNegative);
+    }
+    if (used == 0) {
+      assert(!isNegative);
+      return zero;
+    }
+    if (otherUsed == 0) {
+      return _isNegative == isNegative ? this : -this;
+    }
+    var resultUsed = used + 1;
+    var resultDigits = new Uint16List(resultUsed);
+    _absAdd(_digits, used, other._digits, otherUsed, resultDigits);
+    return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+  }
+
+  /// Returns `abs(this) - abs(other)` with sign set according to [isNegative].
+  ///
+  /// Requirement: `abs(this) >= abs(other)`.
+  _BigIntImpl _absSubSetSign(_BigIntImpl other, bool isNegative) {
+    assert(_absCompare(other) >= 0);
+    var used = _used;
+    if (used == 0) {
+      assert(!isNegative);
+      return zero;
+    }
+    var otherUsed = other._used;
+    if (otherUsed == 0) {
+      return _isNegative == isNegative ? this : -this;
+    }
+    var resultDigits = new Uint16List(used);
+    _absSub(_digits, used, other._digits, otherUsed, resultDigits);
+    return new _BigIntImpl._(isNegative, used, resultDigits);
+  }
+
+  /// Returns `abs(this) & abs(other)` with sign set according to [isNegative].
+  _BigIntImpl _absAndSetSign(_BigIntImpl other, bool isNegative) {
+    var resultUsed = _min(_used, other._used);
+    var digits = _digits;
+    var otherDigits = other._digits;
+    var resultDigits = new Uint16List(resultUsed);
+    for (var i = 0; i < resultUsed; i++) {
+      resultDigits[i] = digits[i] & otherDigits[i];
+    }
+    return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+  }
+
+  /// Returns `abs(this) &~ abs(other)` with sign set according to [isNegative].
+  _BigIntImpl _absAndNotSetSign(_BigIntImpl other, bool isNegative) {
+    var resultUsed = _used;
+    var digits = _digits;
+    var otherDigits = other._digits;
+    var resultDigits = new Uint16List(resultUsed);
+    var m = _min(resultUsed, other._used);
+    for (var i = 0; i < m; i++) {
+      resultDigits[i] = digits[i] & ~otherDigits[i];
+    }
+    for (var i = m; i < resultUsed; i++) {
+      resultDigits[i] = digits[i];
+    }
+    return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+  }
+
+  /// Returns `abs(this) | abs(other)` with sign set according to [isNegative].
+  _BigIntImpl _absOrSetSign(_BigIntImpl other, bool isNegative) {
+    var used = _used;
+    var otherUsed = other._used;
+    var resultUsed = _max(used, otherUsed);
+    var digits = _digits;
+    var otherDigits = other._digits;
+    var resultDigits = new Uint16List(resultUsed);
+    var l, m;
+    if (used < otherUsed) {
+      l = other;
+      m = used;
+    } else {
+      l = this;
+      m = otherUsed;
+    }
+    for (var i = 0; i < m; i++) {
+      resultDigits[i] = digits[i] | otherDigits[i];
+    }
+    var lDigits = l._digits;
+    for (var i = m; i < resultUsed; i++) {
+      resultDigits[i] = lDigits[i];
+    }
+    return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+  }
+
+  /// Returns `abs(this) ^ abs(other)` with sign set according to [isNegative].
+  _BigIntImpl _absXorSetSign(_BigIntImpl other, bool isNegative) {
+    var used = _used;
+    var otherUsed = other._used;
+    var resultUsed = _max(used, otherUsed);
+    var digits = _digits;
+    var otherDigits = other._digits;
+    var resultDigits = new Uint16List(resultUsed);
+    var l, m;
+    if (used < otherUsed) {
+      l = other;
+      m = used;
+    } else {
+      l = this;
+      m = otherUsed;
+    }
+    for (var i = 0; i < m; i++) {
+      resultDigits[i] = digits[i] ^ otherDigits[i];
+    }
+    var lDigits = l._digits;
+    for (var i = m; i < resultUsed; i++) {
+      resultDigits[i] = lDigits[i];
+    }
+    return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+  }
+
+  /// Bit-wise and operator.
+  ///
+  /// Treating both `this` and [other] as sufficiently large two's component
+  /// integers, the result is a number with only the bits set that are set in
+  /// both `this` and [other]
+  ///
+  /// Of both operands are negative, the result is negative, otherwise
+  /// the result is non-negative.
+  _BigIntImpl operator &(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (_isZero || other._isZero) return zero;
+    if (_isNegative == other._isNegative) {
+      if (_isNegative) {
+        // (-this) & (-other) == ~(this-1) & ~(other-1)
+        //                    == ~((this-1) | (other-1))
+        //                    == -(((this-1) | (other-1)) + 1)
+        _BigIntImpl this1 = _absSubSetSign(one, true);
+        _BigIntImpl other1 = other._absSubSetSign(one, true);
+        // Result cannot be zero if this and other are negative.
+        return this1._absOrSetSign(other1, true)._absAddSetSign(one, true);
+      }
+      return _absAndSetSign(other, false);
+    }
+    // _isNegative != other._isNegative
+    var p, n;
+    if (_isNegative) {
+      p = other;
+      n = this;
+    } else {
+      // & is symmetric.
+      p = this;
+      n = other;
+    }
+    // p & (-n) == p & ~(n-1) == p &~ (n-1)
+    var n1 = n._absSubSetSign(one, false);
+    return p._absAndNotSetSign(n1, false);
+  }
+
+  /// Bit-wise or operator.
+  ///
+  /// Treating both `this` and [other] as sufficiently large two's component
+  /// integers, the result is a number with the bits set that are set in either
+  /// of `this` and [other]
+  ///
+  /// If both operands are non-negative, the result is non-negative,
+  /// otherwise the result us negative.
+  _BigIntImpl operator |(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (_isZero) return other;
+    if (other._isZero) return this;
+    if (_isNegative == other._isNegative) {
+      if (_isNegative) {
+        // (-this) | (-other) == ~(this-1) | ~(other-1)
+        //                    == ~((this-1) & (other-1))
+        //                    == -(((this-1) & (other-1)) + 1)
+        var this1 = _absSubSetSign(one, true);
+        var other1 = other._absSubSetSign(one, true);
+        // Result cannot be zero if this and a are negative.
+        return this1._absAndSetSign(other1, true)._absAddSetSign(one, true);
+      }
+      return _absOrSetSign(other, false);
+    }
+    // _neg != a._neg
+    var p, n;
+    if (_isNegative) {
+      p = other;
+      n = this;
+    } else {
+      // | is symmetric.
+      p = this;
+      n = other;
+    }
+    // p | (-n) == p | ~(n-1) == ~((n-1) &~ p) == -(~((n-1) &~ p) + 1)
+    var n1 = n._absSubSetSign(one, true);
+    // Result cannot be zero if only one of this or a is negative.
+    return n1._absAndNotSetSign(p, true)._absAddSetSign(one, true);
+  }
+
+  /// Bit-wise exclusive-or operator.
+  ///
+  /// Treating both `this` and [other] as sufficiently large two's component
+  /// integers, the result is a number with the bits set that are set in one,
+  /// but not both, of `this` and [other]
+  ///
+  /// If the operands have the same sign, the result is non-negative,
+  /// otherwise the result is negative.
+  _BigIntImpl operator ^(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (_isZero) return other;
+    if (other._isZero) return this;
+    if (_isNegative == other._isNegative) {
+      if (_isNegative) {
+        // (-this) ^ (-other) == ~(this-1) ^ ~(other-1) == (this-1) ^ (other-1)
+        var this1 = _absSubSetSign(one, true);
+        var other1 = other._absSubSetSign(one, true);
+        return this1._absXorSetSign(other1, false);
+      }
+      return _absXorSetSign(other, false);
+    }
+    // _isNegative != a._isNegative
+    var p, n;
+    if (_isNegative) {
+      p = other;
+      n = this;
+    } else {
+      // ^ is symmetric.
+      p = this;
+      n = other;
+    }
+    // p ^ (-n) == p ^ ~(n-1) == ~(p ^ (n-1)) == -((p ^ (n-1)) + 1)
+    var n1 = n._absSubSetSign(one, true);
+    // Result cannot be zero if only one of this or a is negative.
+    return p._absXorSetSign(n1, true)._absAddSetSign(one, true);
+  }
+
+  /// The bit-wise negate operator.
+  ///
+  /// Treating `this` as a sufficiently large two's component integer,
+  /// the result is a number with the opposite bits set.
+  ///
+  /// This maps any integer `x` to `-x - 1`.
+  _BigIntImpl operator ~() {
+    if (_isZero) return _minusOne;
+    if (_isNegative) {
+      // ~(-this) == ~(~(this-1)) == this-1
+      return _absSubSetSign(one, false);
+    }
+    // ~this == -this-1 == -(this+1)
+    // Result cannot be zero if this is positive.
+    return _absAddSetSign(one, true);
+  }
+
+  /// Addition operator.
+  _BigIntImpl operator +(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (_isZero) return other;
+    if (other._isZero) return this;
+    var isNegative = _isNegative;
+    if (isNegative == other._isNegative) {
+      // this + other == this + other
+      // (-this) + (-other) == -(this + other)
+      return _absAddSetSign(other, isNegative);
+    }
+    // this + (-other) == this - other == -(this - other)
+    // (-this) + other == other - this == -(this - other)
+    if (_absCompare(other) >= 0) {
+      return _absSubSetSign(other, isNegative);
+    }
+    return other._absSubSetSign(this, !isNegative);
+  }
+
+  /// Subtraction operator.
+  _BigIntImpl operator -(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (_isZero) return -other;
+    if (other._isZero) return this;
+    var isNegative = _isNegative;
+    if (isNegative != other._isNegative) {
+      // this - (-other) == this + other
+      // (-this) - other == -(this + other)
+      return _absAddSetSign(other, isNegative);
+    }
+    // this - other == this - a == -(this - other)
+    // (-this) - (-other) == other - this == -(this - other)
+    if (_absCompare(other) >= 0) {
+      return _absSubSetSign(other, isNegative);
+    }
+    return other._absSubSetSign(this, !isNegative);
+  }
+
+  /// Multiplies [x] with [multiplicandDigits] and adds the result to
+  /// [accumulatorDigits].
+  ///
+  /// The [multiplicandDigits] in the range [i] to [i]+[n]-1 are the
+  /// multiplicand digits.
+  ///
+  /// The [acculumatorDigits] in the range [j] to [j]+[n]-1 are the accumulator
+  /// digits.
+  ///
+  /// Adds the result of the multiplicand-digits * [x] to the accumulator.
+  ///
+  /// Concretely: `accumulatorDigits[j..j+n] += x * m_digits[i..i+n-1]`.
+  static void _mulAdd(int x, Uint16List multiplicandDigits, int i,
+      Uint16List accumulatorDigits, int j, int n) {
+    if (x == 0) {
+      // No-op if x is 0.
+      return;
+    }
+    int c = 0;
+    while (--n >= 0) {
+      int product = x * multiplicandDigits[i++];
+      int combined = product + accumulatorDigits[j] + c;
+      accumulatorDigits[j++] = combined & _digitMask;
+      // Note that this works with 53 bits, as the division will not lose
+      // bits.
+      c = combined ~/ _digitBase;
+    }
+    while (c != 0) {
+      int l = accumulatorDigits[j] + c;
+      accumulatorDigits[j++] = l & _digitMask;
+      c = l ~/ _digitBase;
+    }
+  }
+
+  /// Multiplication operator.
+  _BigIntImpl operator *(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    var used = _used;
+    var otherUsed = other._used;
+    if (used == 0 || otherUsed == 0) {
+      return zero;
+    }
+    var resultUsed = used + otherUsed;
+    var digits = _digits;
+    var otherDigits = other._digits;
+    var resultDigits = new Uint16List(resultUsed);
+    var i = 0;
+    while (i < otherUsed) {
+      _mulAdd(otherDigits[i], digits, 0, resultDigits, i, used);
+      i++;
+    }
+    return new _BigIntImpl._(
+        _isNegative != other._isNegative, resultUsed, resultDigits);
+  }
+
+  // r_digits[0..rUsed-1] = xDigits[0..xUsed-1]*otherDigits[0..otherUsed-1].
+  // Return resultUsed = xUsed + otherUsed.
+  static int _mulDigits(Uint16List xDigits, int xUsed, Uint16List otherDigits,
+      int otherUsed, Uint16List resultDigits) {
+    var resultUsed = xUsed + otherUsed;
+    var i = resultUsed;
+    assert(resultDigits.length >= i);
+    while (--i >= 0) {
+      resultDigits[i] = 0;
+    }
+    i = 0;
+    while (i < otherUsed) {
+      _mulAdd(otherDigits[i], xDigits, 0, resultDigits, i, xUsed);
+      i++;
+    }
+    return resultUsed;
+  }
+
+  /// Returns an estimate of `digits[i-1..i] ~/ topDigitDivisor`.
+  static int _estimateQuotientDigit(
+      int topDigitDivisor, Uint16List digits, int i) {
+    if (digits[i] == topDigitDivisor) return _digitMask;
+    var quotientDigit =
+        (digits[i] << _digitBits | digits[i - 1]) ~/ topDigitDivisor;
+    if (quotientDigit > _digitMask) return _digitMask;
+    return quotientDigit;
+  }
+
+  /// Returns `trunc(this / other)`, with `other != 0`.
+  _BigIntImpl _div(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    assert(other._used > 0);
+    if (_used < other._used) {
+      return zero;
+    }
+    _divRem(other);
+    // Return quotient, i.e.
+    // _lastQuoRem_digits[_lastRem_used.._lastQuoRem_used-1] with proper sign.
+    var lastQuo_used = _lastQuoRemUsed - _lastRemUsed;
+    var quo_digits = _cloneDigits(
+        _lastQuoRemDigits, _lastRemUsed, _lastQuoRemUsed, lastQuo_used);
+    var quo = new _BigIntImpl._(false, lastQuo_used, quo_digits);
+    if ((_isNegative != other._isNegative) && (quo._used > 0)) {
+      quo = -quo;
+    }
+    return quo;
+  }
+
+  /// Returns `this - other * trunc(this / other)`, with `other != 0`.
+  _BigIntImpl _rem(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    assert(other._used > 0);
+    if (_used < other._used) {
+      return this;
+    }
+    _divRem(other);
+    // Return remainder, i.e.
+    // denormalized _lastQuoRem_digits[0.._lastRem_used-1] with proper sign.
+    var remDigits =
+        _cloneDigits(_lastQuoRemDigits, 0, _lastRemUsed, _lastRemUsed);
+    var rem = new _BigIntImpl._(false, _lastRemUsed, remDigits);
+    if (_lastRem_nsh > 0) {
+      rem = rem >> _lastRem_nsh; // Denormalize remainder.
+    }
+    if (_isNegative && (rem._used > 0)) {
+      rem = -rem;
+    }
+    return rem;
+  }
+
+  /// Computes this ~/ other and this.remainder(other).
+  ///
+  /// Stores the result in [_lastQuoRemDigits], [_lastQuoRemUsed] and
+  /// [_lastRemUsed]. The [_lastQuoRemDigits] contains the digits of *both*, the
+  /// quotient and the remainder.
+  ///
+  /// Caches the input to avoid doing the work again when users write
+  /// `a ~/ b` followed by a `a % b`.
+  void _divRem(_BigIntImpl other) {
+    // Check if result is already cached.
+    if ((this._used == _lastDividendUsed) &&
+        (other._used == _lastDivisorUsed) &&
+        identical(this._digits, _lastDividendDigits) &&
+        identical(other._digits, _lastDivisorDigits)) {
+      return;
+    }
+    assert(_used >= other._used);
+
+    var nsh = _digitBits - other._digits[other._used - 1].bitLength;
+    // Concatenated positive quotient and normalized positive remainder.
+    // The resultDigits can have at most one more digit than the dividend.
+    Uint16List resultDigits;
+    int resultUsed;
+    // Normalized positive divisor.
+    // The normalized divisor has the most-significant bit of its most
+    // significant digit set.
+    // This makes estimating the quotient easier.
+    Uint16List yDigits;
+    int yUsed;
+    if (nsh > 0) {
+      yDigits = new Uint16List(other._used + 5);
+      yUsed = _lShiftDigits(other._digits, other._used, nsh, yDigits);
+      resultDigits = new Uint16List(_used + 5);
+      resultUsed = _lShiftDigits(_digits, _used, nsh, resultDigits);
+    } else {
+      yDigits = other._digits;
+      yUsed = other._used;
+      resultDigits = _cloneDigits(_digits, 0, _used, _used + 2);
+      resultUsed = _used;
+    }
+    var topDigitDivisor = yDigits[yUsed - 1];
+    var i = resultUsed;
+    var j = i - yUsed;
+    // tmpDigits is a temporary array of i (resultUsed) digits.
+    var tmpDigits = new Uint16List(i);
+    var tmpUsed = _dlShiftDigits(yDigits, yUsed, j, tmpDigits);
+    // Explicit first division step in case normalized dividend is larger or
+    // equal to shifted normalized divisor.
+    if (_compareDigits(resultDigits, resultUsed, tmpDigits, tmpUsed) >= 0) {
+      assert(i == resultUsed);
+      resultDigits[resultUsed++] = 1; // Quotient = 1.
+      // Subtract divisor from remainder.
+      _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+    } else {
+      // Account for possible carry in _mulAdd step.
+      resultDigits[resultUsed++] = 0;
+    }
+
+    // Negate y so we can later use _mulAdd instead of non-existent _mulSub.
+    var nyDigits = new Uint16List(yUsed + 2);
+    nyDigits[yUsed] = 1;
+    _absSub(nyDigits, yUsed + 1, yDigits, yUsed, nyDigits);
+    // nyDigits is read-only and has yUsed digits (possibly including several
+    // leading zeros).
+    // resultDigits is modified during iteration.
+    // resultDigits[0..yUsed-1] is the current remainder.
+    // resultDigits[yUsed..resultUsed-1] is the current quotient.
+    --i;
+
+    while (j > 0) {
+      var estimatedQuotientDigit =
+          _estimateQuotientDigit(topDigitDivisor, resultDigits, i);
+      j--;
+      _mulAdd(estimatedQuotientDigit, nyDigits, 0, resultDigits, j, yUsed);
+      if (resultDigits[i] < estimatedQuotientDigit) {
+        // Reusing the already existing tmpDigits array.
+        var tmpUsed = _dlShiftDigits(nyDigits, yUsed, j, tmpDigits);
+        _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+        while (resultDigits[i] < --estimatedQuotientDigit) {
+          _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+        }
+      }
+      i--;
+    }
+    // Cache result.
+    _lastDividendDigits = _digits;
+    _lastDividendUsed = _used;
+    _lastDivisorDigits = other._digits;
+    _lastDivisorUsed = other._used;
+    _lastQuoRemDigits = resultDigits;
+    _lastQuoRemUsed = resultUsed;
+    _lastRemUsed = yUsed;
+    _lastRem_nsh = nsh;
+  }
+
+  int get hashCode {
+    // This is the [Jenkins hash function][1] but using masking to keep
+    // values in SMI range.
+    //
+    // [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
+
+    int combine(int hash, int value) {
+      hash = 0x1fffffff & (hash + value);
+      hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
+      return hash ^ (hash >> 6);
+    }
+
+    int finish(int hash) {
+      hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
+      hash = hash ^ (hash >> 11);
+      return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
+    }
+
+    if (_isZero) return 6707; // Just a random number.
+    var hash = _isNegative ? 83585 : 429689; // Also random.
+    for (int i = 0; i < _used; i++) {
+      hash = combine(hash, _digits[i]);
+    }
+    return finish(hash);
+  }
+
+  /// Test whether this value is numerically equal to `other`.
+  ///
+  /// If [other] is a [_BigIntImpl] returns whether the two operands have the
+  /// same value.
+  ///
+  /// Returns false if `other` is not a [_BigIntImpl].
+  bool operator ==(Object other) =>
+      other is _BigIntImpl && compareTo(other) == 0;
+
+  /// Returns the minimum number of bits required to store this big integer.
+  ///
+  /// The number of bits excludes the sign bit, which gives the natural length
+  /// for non-negative (unsigned) values.  Negative values are complemented to
+  /// return the bit position of the first bit that differs from the sign bit.
+  ///
+  /// To find the number of bits needed to store the value as a signed value,
+  /// add one, i.e. use `x.bitLength + 1`.
+  ///
+  /// ```
+  /// x.bitLength == (-x-1).bitLength
+  ///
+  /// new BigInt.from(3).bitLength == 2;   // 00000011
+  /// new BigInt.from(2).bitLength == 2;   // 00000010
+  /// new BigInt.from(1).bitLength == 1;   // 00000001
+  /// new BigInt.from(0).bitLength == 0;   // 00000000
+  /// new BigInt.from(-1).bitLength == 0;  // 11111111
+  /// new BigInt.from(-2).bitLength == 1;  // 11111110
+  /// new BigInt.from(-3).bitLength == 2;  // 11111101
+  /// new BigInt.from(-4).bitLength == 2;  // 11111100
+  /// ```
+  int get bitLength {
+    if (_used == 0) return 0;
+    if (_isNegative) return (~this).bitLength;
+    return _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
+  }
+
+  /// Truncating division operator.
+  ///
+  /// Performs a truncating integer division, where the remainder is discarded.
+  ///
+  /// The remainder can be computed using the [remainder] method.
+  ///
+  /// Examples:
+  /// ```
+  /// var seven = new BigInt.from(7);
+  /// var three = new BigInt.from(3);
+  /// seven ~/ three;    // => 2
+  /// (-seven) ~/ three; // => -2
+  /// seven ~/ -three;   // => -2
+  /// seven.remainder(three);    // => 1
+  /// (-seven).remainder(three); // => -1
+  /// seven.remainder(-three);   // => 1
+  /// ```
+  _BigIntImpl operator ~/(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (other._used == 0) {
+      throw const IntegerDivisionByZeroException();
+    }
+    return _div(other);
+  }
+
+  /// Returns the remainder of the truncating division of `this` by [other].
+  ///
+  /// The result `r` of this operation satisfies:
+  /// `this == (this ~/ other) * other + r`.
+  /// As a consequence the remainder `r` has the same sign as the divider
+  /// `this`.
+  _BigIntImpl remainder(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (other._used == 0) {
+      throw const IntegerDivisionByZeroException();
+    }
+    return _rem(other);
+  }
+
+  /// Division operator.
+  double operator /(BigInt other) => this.toDouble() / other.toDouble();
+
+  /// Relational less than operator.
+  bool operator <(BigInt other) => compareTo(other) < 0;
+
+  /// Relational less than or equal operator.
+  bool operator <=(BigInt other) => compareTo(other) <= 0;
+
+  /// Relational greater than operator.
+  bool operator >(BigInt other) => compareTo(other) > 0;
+
+  /// Relational greater than or equal operator.
+  bool operator >=(BigInt other) => compareTo(other) >= 0;
+
+  /// Euclidean modulo operator.
+  ///
+  /// Returns the remainder of the Euclidean division. The Euclidean division of
+  /// two integers `a` and `b` yields two integers `q` and `r` such that
+  /// `a == b * q + r` and `0 <= r < b.abs()`.
+  ///
+  /// The sign of the returned value `r` is always positive.
+  ///
+  /// See [remainder] for the remainder of the truncating division.
+  _BigIntImpl operator %(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (other._used == 0) {
+      throw const IntegerDivisionByZeroException();
+    }
+    var result = _rem(other);
+    if (result._isNegative) {
+      if (other._isNegative) {
+        result = result - other;
+      } else {
+        result = result + other;
+      }
+    }
+    return result;
+  }
+
+  /// Returns the sign of this big integer.
+  ///
+  /// Returns 0 for zero, -1 for values less than zero and
+  /// +1 for values greater than zero.
+  int get sign {
+    if (_used == 0) return 0;
+    return _isNegative ? -1 : 1;
+  }
+
+  /// Whether this big integer is even.
+  bool get isEven => _used == 0 || (_digits[0] & 1) == 0;
+
+  /// Whether this big integer is odd.
+  bool get isOdd => !isEven;
+
+  /// Whether this number is negative.
+  bool get isNegative => _isNegative;
+
+  _BigIntImpl pow(int exponent) {
+    if (exponent < 0) {
+      throw new ArgumentError("Exponent must not be negative: $exponent");
+    }
+    if (exponent == 0) return one;
+
+    // Exponentiation by squaring.
+    var result = one;
+    var base = this;
+    while (exponent != 0) {
+      if ((exponent & 1) == 1) {
+        result *= base;
+      }
+      exponent >>= 1;
+      // Skip unnecessary operation.
+      if (exponent != 0) {
+        base *= base;
+      }
+    }
+    return result;
+  }
+
+  /// Returns this integer to the power of [exponent] modulo [modulus].
+  ///
+  /// The [exponent] must be non-negative and [modulus] must be
+  /// positive.
+  _BigIntImpl modPow(BigInt bigExponent, BigInt bigModulus) {
+    _BigIntImpl exponent = bigExponent;
+    _BigIntImpl modulus = bigModulus;
+    if (exponent._isNegative) {
+      throw new ArgumentError("exponent must be positive: $exponent");
+    }
+    if (modulus <= zero) {
+      throw new ArgumentError("modulus must be strictly positive: $modulus");
+    }
+    if (exponent._isZero) return one;
+
+    final modulusUsed = modulus._used;
+    final modulusUsed2p4 = 2 * modulusUsed + 4;
+    final exponentBitlen = exponent.bitLength;
+    if (exponentBitlen <= 0) return one;
+    _BigIntReduction z = new _BigIntClassic(modulus);
+    var resultDigits = new Uint16List(modulusUsed2p4);
+    var result2Digits = new Uint16List(modulusUsed2p4);
+    var gDigits = new Uint16List(modulusUsed);
+    var gUsed = z.convert(this, gDigits);
+    // Initialize result with g.
+    // Copy leading zero if any.
+    for (int j = gUsed - 1; j >= 0; j--) {
+      resultDigits[j] = gDigits[j];
+    }
+    var resultUsed = gUsed;
+    var result2Used;
+    for (int i = exponentBitlen - 2; i >= 0; i--) {
+      result2Used = z.sqr(resultDigits, resultUsed, result2Digits);
+      if (!(exponent & (one << i))._isZero) {
+        resultUsed =
+            z.mul(result2Digits, result2Used, gDigits, gUsed, resultDigits);
+      } else {
+        // Swap result and result2.
+        var tmpDigits = resultDigits;
+        var tmpUsed = resultUsed;
+        resultDigits = result2Digits;
+        resultUsed = result2Used;
+        result2Digits = tmpDigits;
+        result2Used = tmpUsed;
+      }
+    }
+    return z.revert(resultDigits, resultUsed);
+  }
+
+  // If inv is false, returns gcd(x, y).
+  // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1.
+  // If inv is true and gcd(x, y) != 1, throws Exception("Not coprime").
+  static _BigIntImpl _binaryGcd(_BigIntImpl x, _BigIntImpl y, bool inv) {
+    var xDigits = x._digits;
+    var yDigits = y._digits;
+    var xUsed = x._used;
+    var yUsed = y._used;
+    var maxUsed = xUsed > yUsed ? xUsed : yUsed;
+    var unshiftedMaxUsed = maxUsed; // Keep
+    xDigits = _cloneDigits(xDigits, 0, xUsed, maxUsed);
+    yDigits = _cloneDigits(yDigits, 0, yUsed, maxUsed);
+    int shiftAmount = 0;
+    if (inv) {
+      if ((yUsed == 1) && (yDigits[0] == 1)) return one;
+      if ((yUsed == 0) || (yDigits[0].isEven && xDigits[0].isEven)) {
+        throw new Exception("Not coprime");
+      }
+    } else {
+      if (x._isZero) {
+        throw new ArgumentError.value(0, "this", "must not be zero");
+      }
+      if (y._isZero) {
+        throw new ArgumentError.value(0, "other", "must not be zero");
+      }
+      if (((xUsed == 1) && (xDigits[0] == 1)) ||
+          ((yUsed == 1) && (yDigits[0] == 1))) return one;
+      while (((xDigits[0] & 1) == 0) && ((yDigits[0] & 1) == 0)) {
+        _rsh(xDigits, xUsed, 1, xDigits);
+        _rsh(yDigits, yUsed, 1, yDigits);
+        shiftAmount++;
+      }
+      if (shiftAmount >= _digitBits) {
+        var digitShiftAmount = shiftAmount ~/ _digitBits;
+        xUsed -= digitShiftAmount;
+        yUsed -= digitShiftAmount;
+        maxUsed -= digitShiftAmount;
+      }
+      if ((yDigits[0] & 1) == 1) {
+        // Swap x and y.
+        var tmpDigits = xDigits;
+        var tmpUsed = xUsed;
+        xDigits = yDigits;
+        xUsed = yUsed;
+        yDigits = tmpDigits;
+        yUsed = tmpUsed;
+      }
+    }
+    var uDigits = _cloneDigits(xDigits, 0, xUsed, unshiftedMaxUsed);
+    var vDigits =
+        _cloneDigits(yDigits, 0, yUsed, unshiftedMaxUsed + 2); // +2 for lsh.
+    final bool ac = (xDigits[0] & 1) == 0;
+
+    // Variables a, b, c, and d require one more digit.
+    final abcdUsed = maxUsed + 1;
+    final abcdLen = abcdUsed + 2; // +2 to satisfy _absAdd.
+    var aDigits, bDigits, cDigits, dDigits;
+    bool aIsNegative, bIsNegative, cIsNegative, dIsNegative;
+    if (ac) {
+      aDigits = new Uint16List(abcdLen);
+      aIsNegative = false;
+      aDigits[0] = 1;
+      cDigits = new Uint16List(abcdLen);
+      cIsNegative = false;
+    }
+    bDigits = new Uint16List(abcdLen);
+    bIsNegative = false;
+    dDigits = new Uint16List(abcdLen);
+    dIsNegative = false;
+    dDigits[0] = 1;
+
+    while (true) {
+      while ((uDigits[0] & 1) == 0) {
+        _rsh(uDigits, maxUsed, 1, uDigits);
+        if (ac) {
+          if (((aDigits[0] & 1) == 1) || ((bDigits[0] & 1) == 1)) {
+            // a += y
+            if (aIsNegative) {
+              if ((aDigits[maxUsed] != 0) ||
+                  (_compareDigits(aDigits, maxUsed, yDigits, maxUsed)) > 0) {
+                _absSub(aDigits, abcdUsed, yDigits, maxUsed, aDigits);
+              } else {
+                _absSub(yDigits, maxUsed, aDigits, maxUsed, aDigits);
+                aIsNegative = false;
+              }
+            } else {
+              _absAdd(aDigits, abcdUsed, yDigits, maxUsed, aDigits);
+            }
+            // b -= x
+            if (bIsNegative) {
+              _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+            } else if ((bDigits[maxUsed] != 0) ||
+                (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) {
+              _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+            } else {
+              _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits);
+              bIsNegative = true;
+            }
+          }
+          _rsh(aDigits, abcdUsed, 1, aDigits);
+        } else if ((bDigits[0] & 1) == 1) {
+          // b -= x
+          if (bIsNegative) {
+            _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+          } else if ((bDigits[maxUsed] != 0) ||
+              (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) {
+            _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+          } else {
+            _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits);
+            bIsNegative = true;
+          }
+        }
+        _rsh(bDigits, abcdUsed, 1, bDigits);
+      }
+      while ((vDigits[0] & 1) == 0) {
+        _rsh(vDigits, maxUsed, 1, vDigits);
+        if (ac) {
+          if (((cDigits[0] & 1) == 1) || ((dDigits[0] & 1) == 1)) {
+            // c += y
+            if (cIsNegative) {
+              if ((cDigits[maxUsed] != 0) ||
+                  (_compareDigits(cDigits, maxUsed, yDigits, maxUsed) > 0)) {
+                _absSub(cDigits, abcdUsed, yDigits, maxUsed, cDigits);
+              } else {
+                _absSub(yDigits, maxUsed, cDigits, maxUsed, cDigits);
+                cIsNegative = false;
+              }
+            } else {
+              _absAdd(cDigits, abcdUsed, yDigits, maxUsed, cDigits);
+            }
+            // d -= x
+            if (dIsNegative) {
+              _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+            } else if ((dDigits[maxUsed] != 0) ||
+                (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+              _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+            } else {
+              _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+              dIsNegative = true;
+            }
+          }
+          _rsh(cDigits, abcdUsed, 1, cDigits);
+        } else if ((dDigits[0] & 1) == 1) {
+          // d -= x
+          if (dIsNegative) {
+            _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+          } else if ((dDigits[maxUsed] != 0) ||
+              (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+            _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+          } else {
+            _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+            dIsNegative = true;
+          }
+        }
+        _rsh(dDigits, abcdUsed, 1, dDigits);
+      }
+      if (_compareDigits(uDigits, maxUsed, vDigits, maxUsed) >= 0) {
+        // u -= v
+        _absSub(uDigits, maxUsed, vDigits, maxUsed, uDigits);
+        if (ac) {
+          // a -= c
+          if (aIsNegative == cIsNegative) {
+            var a_cmp_c = _compareDigits(aDigits, abcdUsed, cDigits, abcdUsed);
+            if (a_cmp_c > 0) {
+              _absSub(aDigits, abcdUsed, cDigits, abcdUsed, aDigits);
+            } else {
+              _absSub(cDigits, abcdUsed, aDigits, abcdUsed, aDigits);
+              aIsNegative = !aIsNegative && (a_cmp_c != 0);
+            }
+          } else {
+            _absAdd(aDigits, abcdUsed, cDigits, abcdUsed, aDigits);
+          }
+        }
+        // b -= d
+        if (bIsNegative == dIsNegative) {
+          var b_cmp_d = _compareDigits(bDigits, abcdUsed, dDigits, abcdUsed);
+          if (b_cmp_d > 0) {
+            _absSub(bDigits, abcdUsed, dDigits, abcdUsed, bDigits);
+          } else {
+            _absSub(dDigits, abcdUsed, bDigits, abcdUsed, bDigits);
+            bIsNegative = !bIsNegative && (b_cmp_d != 0);
+          }
+        } else {
+          _absAdd(bDigits, abcdUsed, dDigits, abcdUsed, bDigits);
+        }
+      } else {
+        // v -= u
+        _absSub(vDigits, maxUsed, uDigits, maxUsed, vDigits);
+        if (ac) {
+          // c -= a
+          if (cIsNegative == aIsNegative) {
+            var c_cmp_a = _compareDigits(cDigits, abcdUsed, aDigits, abcdUsed);
+            if (c_cmp_a > 0) {
+              _absSub(cDigits, abcdUsed, aDigits, abcdUsed, cDigits);
+            } else {
+              _absSub(aDigits, abcdUsed, cDigits, abcdUsed, cDigits);
+              cIsNegative = !cIsNegative && (c_cmp_a != 0);
+            }
+          } else {
+            _absAdd(cDigits, abcdUsed, aDigits, abcdUsed, cDigits);
+          }
+        }
+        // d -= b
+        if (dIsNegative == bIsNegative) {
+          var d_cmp_b = _compareDigits(dDigits, abcdUsed, bDigits, abcdUsed);
+          if (d_cmp_b > 0) {
+            _absSub(dDigits, abcdUsed, bDigits, abcdUsed, dDigits);
+          } else {
+            _absSub(bDigits, abcdUsed, dDigits, abcdUsed, dDigits);
+            dIsNegative = !dIsNegative && (d_cmp_b != 0);
+          }
+        } else {
+          _absAdd(dDigits, abcdUsed, bDigits, abcdUsed, dDigits);
+        }
+      }
+      // Exit loop if u == 0.
+      var i = maxUsed;
+      while ((i > 0) && (uDigits[i - 1] == 0)) --i;
+      if (i == 0) break;
+    }
+    if (!inv) {
+      if (shiftAmount > 0) {
+        maxUsed = _lShiftDigits(vDigits, maxUsed, shiftAmount, vDigits);
+      }
+      return new _BigIntImpl._(false, maxUsed, vDigits);
+    }
+    // No inverse if v != 1.
+    var i = maxUsed - 1;
+    while ((i > 0) && (vDigits[i] == 0)) --i;
+    if ((i != 0) || (vDigits[0] != 1)) {
+      throw new Exception("Not coprime");
+    }
+
+    if (dIsNegative) {
+      while ((dDigits[maxUsed] != 0) ||
+          (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+        // d += x, d still negative
+        _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+      }
+      // d += x
+      _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+      dIsNegative = false;
+    } else {
+      while ((dDigits[maxUsed] != 0) ||
+          (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) >= 0)) {
+        // d -= x
+        _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+      }
+    }
+    return new _BigIntImpl._(false, maxUsed, dDigits);
+  }
+
+  /// Returns the modular multiplicative inverse of this big integer
+  /// modulo [modulus].
+  ///
+  /// The [modulus] must be positive.
+  ///
+  /// It is an error if no modular inverse exists.
+  // Returns 1/this % modulus, with modulus > 0.
+  _BigIntImpl modInverse(BigInt bigInt) {
+    _BigIntImpl modulus = bigInt;
+    if (modulus <= zero) {
+      throw new ArgumentError("Modulus must be strictly positive: $modulus");
+    }
+    if (modulus == one) return zero;
+    var tmp = this;
+    if (tmp._isNegative || (tmp._absCompare(modulus) >= 0)) {
+      tmp %= modulus;
+    }
+    return _binaryGcd(modulus, tmp, true);
+  }
+
+  /// Returns the greatest common divisor of this big integer and [other].
+  ///
+  /// If either number is non-zero, the result is the numerically greatest
+  /// integer dividing both `this` and `other`.
+  ///
+  /// The greatest common divisor is independent of the order,
+  /// so `x.gcd(y)` is  always the same as `y.gcd(x)`.
+  ///
+  /// For any integer `x`, `x.gcd(x)` is `x.abs()`.
+  ///
+  /// If both `this` and `other` is zero, the result is also zero.
+  _BigIntImpl gcd(BigInt bigInt) {
+    _BigIntImpl other = bigInt;
+    if (_isZero) return other.abs();
+    if (other._isZero) return this.abs();
+    return _binaryGcd(this, other, false);
+  }
+
+  /// Returns the least significant [width] bits of this big integer as a
+  /// non-negative number (i.e. unsigned representation).  The returned value
+  /// has zeros in all bit positions higher than [width].
+  ///
+  /// ```
+  /// new BigInt.from(-1).toUnsigned(5) == 31   // 11111111  ->  00011111
+  /// ```
+  ///
+  /// This operation can be used to simulate arithmetic from low level
+  /// languages.  For example, to increment an 8 bit quantity:
+  ///
+  /// ```
+  /// q = (q + 1).toUnsigned(8);
+  /// ```
+  ///
+  /// `q` will count from `0` up to `255` and then wrap around to `0`.
+  ///
+  /// If the input fits in [width] bits without truncation, the result is the
+  /// same as the input.  The minimum width needed to avoid truncation of `x` is
+  /// given by `x.bitLength`, i.e.
+  ///
+  /// ```
+  /// x == x.toUnsigned(x.bitLength);
+  /// ```
+  _BigIntImpl toUnsigned(int width) {
+    return this & ((one << width) - one);
+  }
+
+  /// Returns the least significant [width] bits of this integer, extending the
+  /// highest retained bit to the sign.  This is the same as truncating the
+  /// value to fit in [width] bits using an signed 2-s complement
+  /// representation.  The returned value has the same bit value in all
+  /// positions higher than [width].
+  ///
+  /// ```
+  /// var big15 = new BigInt.from(15);
+  /// var big16 = new BigInt.from(16);
+  /// var big239 = new BigInt.from(239);
+  ///                                      V--sign bit-V
+  /// big16.toSigned(5) == -big16   //  00010000 -> 11110000
+  /// big239.toSigned(5) == big15   //  11101111 -> 00001111
+  ///                                      ^           ^
+  /// ```
+  ///
+  /// This operation can be used to simulate arithmetic from low level
+  /// languages.  For example, to increment an 8 bit signed quantity:
+  ///
+  /// ```
+  /// q = (q + 1).toSigned(8);
+  /// ```
+  ///
+  /// `q` will count from `0` up to `127`, wrap to `-128` and count back up to
+  /// `127`.
+  ///
+  /// If the input value fits in [width] bits without truncation, the result is
+  /// the same as the input.  The minimum width needed to avoid truncation of
+  /// `x` is `x.bitLength + 1`, i.e.
+  ///
+  /// ```
+  /// x == x.toSigned(x.bitLength + 1);
+  /// ```
+  _BigIntImpl toSigned(int width) {
+    // The value of binary number weights each bit by a power of two.  The
+    // twos-complement value weights the sign bit negatively.  We compute the
+    // value of the negative weighting by isolating the sign bit with the
+    // correct power of two weighting and subtracting it from the value of the
+    // lower bits.
+    var signMask = one << (width - 1);
+    return (this & (signMask - one)) - (this & signMask);
+  }
+
+  // Maximum number of digits that always fit in mantissa.
+  static const _simpleValidIntDigits = 53 ~/ _digitBits;
+
+  bool get isValidInt {
+    if (_used <= _simpleValidIntDigits) return true;
+    var asInt = toInt();
+    if (!asInt.toDouble().isFinite) return false;
+    return this == new _BigIntImpl._fromInt(asInt);
+  }
+
+  int toInt() {
+    var result = 0;
+    for (int i = _used - 1; i >= 0; i--) {
+      result = result * _digitBase + _digits[i];
+    }
+    return _isNegative ? -result : result;
+  }
+
+  /// Returns this [_BigIntImpl] as a [double].
+  ///
+  /// If the number is not representable as a [double], an
+  /// approximation is returned. For numerically large integers, the
+  /// approximation may be infinite.
+  double toDouble() {
+    const int exponentBias = 1075;
+    // There are 11 bits for the exponent.
+    // 2047 (all bits set to 1) is reserved for infinity and NaN.
+    // When storing the exponent in the 11 bits, it is biased by exponentBias
+    // to support negative exponents.
+    const int maxDoubleExponent = 2046 - exponentBias;
+    if (_isZero) return 0.0;
+
+    // We fill the 53 bits little-endian.
+    var resultBits = new Uint8List(8);
+
+    var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
+    if (length > maxDoubleExponent + 53) {
+      return _isNegative ? double.negativeInfinity : double.infinity;
+    }
+
+    // The most significant bit is for the sign.
+    if (_isNegative) resultBits[7] = 0x80;
+
+    // Write the exponent into bits 1..12:
+    var biasedExponent = length - 53 + exponentBias;
+    resultBits[6] = (biasedExponent & 0xF) << 4;
+    resultBits[7] |= biasedExponent >> 4;
+
+    int cachedBits = 0;
+    int cachedBitsLength = 0;
+    int digitIndex = _used - 1;
+    int readBits(int n) {
+      // Ensure that we have enough bits in [cachedBits].
+      while (cachedBitsLength < n) {
+        int nextDigit;
+        int nextDigitLength = _digitBits; // May get updated.
+        if (digitIndex < 0) {
+          nextDigit = 0;
+          digitIndex--;
+        } else {
+          nextDigit = _digits[digitIndex];
+          if (digitIndex == _used - 1) nextDigitLength = nextDigit.bitLength;
+          digitIndex--;
+        }
+        cachedBits = (cachedBits << nextDigitLength) + nextDigit;
+        cachedBitsLength += nextDigitLength;
+      }
+      // Read the top [n] bits.
+      var result = cachedBits >> (cachedBitsLength - n);
+      // Remove the bits from the cache.
+      cachedBits -= result << (cachedBitsLength - n);
+      cachedBitsLength -= n;
+      return result;
+    }
+
+    // The first leading 1 bit is implicit in the double-representation and can
+    // be discarded.
+    var leadingBits = readBits(5) & 0xF;
+    resultBits[6] |= leadingBits;
+
+    for (int i = 5; i >= 0; i--) {
+      // Get the remaining 48 bits.
+      resultBits[i] = readBits(8);
+    }
+
+    void roundUp() {
+      // Simply consists of adding 1 to the whole 64 bit "number".
+      // It will update the exponent, if necessary.
+      // It might even round up to infinity (which is what we want).
+      var carry = 1;
+      for (int i = 0; i < 8; i++) {
+        if (carry == 0) break;
+        var sum = resultBits[i] + carry;
+        resultBits[i] = sum & 0xFF;
+        carry = sum >> 8;
+      }
+    }
+
+    if (readBits(1) == 1) {
+      if (resultBits[0].isOdd) {
+        // Rounds to even all the time.
+        roundUp();
+      } else {
+        // Round up, if there is at least one other digit that is not 0.
+        if (cachedBits != 0) {
+          // There is already one in the cachedBits.
+          roundUp();
+        } else {
+          for (int i = digitIndex; digitIndex >= 0; i--) {
+            if (_digits[i] != 0) {
+              roundUp();
+              break;
+            }
+          }
+        }
+      }
+    }
+    return resultBits.buffer.asByteData().getFloat64(0, Endian.little);
+  }
+
+  /// Returns a String-representation of this integer.
+  ///
+  /// The returned string is parsable by [parse].
+  /// For any `_BigIntImpl` `i`, it is guaranteed that
+  /// `i == _BigIntImpl.parse(i.toString())`.
+  String toString() {
+    if (_used == 0) return "0";
+    if (_used == 1) {
+      if (_isNegative) return (-_digits[0]).toString();
+      return _digits[0].toString();
+    }
+
+    // Generate in chunks of 4 digits.
+    // The chunks are in reversed order.
+    var decimalDigitChunks = <String>[];
+    var rest = isNegative ? -this : this;
+    while (rest._used > 1) {
+      var digits4 = rest.remainder(_bigInt10000).toString();
+      decimalDigitChunks.add(digits4);
+      if (digits4.length == 1) decimalDigitChunks.add("000");
+      if (digits4.length == 2) decimalDigitChunks.add("00");
+      if (digits4.length == 3) decimalDigitChunks.add("0");
+      rest = rest ~/ _bigInt10000;
+    }
+    decimalDigitChunks.add(rest._digits[0].toString());
+    if (_isNegative) decimalDigitChunks.add("-");
+    return decimalDigitChunks.reversed.join();
+  }
+
+  int _toRadixCodeUnit(int digit) {
+    const int _0 = 48;
+    const int _a = 97;
+    if (digit < 10) return _0 + digit;
+    return _a + digit - 10;
+  }
+
+  /// Converts [this] to a string representation in the given [radix].
+  ///
+  /// In the string representation, lower-case letters are used for digits above
+  /// '9', with 'a' being 10 an 'z' being 35.
+  ///
+  /// The [radix] argument must be an integer in the range 2 to 36.
+  String toRadixString(int radix) {
+    if (radix > 36) throw new RangeError.range(radix, 2, 36);
+
+    if (_used == 0) return "0";
+
+    if (_used == 1) {
+      var digitString = _digits[0].toRadixString(radix);
+      if (_isNegative) return "-" + digitString;
+      return digitString;
+    }
+
+    if (radix == 16) return _toHexString();
+
+    var base = new _BigIntImpl._fromInt(radix);
+    var reversedDigitCodeUnits = <int>[];
+    var rest = this.abs();
+    while (!rest._isZero) {
+      var digit = rest.remainder(base).toInt();
+      rest = rest ~/ base;
+      reversedDigitCodeUnits.add(_toRadixCodeUnit(digit));
+    }
+    var digitString = new String.fromCharCodes(reversedDigitCodeUnits.reversed);
+    if (_isNegative) return "-" + digitString;
+    return digitString;
+  }
+
+  String _toHexString() {
+    var chars = <int>[];
+    for (int i = 0; i < _used - 1; i++) {
+      int chunk = _digits[i];
+      for (int j = 0; j < (_digitBits ~/ 4); j++) {
+        chars.add(_toRadixCodeUnit(chunk & 0xF));
+        chunk >>= 4;
+      }
+    }
+    var msbChunk = _digits[_used - 1];
+    while (msbChunk != 0) {
+      chars.add(_toRadixCodeUnit(msbChunk & 0xF));
+      msbChunk >>= 4;
+    }
+    if (_isNegative) {
+      const _dash = 45;
+      chars.add(_dash);
+    }
+    return new String.fromCharCodes(chars.reversed);
+  }
+}
+
+// Interface for modular reduction.
+abstract class _BigIntReduction {
+  // Return the number of digits used by r_digits.
+  int convert(_BigIntImpl x, Uint16List r_digits);
+  int mul(Uint16List xDigits, int xUsed, Uint16List yDigits, int yUsed,
+      Uint16List resultDigits);
+  int sqr(Uint16List xDigits, int xUsed, Uint16List resultDigits);
+
+  // Return x reverted to _BigIntImpl.
+  _BigIntImpl revert(Uint16List xDigits, int xUsed);
+}
+
+// Modular reduction using "classic" algorithm.
+class _BigIntClassic implements _BigIntReduction {
+  final _BigIntImpl _modulus; // Modulus.
+  final _BigIntImpl _normalizedModulus; // Normalized _modulus.
+
+  _BigIntClassic(this._modulus)
+      : _normalizedModulus = _modulus <<
+            (_BigIntImpl._digitBits -
+                _modulus._digits[_modulus._used - 1].bitLength);
+
+  int convert(_BigIntImpl x, Uint16List resultDigits) {
+    var digits;
+    var used;
+    if (x._isNegative || x._absCompare(_modulus) >= 0) {
+      var remainder = x._rem(_modulus);
+      if (x._isNegative && remainder._used > 0) {
+        assert(remainder._isNegative);
+        remainder += _modulus;
+      }
+      assert(!remainder._isNegative);
+      used = remainder._used;
+      digits = remainder._digits;
+    } else {
+      used = x._used;
+      digits = x._digits;
+    }
+    var i = used; // Copy leading zero if any.
+    while (--i >= 0) {
+      resultDigits[i] = digits[i];
+    }
+    return used;
+  }
+
+  _BigIntImpl revert(Uint16List xDigits, int xUsed) {
+    return new _BigIntImpl._(false, xUsed, xDigits);
+  }
+
+  int _reduce(Uint16List xDigits, int xUsed) {
+    if (xUsed < _modulus._used) {
+      return xUsed;
+    }
+    var reverted = revert(xDigits, xUsed);
+    var rem = reverted._rem(_normalizedModulus);
+    return convert(rem, xDigits);
+  }
+
+  int sqr(Uint16List xDigits, int xUsed, Uint16List resultDigits) {
+    var b = new _BigIntImpl._(false, xUsed, xDigits);
+    var b2 = b * b;
+    for (int i = 0; i < b2._used; i++) {
+      resultDigits[i] = b2._digits[i];
+    }
+    for (int i = b2._used; i < 2 * xUsed; i++) {
+      resultDigits[i] = 0;
+    }
+    return _reduce(resultDigits, 2 * xUsed);
+  }
+
+  int mul(Uint16List xDigits, int xUsed, Uint16List yDigits, int yUsed,
+      Uint16List resultDigits) {
+    var resultUsed =
+        _BigIntImpl._mulDigits(xDigits, xUsed, yDigits, yUsed, resultDigits);
+    return _reduce(resultDigits, resultUsed);
+  }
+}
+
+/// Creates an invocation object used in noSuchMethod forwarding stubs.
+///
+/// The signature is hardwired to the kernel nodes generated in the
+/// `Dart2jsTarget` and read in the `KernelSsaGraphBuilder`.
+external Invocation _createInvocationMirror(
+    String memberName,
+    List typeArguments,
+    List positionalArguments,
+    Map<String, dynamic> namedArguments,
+    int kind);
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/developer_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/developer_patch.dart
new file mode 100644
index 0000000..0ff0f66
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/developer_patch.dart
@@ -0,0 +1,172 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Patch file for dart:developer library.
+
+import 'dart:_js_helper' show patch, ForceInline;
+import 'dart:_foreign_helper' show JS;
+import 'dart:async' show Zone;
+import 'dart:isolate';
+
+@patch
+@pragma('dart2js:tryInline')
+bool debugger({bool when: true, String message}) {
+  if (when) {
+    JS('', 'debugger');
+  }
+  return when;
+}
+
+@patch
+Object inspect(Object object) {
+  return object;
+}
+
+@patch
+void log(String message,
+    {DateTime time,
+    int sequenceNumber,
+    int level: 0,
+    String name: '',
+    Zone zone,
+    Object error,
+    StackTrace stackTrace}) {
+  // TODO.
+}
+
+final _extensions = new Map<String, ServiceExtensionHandler>();
+
+@patch
+ServiceExtensionHandler _lookupExtension(String method) {
+  return _extensions[method];
+}
+
+@patch
+_registerExtension(String method, ServiceExtensionHandler handler) {
+  _extensions[method] = handler;
+}
+
+@patch
+void _postEvent(String eventKind, String eventData) {
+  // TODO.
+}
+
+@patch
+bool _isDartStreamEnabled() {
+  return false;
+}
+
+@patch
+int _getTraceClock() {
+  // TODO.
+  return _clockValue++;
+}
+
+int _clockValue = 0;
+
+@patch
+int _getThreadCpuClock() {
+  return -1;
+}
+
+@patch
+void _reportCompleteEvent(int start, int startCpu, String category, String name,
+    String argumentsAsJson) {
+  // TODO.
+}
+
+@patch
+void _reportFlowEvent(int start, int startCpu, String category, String name,
+    int type, int id, String argumentsAsJson) {
+  // TODO.
+}
+
+@patch
+void _reportInstantEvent(
+    int start, String category, String name, String argumentsAsJson) {
+  // TODO.
+}
+
+@patch
+int _getNextAsyncId() {
+  return 0;
+}
+
+@patch
+void _reportTaskEvent(int start, int taskId, String phase, String category,
+    String name, String argumentsAsJson) {
+  // TODO.
+}
+
+@patch
+int _getServiceMajorVersion() {
+  return 0;
+}
+
+@patch
+int _getServiceMinorVersion() {
+  return 0;
+}
+
+@patch
+void _getServerInfo(SendPort sendPort) {
+  sendPort.send(null);
+}
+
+@patch
+void _webServerControl(SendPort sendPort, bool enable) {
+  sendPort.send(null);
+}
+
+@patch
+String _getIsolateIDFromSendPort(SendPort sendPort) {
+  return null;
+}
+
+@patch
+class UserTag {
+  @patch
+  factory UserTag(String label) = _FakeUserTag;
+
+  @patch
+  static UserTag get defaultTag => _FakeUserTag._defaultTag;
+}
+
+class _FakeUserTag implements UserTag {
+  static Map _instances = {};
+
+  _FakeUserTag.real(this.label);
+
+  factory _FakeUserTag(String label) {
+    // Canonicalize by name.
+    var existingTag = _instances[label];
+    if (existingTag != null) {
+      return existingTag;
+    }
+    // Throw an exception if we've reached the maximum number of user tags.
+    if (_instances.length == UserTag.MAX_USER_TAGS) {
+      throw new UnsupportedError(
+          'UserTag instance limit (${UserTag.MAX_USER_TAGS}) reached.');
+    }
+    // Create a new instance and add it to the instance map.
+    var instance = new _FakeUserTag.real(label);
+    _instances[label] = instance;
+    return instance;
+  }
+
+  final String label;
+
+  UserTag makeCurrent() {
+    var old = _currentTag;
+    _currentTag = this;
+    return old;
+  }
+
+  static final UserTag _defaultTag = new _FakeUserTag('Default');
+}
+
+var _currentTag = _FakeUserTag._defaultTag;
+
+@patch
+UserTag getCurrentTag() => _currentTag;
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/foreign_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/foreign_helper.dart
new file mode 100644
index 0000000..0cecf96
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/foreign_helper.dart
@@ -0,0 +1,272 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library _foreign_helper;
+
+import 'dart:_js_embedded_names' show JsGetName, JsBuiltin;
+
+/// Emits a JavaScript code fragment parametrized by arguments.
+///
+/// Hash characters `#` in the [codeTemplate] are replaced in left-to-right
+/// order with expressions that contain the values of, or evaluate to, the
+/// arguments.  The number of hash marks must match the number or arguments.
+/// Although declared with arguments [arg0] through [arg2], the form actually
+/// has no limit on the number of arguments.
+///
+/// The [typeDescription] argument is interpreted as a description of the
+/// behavior of the JavaScript code.  Currently it describes the side effects
+/// types that may be returned by the expression, with the additional behavior
+/// that the returned values may be fresh instances of the types.  The type
+/// information must be correct as it is trusted by the compiler in
+/// optimizations, and it must be precise as possible since it is used for
+/// native live type analysis to tree-shake large parts of the DOM libraries.
+/// If poorly written, the [typeDescription] will cause unnecessarily bloated
+/// programs.  (You can check for this by compiling with `--verbose`; there is
+/// an info message describing the number of native (DOM) types that can be
+/// removed, which usually should be greater than zero.)
+///
+/// The [typeDescription] must be a [String]. Two forms of it are supported:
+///
+/// 1) a union of types separated by vertical bar `|` symbols, e.g.
+///    `"num|String"` describes the union of numbers and Strings.  There is no
+///    type in Dart that is this precise.  The Dart alternative would be
+///    `Object` or `dynamic`, but these types imply that the JS-code might also
+///    be creating instances of all the DOM types.
+///
+///    If `null` is possible, it must be specified explicitly, e.g.
+///    `"String|Null"`. [typeDescription] has several extensions to help
+///    describe the behavior more accurately.  In addition to the union type
+///    already described:
+///
+///    + `=Object` is a plain JavaScript object.  Some DOM methods return
+///       instances that have no corresponding Dart type (e.g. cross-frame
+///       documents), `=Object` can be used to describe these untyped' values.
+///
+///    + `var` or empty string.  If the entire [typeDescription] is `var` (or
+///      empty string) then the type is `dynamic` but the code is known to not
+///      create any instances.
+///
+///   Examples:
+///
+///       // Parent window might be an opaque cross-frame window.
+///       var thing = JS('=Object|Window', '#.parent', myWindow);
+///
+/// 2) a sequence of the form `<tag>:<value>;` where `<tag>` is one of
+///    `creates`, `returns`, `effects` or `depends`.
+///
+///    The first two tags are used to specify the created and returned types of
+///    the expression. The value of `creates` and `returns` is a type string as
+///    defined in 1).
+///
+///    The tags `effects` and `depends` encode the side effects of this call.
+///    They can be omitted, in which case the expression is parsed and a safe
+///    conservative side-effect estimation is computed.
+///
+///    The values of `effects` and `depends` may be 'all', 'none' or a
+///    comma-separated list of 'no-index', 'no-instance' and 'no-static'.
+///
+///    The value 'all' indicates that the call affects/depends on every
+///    side-effect. The flag 'none' signals that the call does not affect
+///    (resp. depends on) anything.
+///
+///    The value 'no-index' indicates that the call does *not* do (resp. depends
+///    on) any array index-store. The flag 'no-instance' indicates that the call
+///    does not modify (resp. depends on) any instance variable. Similarly,
+///    the 'no-static' value indicates that the call does not modify (resp.
+///    depends on) any static variable.
+///
+///    The `effects` and `depends` flag must be used in tandem. Either both are
+///    specified or none is.
+///
+///    Each tag (including the type tags) may only occur once in the sequence.
+///
+/// Guidelines:
+///
+///  + Do not use any parameter, local, method or field names in the
+///    [codeTemplate].  These names are all subject to arbitrary renaming by the
+///    compiler.  Pass the values in via `#` substition, and test with the
+///    `--minify` dart2js command-line option.
+///
+///  + The substituted expressions are values, not locations.
+///
+///        JS('void', '# += "x"', this.field);
+///
+///    `this.field` might not be a substituted as a reference to the field.  The
+///    generated code might accidentally work as intended, but it also might be
+///
+///        var t1 = this.field;
+///        t1 += "x";
+///
+///    or
+///
+///        this.get$field() += "x";
+///
+///    The remedy in this case is to expand the `+=` operator, leaving all
+///    references to the Dart field as Dart code:
+///
+///        this.field = JS('String', '# + "x"', this.field);
+///
+///  + Never use `#` in function bodies.
+///
+///    This is a variation on the previous guideline.  Since `#` is replaced
+///    with an *expression* and the expression is only valid in the immediate
+///    context, `#` should never appear in a function body.  Doing so might
+///    defer the evaluation of the expression, and its side effects, until the
+///    function is called.
+///
+///    For example,
+///
+///        var value = foo();
+///        var f = JS('', 'function(){return #}', value)
+///
+///    might result in no immediate call to `foo` and a call to `foo` on every
+///    call to the JavaScript function bound to `f`.  This is better:
+///
+///        var f = JS('',
+///            '(function(val) { return function(){return val}; })(#)', value);
+///
+///    Since `#` occurs in the immediately evaluated expression, the expression
+///    is immediately evaluated and bound to `val` in the immediate call.
+///
+///
+/// Type argument.
+///
+/// In Dart 2.0, the type argument additionally constrains the returned type.
+/// So, with type inference filling in the type argumemnt,
+///
+///     String s = JS('', 'JSON.stringify(#)', x);
+///
+/// will be the same as the current meaning of
+///
+///     var s = JS('String|Null', 'JSON.stringify(#)', x);
+///
+///
+/// Additional notes.
+///
+/// In the future we may extend [typeDescription] to include other aspects of
+/// the behavior, for example, separating the returned types from the
+/// instantiated types to allow the compiler to perform more optimizations
+/// around the code.
+///
+/// This might be an extension of [JS] or a new function similar to [JS] with
+/// additional arguments for the new information.
+// Add additional optional arguments if needed. The method is treated internally
+// as a variable argument method.
+external T JS<T>(String typeDescription, String codeTemplate,
+    [arg0,
+    arg1,
+    arg2,
+    arg3,
+    arg4,
+    arg5,
+    arg6,
+    arg7,
+    arg8,
+    arg9,
+    arg10,
+    arg11,
+    arg12,
+    arg13,
+    arg14,
+    arg51,
+    arg16,
+    arg17,
+    arg18,
+    arg19]);
+
+/// Converts the Dart closure [function] into a JavaScript closure.
+///
+/// Warning: This is no different from [RAW_DART_FUNCTION_REF] which means care
+/// must be taken to store the current isolate.
+external DART_CLOSURE_TO_JS(Function function);
+
+/// Returns a raw reference to the JavaScript function which implements
+/// [function].
+///
+/// Warning: this is dangerous, you should probably use
+/// [DART_CLOSURE_TO_JS] instead. The returned object is not a valid
+/// Dart closure, does not store the isolate context or arity.
+///
+/// A valid example of where this can be used is as the second argument
+/// to V8's Error.captureStackTrace. See
+/// https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi.
+external RAW_DART_FUNCTION_REF(Function function);
+
+/// Sets the current static state to [staticState].
+external void JS_SET_STATIC_STATE(staticState);
+
+/// Returns the interceptor for class [type].  The interceptor is the type's
+/// constructor's `prototype` property.  [type] will typically be the class, not
+/// an interface, e.g. `JS_INTERCEPTOR_CONSTANT(JSInt)`, not
+/// `JS_INTERCEPTOR_CONSTANT(int)`.
+external JS_INTERCEPTOR_CONSTANT(Type type);
+
+/// Returns the interceptor for [object].
+///
+/// Calls are replaced with the [HInterceptor] SSA instruction.
+external getInterceptor(object);
+
+/// Returns the Rti object for the type for JavaScript arrays via JS-interop.
+///
+/// Calls are replaced with a [HLoadType] SSA instruction.
+external Object getJSArrayInteropRti();
+
+/// Returns the object corresponding to Namer.staticStateHolder.
+external JS_GET_STATIC_STATE();
+
+/// Returns the JS name for [name] from the Namer.
+external String JS_GET_NAME(JsGetName name);
+
+/// Reads an embedded global.
+///
+/// The [name] should be a constant defined in the `_embedded_names` library.
+external JS_EMBEDDED_GLOBAL(String typeDescription, String name);
+
+/// Instructs the compiler to execute the [builtinName] action at the call-site.
+///
+/// The [builtin] should be a constant defined in the `_embedded_names`
+/// library.
+// Add additional optional arguments if needed. The method is treated internally
+// as a variable argument method.
+external JS_BUILTIN(String typeDescription, JsBuiltin builtin,
+    [arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11]);
+
+/// Returns the state of a flag that is determined by the state of the compiler
+/// when the program has been analyzed.
+external bool JS_GET_FLAG(String name);
+
+/// Pretend [code] is executed.  Generates no executable code.  This is used to
+/// model effects at some other point in external code.  For example, the
+/// following models an assignment to foo with an unknown value.
+///
+///     var foo;
+///
+///     main() {
+///       JS_EFFECT((_){ foo = _; })
+///     }
+///
+/// TODO(sra): Replace this hack with something to mark the volatile or
+/// externally initialized elements.
+void JS_EFFECT(Function code) {
+  code(null);
+}
+
+/// Use this class for creating constants that hold JavaScript code.
+/// For example:
+///
+/// const constant = JS_CONST('typeof window != "undefined");
+///
+/// This code will generate:
+/// $.JS_CONST_1 = typeof window != "undefined";
+class JS_CONST {
+  final String code;
+  const JS_CONST(this.code);
+}
+
+/// JavaScript string concatenation. Inputs must be Strings.  Corresponds to the
+/// HStringConcat SSA instruction and may be constant-folded.
+String JS_STRING_CONCAT(String a, String b) {
+  // This body is unused, only here for type analysis.
+  return JS('String', '# + #', a, b);
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/instantiation.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/instantiation.dart
new file mode 100644
index 0000000..bb003e6
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/instantiation.dart
@@ -0,0 +1,334 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 _js_helper;
+
+/// Support class for generic function type instantiation (binding of types).
+///
+abstract class Instantiation extends Closure {
+  final Closure _genericClosure;
+  Instantiation(this._genericClosure) {
+    // TODO(sra): Copy some metadata used by Function.apply.
+
+    // Mark support code as used.  The JS condition is inscrutable to dart2js,
+    // so the 'if (false)' is in the final program.
+    // TODO(sra): Find a better way to do this. Generating the signature methods
+    // earlier as SSA on the instantiation closures should achieve this.
+    if (JS('bool', 'false')) {
+      // [instantiatedGenericFunctionType] is called from injected $signature
+      // methods with runtime type representations.
+      if (JS_GET_FLAG('USE_NEW_RTI')) {
+        newRti.instantiatedGenericFunctionType(JS('', '0'), JS('', '0'));
+      } else {
+        instantiatedGenericFunctionType(JS('', '0'), JS('', '0'));
+      }
+    }
+  }
+
+  /// Returns a list of the bound types.
+  List get _types;
+
+  String toString() {
+    var types = "<${_types.join(', ')}>";
+    // TODO(sra): Refactor Closure formatting to place type arguments inside,
+    // e.g. "Closure 'map<String>' of Instance of 'JSArray<int>'".
+    return '$_genericClosure with $types';
+  }
+}
+
+/// Instantiation classes are subclasses of [Instantiation]. For now we have a
+/// fixed number of subclasses. Later we might generate the classes on demand.
+class Instantiation1<T1> extends Instantiation {
+  Instantiation1(Closure f) : super(f);
+  List get _types => [T1];
+}
+
+class Instantiation2<T1, T2> extends Instantiation {
+  Instantiation2(Closure f) : super(f);
+  List get _types => [T1, T2];
+}
+
+class Instantiation3<T1, T2, T3> extends Instantiation {
+  Instantiation3(Closure f) : super(f);
+  List get _types => [T1, T2, T3];
+}
+
+class Instantiation4<T1, T2, T3, T4> extends Instantiation {
+  Instantiation4(Closure f) : super(f);
+  List get _types => [T1, T2, T3, T4];
+}
+
+class Instantiation5<T1, T2, T3, T4, T5> extends Instantiation {
+  Instantiation5(Closure f) : super(f);
+  List get _types => [T1, T2, T3, T4, T5];
+}
+
+class Instantiation6<T1, T2, T3, T4, T5, T6> extends Instantiation {
+  Instantiation6(Closure f) : super(f);
+  List get _types => [T1, T2, T3, T4, T5, T6];
+}
+
+class Instantiation7<T1, T2, T3, T4, T5, T6, T7> extends Instantiation {
+  Instantiation7(Closure f) : super(f);
+  List get _types => [T1, T2, T3, T4, T5, T6, T7];
+}
+
+class Instantiation8<T1, T2, T3, T4, T5, T6, T7, T8> extends Instantiation {
+  Instantiation8(Closure f) : super(f);
+  List get _types => [T1, T2, T3, T4, T5, T6, T7, T8];
+}
+
+class Instantiation9<T1, T2, T3, T4, T5, T6, T7, T8, T9> extends Instantiation {
+  Instantiation9(Closure f) : super(f);
+  List get _types => [T1, T2, T3, T4, T5, T6, T7, T8, T9];
+}
+
+class Instantiation10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>
+    extends Instantiation {
+  Instantiation10(Closure f) : super(f);
+  List get _types => [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10];
+}
+
+class Instantiation11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>
+    extends Instantiation {
+  Instantiation11(Closure f) : super(f);
+  List get _types => [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11];
+}
+
+class Instantiation12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>
+    extends Instantiation {
+  Instantiation12(Closure f) : super(f);
+  List get _types => [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12];
+}
+
+class Instantiation13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>
+    extends Instantiation {
+  Instantiation13(Closure f) : super(f);
+  List get _types => [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13];
+}
+
+class Instantiation14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14> extends Instantiation {
+  Instantiation14(Closure f) : super(f);
+  List get _types =>
+      [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14];
+}
+
+class Instantiation15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15> extends Instantiation {
+  Instantiation15(Closure f) : super(f);
+  List get _types =>
+      [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15];
+}
+
+class Instantiation16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16> extends Instantiation {
+  Instantiation16(Closure f) : super(f);
+  List get _types =>
+      [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16];
+}
+
+class Instantiation17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17> extends Instantiation {
+  Instantiation17(Closure f) : super(f);
+  List get _types => [
+        T1,
+        T2,
+        T3,
+        T4,
+        T5,
+        T6,
+        T7,
+        T8,
+        T9,
+        T10,
+        T11,
+        T12,
+        T13,
+        T14,
+        T15,
+        T16,
+        T17
+      ];
+}
+
+class Instantiation18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18> extends Instantiation {
+  Instantiation18(Closure f) : super(f);
+  List get _types => [
+        T1,
+        T2,
+        T3,
+        T4,
+        T5,
+        T6,
+        T7,
+        T8,
+        T9,
+        T10,
+        T11,
+        T12,
+        T13,
+        T14,
+        T15,
+        T16,
+        T17,
+        T18
+      ];
+}
+
+class Instantiation19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19> extends Instantiation {
+  Instantiation19(Closure f) : super(f);
+  List get _types => [
+        T1,
+        T2,
+        T3,
+        T4,
+        T5,
+        T6,
+        T7,
+        T8,
+        T9,
+        T10,
+        T11,
+        T12,
+        T13,
+        T14,
+        T15,
+        T16,
+        T17,
+        T18,
+        T19
+      ];
+}
+
+class Instantiation20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20> extends Instantiation {
+  Instantiation20(Closure f) : super(f);
+  List get _types => [
+        T1,
+        T2,
+        T3,
+        T4,
+        T5,
+        T6,
+        T7,
+        T8,
+        T9,
+        T10,
+        T11,
+        T12,
+        T13,
+        T14,
+        T15,
+        T16,
+        T17,
+        T18,
+        T19,
+        T20
+      ];
+}
+
+Instantiation instantiate1<T1>(Closure f) {
+  return new Instantiation1<T1>(f);
+}
+
+Instantiation instantiate2<T1, T2>(Closure f) {
+  return new Instantiation2<T1, T2>(f);
+}
+
+Instantiation instantiate3<T1, T2, T3>(Closure f) {
+  return new Instantiation3<T1, T2, T3>(f);
+}
+
+Instantiation instantiate4<T1, T2, T3, T4>(Closure f) {
+  return new Instantiation4<T1, T2, T3, T4>(f);
+}
+
+Instantiation instantiate5<T1, T2, T3, T4, T5>(Closure f) {
+  return new Instantiation5<T1, T2, T3, T4, T5>(f);
+}
+
+Instantiation instantiate6<T1, T2, T3, T4, T5, T6>(Closure f) {
+  return new Instantiation6<T1, T2, T3, T4, T5, T6>(f);
+}
+
+Instantiation instantiate7<T1, T2, T3, T4, T5, T6, T7>(Closure f) {
+  return new Instantiation7<T1, T2, T3, T4, T5, T6, T7>(f);
+}
+
+Instantiation instantiate8<T1, T2, T3, T4, T5, T6, T7, T8>(Closure f) {
+  return new Instantiation8<T1, T2, T3, T4, T5, T6, T7, T8>(f);
+}
+
+Instantiation instantiate9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Closure f) {
+  return new Instantiation9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(f);
+}
+
+Instantiation instantiate10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
+    Closure f) {
+  return new Instantiation10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(f);
+}
+
+Instantiation instantiate11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(
+    Closure f) {
+  return new Instantiation11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(f);
+}
+
+Instantiation instantiate12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(
+    Closure f) {
+  return new Instantiation12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(
+      f);
+}
+
+Instantiation
+    instantiate13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(
+        Closure f) {
+  return new Instantiation13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13>(f);
+}
+
+Instantiation
+    instantiate14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(
+        Closure f) {
+  return new Instantiation14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14>(f);
+}
+
+Instantiation instantiate15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+    T13, T14, T15>(Closure f) {
+  return new Instantiation15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15>(f);
+}
+
+Instantiation instantiate16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+    T13, T14, T15, T16>(Closure f) {
+  return new Instantiation16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16>(f);
+}
+
+Instantiation instantiate17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+    T13, T14, T15, T16, T17>(Closure f) {
+  return new Instantiation17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17>(f);
+}
+
+Instantiation instantiate18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+    T13, T14, T15, T16, T17, T18>(Closure f) {
+  return new Instantiation18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18>(f);
+}
+
+Instantiation instantiate19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+    T13, T14, T15, T16, T17, T18, T19>(Closure f) {
+  return new Instantiation19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19>(f);
+}
+
+Instantiation instantiate20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+    T13, T14, T15, T16, T17, T18, T19, T20>(Closure f) {
+  return new Instantiation20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20>(f);
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart
new file mode 100644
index 0000000..b676c1b
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart
@@ -0,0 +1,455 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library _interceptors;
+
+import 'dart:_js_embedded_names'
+    show DISPATCH_PROPERTY_NAME, TYPE_TO_INTERCEPTOR_MAP;
+
+import 'dart:collection' hide LinkedList, LinkedListEntry;
+import 'dart:_internal' hide Symbol;
+import "dart:_internal" as _symbol_dev show Symbol;
+import 'dart:_js_helper'
+    show
+        allMatchesInStringUnchecked,
+        JSSyntaxRegExp,
+        Primitives,
+        argumentErrorValue,
+        checkBool,
+        checkInt,
+        checkNull,
+        checkNum,
+        checkString,
+        defineProperty,
+        diagnoseIndexError,
+        getIsolateAffinityTag,
+        getRuntimeType,
+        initNativeDispatch,
+        initNativeDispatchFlag,
+        regExpGetNative,
+        regExpCaptureCount,
+        stringContainsUnchecked,
+        stringIndexOfStringUnchecked,
+        stringLastIndexOfUnchecked,
+        stringReplaceAllFuncUnchecked,
+        stringReplaceAllUnchecked,
+        stringReplaceFirstUnchecked,
+        stringReplaceFirstMappedUnchecked,
+        stringReplaceRangeUnchecked,
+        stringSplitUnchecked,
+        throwConcurrentModificationError,
+        lookupAndCacheInterceptor,
+        StringMatch,
+        firstMatchAfter,
+        NoInline;
+
+import 'dart:_foreign_helper'
+    show
+        getInterceptor,
+        JS,
+        JS_EFFECT,
+        JS_EMBEDDED_GLOBAL,
+        JS_INTERCEPTOR_CONSTANT,
+        JS_STRING_CONCAT;
+import 'dart:math' show Random, ln2;
+
+part 'js_array.dart';
+part 'js_number.dart';
+part 'js_string.dart';
+
+final String DART_CLOSURE_PROPERTY_NAME =
+    getIsolateAffinityTag(r'_$dart_dartClosure');
+
+String _symbolToString(Symbol symbol) => _symbol_dev.Symbol.getName(symbol);
+
+_symbolMapToStringMap(Map<Symbol, dynamic> map) {
+  if (map == null) return null;
+  var result = new Map<String, dynamic>();
+  map.forEach((Symbol key, value) {
+    result[_symbolToString(key)] = value;
+  });
+  return result;
+}
+
+getDispatchProperty(object) {
+  return JS(
+      '', '#[#]', object, JS_EMBEDDED_GLOBAL('String', DISPATCH_PROPERTY_NAME));
+}
+
+setDispatchProperty(object, value) {
+  defineProperty(
+      object, JS_EMBEDDED_GLOBAL('String', DISPATCH_PROPERTY_NAME), value);
+}
+
+// Avoid inlining this method because inlining gives us multiple allocation
+// points for records which is bad because it leads to polymorphic access.
+@pragma('dart2js:noInline')
+makeDispatchRecord(interceptor, proto, extension, indexability) {
+  // Dispatch records are stored in the prototype chain, and in some cases, on
+  // instances.
+  //
+  // The record layout and field usage is designed to minimize the number of
+  // operations on the common paths.
+  //
+  // [interceptor] is the interceptor - a holder of methods for the object,
+  // i.e. the prototype of the interceptor class.
+  //
+  // [proto] is usually the prototype, used to check that the dispatch record
+  // matches the object and is not the dispatch record of a superclass.  Other
+  // values:
+  //  - `false` for leaf classes that need no check.
+  //  - `true` for Dart classes where the object is its own interceptor (unused)
+  //  - a function used to continue matching.
+  //
+  // [extension] is used for irregular cases.
+  //
+  // [indexability] is used to cache whether or not the object
+  // implements JavaScriptIndexingBehavior.
+  //
+  //     proto  interceptor extension action
+  //     -----  ----------- --------- ------
+  //     false  I                     use interceptor I
+  //     true   -                     use object
+  //     P      I                     if object's prototype is P, use I
+  //     F      -           P         if object's prototype is P, call F
+
+  return JS('', '{i: #, p: #, e: #, x: #}', interceptor, proto, extension,
+      indexability);
+}
+
+dispatchRecordInterceptor(record) => JS('', '#.i', record);
+dispatchRecordProto(record) => JS('', '#.p', record);
+dispatchRecordExtension(record) => JS('', '#.e', record);
+dispatchRecordIndexability(record) => JS('bool|Null', '#.x', record);
+
+/// Returns the interceptor for a native class instance. Used by
+/// [getInterceptor].
+getNativeInterceptor(object) {
+  var record = getDispatchProperty(object);
+
+  if (record == null) {
+    if (initNativeDispatchFlag == null) {
+      initNativeDispatch();
+      record = getDispatchProperty(object);
+    }
+  }
+
+  if (record != null) {
+    var proto = dispatchRecordProto(record);
+    if (false == proto) return dispatchRecordInterceptor(record);
+    if (true == proto) return object;
+    var objectProto = JS('', 'Object.getPrototypeOf(#)', object);
+    if (JS('bool', '# === #', proto, objectProto)) {
+      return dispatchRecordInterceptor(record);
+    }
+
+    var extension = dispatchRecordExtension(record);
+    if (JS('bool', '# === #', extension, objectProto)) {
+      // TODO(sra): The discriminator returns a tag.  The tag is an uncached or
+      // instance-cached tag, defaulting to instance-cached if caching
+      // unspecified.
+      var discriminatedTag = JS('', '(#)(#, #)', proto, object, record);
+      throw new UnimplementedError('Return interceptor for $discriminatedTag');
+    }
+  }
+
+  // Check for cached UnknownJavaScriptObject. This avoids doing the slow
+  // dispatch-record based lookup for repeated js-interop classes.
+  var constructor = JS('', '#.constructor', object);
+  var interceptor = lookupInterceptorByConstructor(constructor);
+  if (interceptor != null) return interceptor;
+
+  // This takes care of dispatch-record based caching, but not constructor based
+  // caching of [UnknownJavaScriptObject]s.
+  interceptor = lookupAndCacheInterceptor(object);
+  if (interceptor != null) return interceptor;
+
+  // JavaScript Objects created via object literals and `Object.create(null)`
+  // are 'plain' Objects.  This test could be simplified and the dispatch path
+  // be faster if Object.prototype was pre-patched with a non-leaf dispatch
+  // record.
+  if (JS('bool', 'typeof # == "function"', object)) {
+    interceptor = JS_INTERCEPTOR_CONSTANT(JavaScriptFunction);
+    // TODO(sra): Investigate caching on `Function`. It might be impossible if
+    // some HTML embedded objects on some browsers are (still) JS functions.
+    return interceptor;
+  }
+  var proto = JS('', 'Object.getPrototypeOf(#)', object);
+  if (JS('bool', '# == null', proto)) {
+    // Nowhere to cache output.
+    return JS_INTERCEPTOR_CONSTANT(PlainJavaScriptObject);
+  }
+  interceptor = JS_INTERCEPTOR_CONSTANT(UnknownJavaScriptObject);
+  if (JS('bool', '# === Object.prototype', proto)) {
+    interceptor = JS_INTERCEPTOR_CONSTANT(PlainJavaScriptObject);
+    // TODO(sra): Investigate caching on 'Object'. It might be impossible if
+    // some native class is plain Object (e.g. like Firefox's ImageData).
+    return interceptor;
+  }
+  if (JS('bool', 'typeof # == "function"', constructor)) {
+    cacheInterceptorOnConstructor(constructor, interceptor);
+    return interceptor;
+  }
+  return JS_INTERCEPTOR_CONSTANT(UnknownJavaScriptObject);
+}
+
+// A JS String or Symbol.
+final JS_INTEROP_INTERCEPTOR_TAG = getIsolateAffinityTag(r'_$dart_js');
+
+lookupInterceptorByConstructor(constructor) {
+  return constructor == null
+      ? null
+      : JS('', '#[#]', constructor, JS_INTEROP_INTERCEPTOR_TAG);
+}
+
+void cacheInterceptorOnConstructor(constructor, interceptor) {
+  defineProperty(constructor, JS_INTEROP_INTERCEPTOR_TAG, interceptor);
+}
+
+var constructorToInterceptor =
+    JS('', 'typeof(self.WeakMap) == "undefined" ? new Map() : new WeakMap()');
+
+XlookupInterceptorByConstructor(constructor) {
+  return JS('', '#.get(#)', constructorToInterceptor, constructor);
+}
+
+void XcacheInterceptorOnConstructor(constructor, interceptor) {
+  JS('', '#.set(#, #)', constructorToInterceptor, constructor, interceptor);
+}
+
+/// Data structure used to map a [Type] to the [Interceptor] and constructors
+/// for that type.  It is JavaScript array of 3N entries of adjacent slots
+/// containing a [Type], followed by an [Interceptor] class for the type,
+/// followed by a JavaScript object map for the constructors.
+///
+/// The value of this variable is set by the compiler and contains only types
+/// that are user extensions of native classes where the type occurs as a
+/// constant in the program.
+///
+/// The compiler, in CustomElementsAnalysis, assumes that [typeToInterceptorMap]
+/// is accessed only by code that also calls [findIndexForWebComponentType].  If
+/// this assumption is invalidated, the compiler will have to be updated.
+get typeToInterceptorMap {
+  return JS_EMBEDDED_GLOBAL('', TYPE_TO_INTERCEPTOR_MAP);
+}
+
+int findIndexForNativeSubclassType(Type type) {
+  if (JS('bool', '# == null', typeToInterceptorMap)) return null;
+  List map = JS('JSFixedArray', '#', typeToInterceptorMap);
+  for (int i = 0; i + 1 < map.length; i += 3) {
+    if (type == map[i]) {
+      return i;
+    }
+  }
+  return null;
+}
+
+findInterceptorConstructorForType(Type type) {
+  var index = findIndexForNativeSubclassType(type);
+  if (index == null) return null;
+  List map = JS('JSFixedArray', '#', typeToInterceptorMap);
+  return map[index + 1];
+}
+
+/// Returns a JavaScript function that runs the constructor on its argument, or
+/// `null` if there is no such constructor.
+///
+/// The returned function takes one argument, the web component object.
+findConstructorForNativeSubclassType(Type type, String name) {
+  var index = findIndexForNativeSubclassType(type);
+  if (index == null) return null;
+  List map = JS('JSFixedArray', '#', typeToInterceptorMap);
+  var constructorMap = map[index + 2];
+  var constructorFn = JS('', '#[#]', constructorMap, name);
+  return constructorFn;
+}
+
+findInterceptorForType(Type type) {
+  var constructor = findInterceptorConstructorForType(type);
+  if (constructor == null) return null;
+  return JS('', '#.prototype', constructor);
+}
+
+/// The base interceptor class.
+///
+/// The code `r.foo(a)` is compiled to `getInterceptor(r).foo$1(r, a)`.  The
+/// value returned by [getInterceptor] holds the methods separately from the
+/// state of the instance.  The compiler converts the methods on an interceptor
+/// to take the Dart `this` argument as an explicit `receiver` argument.  The
+/// JavaScript `this` parameter is bound to the interceptor.
+///
+/// In order to have uniform call sites, if a method is defined on an
+/// interceptor, methods of that name on plain unintercepted classes also use
+/// the interceptor calling convention.  The plain classes are
+/// _self-interceptors_, and for them, `getInterceptor(r)` returns `r`.  Methods
+/// on plain unintercepted classes have a redundant `receiver` argument and, to
+/// enable some optimizations, must ignore `receiver` in favour of `this`.
+///
+/// In the case of mixins, a method may be placed on both an intercepted class
+/// and an unintercepted class.  In this case, the method must use the
+/// `receiver` parameter.
+///
+///
+/// There are various optimizations of the general call pattern.
+///
+/// When the interceptor can be statically determined, it can be used directly:
+///
+///     CONSTANT_INTERCEPTOR.foo$1(r, a)
+///
+/// If there are only a few classes, [getInterceptor] can be specialized with a
+/// more efficient dispatch:
+///
+///     getInterceptor$specialized(r).foo$1(r, a)
+///
+/// If it can be determined that the receiver is an unintercepted class, it can
+/// be called directly:
+///
+///     r.foo$1(r, a)
+///
+/// If, further, it is known that the call site cannot call a foo that is
+/// mixed-in to a native class, then it is known that the explicit receiver is
+/// ignored, and space-saving dummy value can be passed instead:
+///
+///     r.foo$1(0, a)
+///
+/// This class defines implementations of *all* methods on [Object] so no
+/// interceptor inherits an implementation from [Object].  This enables the
+/// implementations on Object to ignore the explicit receiver argument, which
+/// allows dummy receiver optimization.
+abstract class Interceptor {
+  const Interceptor();
+
+  bool operator ==(other) => identical(this, other);
+
+  int get hashCode => Primitives.objectHashCode(this);
+
+  String toString() => Primitives.objectToHumanReadableString(this);
+
+  // [Interceptor.noSuchMethod] is identical to [Object.noSuchMethod].  However,
+  // each copy is compiled differently.  The presence of the method on an
+  // Interceptor class forces [noSuchMethod] to use interceptor calling
+  // convention.  In the [Interceptor] version, `this` is the explicit receiver
+  // argument. In the [Object] version, as Object is not an intercepted class,
+  // `this` is the JavaScript receiver, and the explicit receiver is ignored.
+  // The noSuchMethod stubs for selectors that use the interceptor calling
+  // convention do not know the calling convention and forward `this` and
+  // `receiver` to one of these noSuchMethod implementations which selects the
+  // correct Dart receiver.
+  //
+  // We don't allow [noSuchMethod] on intercepted classes (that would force all
+  // calls to use interceptor calling convention).  If we did allow it, the
+  // interceptor context would select the correct `this`.
+  dynamic noSuchMethod(Invocation invocation) {
+    throw new NoSuchMethodError(this, invocation.memberName,
+        invocation.positionalArguments, invocation.namedArguments);
+  }
+
+  Type get runtimeType => getRuntimeType(this);
+}
+
+/// The interceptor class for [bool].
+class JSBool extends Interceptor implements bool {
+  const JSBool();
+
+  // Note: if you change this, also change the function [S].
+  String toString() => JS('String', r'String(#)', this);
+
+  bool operator &(bool other) => JS('bool', "# && #", checkBool(other), this);
+
+  bool operator |(bool other) => JS('bool', "# || #", checkBool(other), this);
+
+  bool operator ^(bool other) => !identical(this, checkBool(other));
+
+  // The values here are SMIs, co-prime and differ about half of the bit
+  // positions, including the low bit, so they are different mod 2^k.
+  int get hashCode => this ? (2 * 3 * 23 * 3761) : (269 * 811);
+
+  Type get runtimeType => bool;
+}
+
+/// The interceptor class for [Null].
+///
+/// This class defines implementations for *all* methods on [Object] since
+/// the methods on Object assume the receiver is non-null.  This means that
+/// JSNull will always be in the interceptor set for methods defined on Object.
+class JSNull extends Interceptor implements Null {
+  const JSNull();
+
+  bool operator ==(other) => identical(null, other);
+
+  // Note: if you change this, also change the function [S].
+  String toString() => 'null';
+
+  int get hashCode => 0;
+
+  // The spec guarantees that `null` is the singleton instance of the `Null`
+  // class. In the mirrors library we also have to patch the `type` getter to
+  // special case `null`.
+  Type get runtimeType => Null;
+
+  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+/// The supertype for JSString and JSArray. Used by the backend as to
+/// have a type mask that contains the objects that we can use the
+/// native JS [] operator and length on.
+abstract class JSIndexable<E> {
+  int get length;
+  E operator [](int index);
+}
+
+/// The supertype for JSMutableArray and
+/// JavaScriptIndexingBehavior. Used by the backend to have a type mask
+/// that contains the objects we can use the JS []= operator on.
+abstract class JSMutableIndexable<E> extends JSIndexable<E> {
+  operator []=(int index, E value);
+}
+
+/// The interface implemented by JavaScript objects.  These are methods in
+/// addition to the regular Dart Object methods like [Object.hashCode].
+///
+/// This is the type that should be exported by a JavaScript interop library.
+abstract class JSObject {}
+
+/// Interceptor base class for JavaScript objects not recognized as some more
+/// specific native type.
+class JavaScriptObject extends Interceptor implements JSObject {
+  const JavaScriptObject();
+
+  // It would be impolite to stash a property on the object.
+  int get hashCode => 0;
+
+  Type get runtimeType => JSObject;
+
+  /// Returns the result of the JavaScript objects `toString` method.
+  String toString() => JS('String', 'String(#)', this);
+}
+
+/// Interceptor for plain JavaScript objects created as JavaScript object
+/// literals or `new Object()`.
+class PlainJavaScriptObject extends JavaScriptObject {
+  const PlainJavaScriptObject();
+}
+
+/// Interceptor for unclassified JavaScript objects, typically objects with a
+/// non-trivial prototype chain.
+///
+/// This class also serves as a fallback for unknown JavaScript exceptions.
+class UnknownJavaScriptObject extends JavaScriptObject {
+  const UnknownJavaScriptObject();
+}
+
+/// Interceptor for JavaScript function objects and Dart functions that have
+/// been converted to JavaScript functions.
+/// These interceptor methods are not always used as the JavaScript function
+/// object has also been mangled to support Dart function calling conventions.
+class JavaScriptFunction extends JavaScriptObject implements Function {
+  const JavaScriptFunction();
+
+  String toString() {
+    var dartClosure = JS('', '#.#', this, DART_CLOSURE_PROPERTY_NAME);
+    if (dartClosure == null) return super.toString();
+    return 'JavaScript function for ${dartClosure.toString()}';
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart
new file mode 100644
index 0000000..77884e2
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart
@@ -0,0 +1,59 @@
+// 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:core' hide Symbol;
+import 'dart:core' as core;
+import 'dart:_js_primitives' show printString;
+import 'dart:_js_helper' show patch, NoInline;
+import 'dart:_interceptors' show JSArray;
+import 'dart:_foreign_helper' show JS, JS_GET_FLAG;
+
+@patch
+class Symbol implements core.Symbol {
+  @patch
+  const Symbol(String name) : this._name = name;
+
+  @patch
+  int get hashCode {
+    int hash = JS('int|Null', '#._hashCode', this);
+    if (hash != null) return hash;
+    const arbitraryPrime = 664597;
+    hash = 0x1fffffff & (arbitraryPrime * _name.hashCode);
+    JS('', '#._hashCode = #', this, hash);
+    return hash;
+  }
+
+  @patch
+  toString() => 'Symbol("$_name")';
+
+  @patch
+  static String computeUnmangledName(Symbol symbol) {
+    throw "unsupported operation";
+  }
+}
+
+@patch
+void printToConsole(String line) {
+  printString('$line');
+}
+
+@patch
+List<T> makeListFixedLength<T>(List<T> growableList) {
+  return JSArray.markFixedList(growableList);
+}
+
+@patch
+List<T> makeFixedListUnmodifiable<T>(List<T> fixedLengthList) {
+  return JSArray.markUnmodifiableList(fixedLengthList);
+}
+
+@patch
+@pragma('dart2js:noInline')
+Object extractTypeArguments<T>(T instance, Function extract) {
+  // This function is recognized and replaced with calls to js_runtime.
+
+  // This call to [extract] is required to model that the function is called and
+  // the returned value flows to the result of extractTypeArguments.
+  return extract();
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart
new file mode 100644
index 0000000..4f3894d
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart
@@ -0,0 +1,690 @@
+// 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:_js_helper' show patch;
+import 'dart:_internal' hide Symbol;
+import 'dart:async';
+import 'dart:convert';
+import 'dart:isolate';
+import 'dart:typed_data';
+
+@patch
+class _Directory {
+  @patch
+  static _current(_Namespace namespace) {
+    throw new UnsupportedError("Directory._current");
+  }
+
+  @patch
+  static _setCurrent(_Namespace namespace, Uint8List path) {
+    throw new UnsupportedError("Directory_SetCurrent");
+  }
+
+  @patch
+  static _createTemp(_Namespace namespace, Uint8List path) {
+    throw new UnsupportedError("Directory._createTemp");
+  }
+
+  @patch
+  static String _systemTemp(_Namespace namespace) {
+    throw new UnsupportedError("Directory._systemTemp");
+  }
+
+  @patch
+  static _exists(_Namespace namespace, Uint8List path) {
+    throw new UnsupportedError("Directory._exists");
+  }
+
+  @patch
+  static _create(_Namespace namespace, Uint8List path) {
+    throw new UnsupportedError("Directory._create");
+  }
+
+  @patch
+  static _deleteNative(_Namespace namespace, Uint8List path, bool recursive) {
+    throw new UnsupportedError("Directory._deleteNative");
+  }
+
+  @patch
+  static _rename(_Namespace namespace, Uint8List path, String newPath) {
+    throw new UnsupportedError("Directory._rename");
+  }
+
+  @patch
+  static void _fillWithDirectoryListing(
+      _Namespace namespace,
+      List<FileSystemEntity> list,
+      Uint8List path,
+      bool recursive,
+      bool followLinks) {
+    throw new UnsupportedError("Directory._fillWithDirectoryListing");
+  }
+}
+
+@patch
+class _AsyncDirectoryListerOps {
+  @patch
+  factory _AsyncDirectoryListerOps(int pointer) {
+    throw new UnsupportedError("Directory._list");
+  }
+}
+
+@patch
+class _EventHandler {
+  @patch
+  static void _sendData(Object sender, SendPort sendPort, int data) {
+    throw new UnsupportedError("EventHandler._sendData");
+  }
+}
+
+@patch
+class FileStat {
+  @patch
+  static _statSync(_Namespace namespace, String path) {
+    throw new UnsupportedError("FileStat.stat");
+  }
+}
+
+@patch
+class FileSystemEntity {
+  @patch
+  static _getTypeNative(
+      _Namespace namespace, Uint8List path, bool followLinks) {
+    throw new UnsupportedError("FileSystemEntity._getType");
+  }
+
+  @patch
+  static _identicalNative(_Namespace namespace, String path1, String path2) {
+    throw new UnsupportedError("FileSystemEntity._identical");
+  }
+
+  @patch
+  static _resolveSymbolicLinks(_Namespace namespace, Uint8List path) {
+    throw new UnsupportedError("FileSystemEntity._resolveSymbolicLinks");
+  }
+}
+
+@patch
+class _File {
+  @patch
+  static _exists(_Namespace namespace, Uint8List path) {
+    throw new UnsupportedError("File._exists");
+  }
+
+  @patch
+  static _create(_Namespace namespace, Uint8List path) {
+    throw new UnsupportedError("File._create");
+  }
+
+  @patch
+  static _createLink(_Namespace namespace, Uint8List path, String target) {
+    throw new UnsupportedError("File._createLink");
+  }
+
+  @patch
+  static _linkTarget(_Namespace namespace, Uint8List path) {
+    throw new UnsupportedError("File._linkTarget");
+  }
+
+  @patch
+  static _deleteNative(_Namespace namespace, Uint8List path) {
+    throw new UnsupportedError("File._deleteNative");
+  }
+
+  @patch
+  static _deleteLinkNative(_Namespace namespace, Uint8List path) {
+    throw new UnsupportedError("File._deleteLinkNative");
+  }
+
+  @patch
+  static _rename(_Namespace namespace, Uint8List oldPath, String newPath) {
+    throw new UnsupportedError("File._rename");
+  }
+
+  @patch
+  static _renameLink(_Namespace namespace, Uint8List oldPath, String newPath) {
+    throw new UnsupportedError("File._renameLink");
+  }
+
+  @patch
+  static _copy(_Namespace namespace, Uint8List oldPath, String newPath) {
+    throw new UnsupportedError("File._copy");
+  }
+
+  @patch
+  static _lengthFromPath(_Namespace namespace, Uint8List path) {
+    throw new UnsupportedError("File._lengthFromPath");
+  }
+
+  @patch
+  static _lastModified(_Namespace namespace, Uint8List path) {
+    throw new UnsupportedError("File._lastModified");
+  }
+
+  @patch
+  static _lastAccessed(_Namespace namespace, Uint8List path) {
+    throw new UnsupportedError("File._lastAccessed");
+  }
+
+  @patch
+  static _setLastModified(_Namespace namespace, Uint8List path, int millis) {
+    throw new UnsupportedError("File._setLastModified");
+  }
+
+  @patch
+  static _setLastAccessed(_Namespace namespace, Uint8List path, int millis) {
+    throw new UnsupportedError("File._setLastAccessed");
+  }
+
+  @patch
+  static _open(_Namespace namespace, Uint8List path, int mode) {
+    throw new UnsupportedError("File._open");
+  }
+
+  @patch
+  static int _openStdio(int fd) {
+    throw new UnsupportedError("File._openStdio");
+  }
+}
+
+@patch
+class _Namespace {
+  @patch
+  static void _setupNamespace(var namespace) {
+    throw new UnsupportedError("_Namespace");
+  }
+
+  @patch
+  static _Namespace get _namespace {
+    throw new UnsupportedError("_Namespace");
+  }
+
+  @patch
+  static int get _namespacePointer {
+    throw new UnsupportedError("_Namespace");
+  }
+}
+
+@patch
+class _RandomAccessFileOps {
+  @patch
+  factory _RandomAccessFileOps(int pointer) {
+    throw new UnsupportedError("RandomAccessFile");
+  }
+}
+
+@patch
+class _IOCrypto {
+  @patch
+  static Uint8List getRandomBytes(int count) {
+    throw new UnsupportedError("_IOCrypto.getRandomBytes");
+  }
+}
+
+@patch
+class _Platform {
+  @patch
+  static int _numberOfProcessors() {
+    throw new UnsupportedError("Platform._numberOfProcessors");
+  }
+
+  @patch
+  static String _pathSeparator() {
+    throw new UnsupportedError("Platform._pathSeparator");
+  }
+
+  @patch
+  static String _operatingSystem() {
+    throw new UnsupportedError("Platform._operatingSystem");
+  }
+
+  @patch
+  static _operatingSystemVersion() {
+    throw new UnsupportedError("Platform._operatingSystemVersion");
+  }
+
+  @patch
+  static _localHostname() {
+    throw new UnsupportedError("Platform._localHostname");
+  }
+
+  @patch
+  static _executable() {
+    throw new UnsupportedError("Platform._executable");
+  }
+
+  @patch
+  static _resolvedExecutable() {
+    throw new UnsupportedError("Platform._resolvedExecutable");
+  }
+
+  @patch
+  static List<String> _executableArguments() {
+    throw new UnsupportedError("Platform._executableArguments");
+  }
+
+  @patch
+  static String _packageRoot() {
+    throw new UnsupportedError("Platform._packageRoot");
+  }
+
+  @patch
+  static String _packageConfig() {
+    throw new UnsupportedError("Platform._packageConfig");
+  }
+
+  @patch
+  static _environment() {
+    throw new UnsupportedError("Platform._environment");
+  }
+
+  @patch
+  static String _version() {
+    throw new UnsupportedError("Platform._version");
+  }
+
+  @patch
+  static String _localeName() {
+    throw new UnsupportedError("Platform._localeName");
+  }
+
+  @patch
+  static Uri _script() {
+    throw new UnsupportedError("Platform._script");
+  }
+}
+
+@patch
+class _ProcessUtils {
+  @patch
+  static void _exit(int status) {
+    throw new UnsupportedError("ProcessUtils._exit");
+  }
+
+  @patch
+  static void _setExitCode(int status) {
+    throw new UnsupportedError("ProcessUtils._setExitCode");
+  }
+
+  @patch
+  static int _getExitCode() {
+    throw new UnsupportedError("ProcessUtils._getExitCode");
+  }
+
+  @patch
+  static void _sleep(int millis) {
+    throw new UnsupportedError("ProcessUtils._sleep");
+  }
+
+  @patch
+  static int _pid(Process process) {
+    throw new UnsupportedError("ProcessUtils._pid");
+  }
+
+  @patch
+  static Stream<ProcessSignal> _watchSignal(ProcessSignal signal) {
+    throw new UnsupportedError("ProcessUtils._watchSignal");
+  }
+}
+
+@patch
+class ProcessInfo {
+  @patch
+  static int get currentRss {
+    throw new UnsupportedError("ProcessInfo.currentRss");
+  }
+
+  @patch
+  static int get maxRss {
+    throw new UnsupportedError("ProcessInfo.maxRss");
+  }
+}
+
+@patch
+class Process {
+  @patch
+  static Future<Process> start(String executable, List<String> arguments,
+      {String workingDirectory,
+      Map<String, String> environment,
+      bool includeParentEnvironment: true,
+      bool runInShell: false,
+      ProcessStartMode mode: ProcessStartMode.normal}) {
+    throw new UnsupportedError("Process.start");
+  }
+
+  @patch
+  static Future<ProcessResult> run(String executable, List<String> arguments,
+      {String workingDirectory,
+      Map<String, String> environment,
+      bool includeParentEnvironment: true,
+      bool runInShell: false,
+      Encoding stdoutEncoding: systemEncoding,
+      Encoding stderrEncoding: systemEncoding}) {
+    throw new UnsupportedError("Process.run");
+  }
+
+  @patch
+  static ProcessResult runSync(String executable, List<String> arguments,
+      {String workingDirectory,
+      Map<String, String> environment,
+      bool includeParentEnvironment: true,
+      bool runInShell: false,
+      Encoding stdoutEncoding: systemEncoding,
+      Encoding stderrEncoding: systemEncoding}) {
+    throw new UnsupportedError("Process.runSync");
+  }
+
+  @patch
+  static bool killPid(int pid, [ProcessSignal signal = ProcessSignal.sigterm]) {
+    throw new UnsupportedError("Process.killPid");
+  }
+}
+
+@patch
+class InternetAddress {
+  @patch
+  static InternetAddress get LOOPBACK_IP_V4 {
+    throw new UnsupportedError("InternetAddress.LOOPBACK_IP_V4");
+  }
+
+  @patch
+  static InternetAddress get LOOPBACK_IP_V6 {
+    throw new UnsupportedError("InternetAddress.LOOPBACK_IP_V6");
+  }
+
+  @patch
+  static InternetAddress get ANY_IP_V4 {
+    throw new UnsupportedError("InternetAddress.ANY_IP_V4");
+  }
+
+  @patch
+  static InternetAddress get ANY_IP_V6 {
+    throw new UnsupportedError("InternetAddress.ANY_IP_V6");
+  }
+
+  @patch
+  factory InternetAddress(String address) {
+    throw new UnsupportedError("InternetAddress");
+  }
+  @patch
+  static Future<List<InternetAddress>> lookup(String host,
+      {InternetAddressType type: InternetAddressType.any}) {
+    throw new UnsupportedError("InternetAddress.lookup");
+  }
+
+  @patch
+  static InternetAddress _cloneWithNewHost(
+      InternetAddress address, String host) {
+    throw new UnsupportedError("InternetAddress._cloneWithNewHost");
+  }
+}
+
+@patch
+class NetworkInterface {
+  @patch
+  static bool get listSupported {
+    throw new UnsupportedError("NetworkInterface.listSupported");
+  }
+
+  @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,
+      {int backlog: 0, bool v6Only: false, bool shared: false}) {
+    throw new UnsupportedError("RawServerSocket.bind");
+  }
+}
+
+@patch
+class ServerSocket {
+  @patch
+  static Future<ServerSocket> bind(address, int port,
+      {int backlog: 0, bool v6Only: false, bool shared: false}) {
+    throw new UnsupportedError("ServerSocket.bind");
+  }
+}
+
+@patch
+class RawSocket {
+  @patch
+  static Future<RawSocket> connect(host, int port,
+      {sourceAddress, Duration timeout}) {
+    throw new UnsupportedError("RawSocket constructor");
+  }
+
+  @patch
+  static Future<ConnectionTask<RawSocket>> startConnect(host, int port,
+      {sourceAddress}) {
+    throw new UnsupportedError("RawSocket constructor");
+  }
+}
+
+@patch
+class Socket {
+  @patch
+  static Future<Socket> _connect(host, int port,
+      {sourceAddress, Duration timeout}) {
+    throw new UnsupportedError("Socket constructor");
+  }
+
+  @patch
+  static Future<ConnectionTask<Socket>> _startConnect(host, int port,
+      {sourceAddress}) {
+    throw new UnsupportedError("Socket constructor");
+  }
+}
+
+@patch
+class SecureSocket {
+  @patch
+  factory SecureSocket._(RawSecureSocket rawSocket) {
+    throw new UnsupportedError("SecureSocket constructor");
+  }
+}
+
+@patch
+class RawSynchronousSocket {
+  @patch
+  static RawSynchronousSocket connectSync(host, int port) {
+    throw new UnsupportedError("RawSynchronousSocket.connectSync");
+  }
+}
+
+@patch
+class RawSocketOption {
+  @patch
+  static int _getOptionValue(int key) {
+    throw UnsupportedError("RawSocketOption._getOptionValue");
+  }
+}
+
+@patch
+class SecurityContext {
+  @patch
+  factory SecurityContext({bool withTrustedRoots: false}) {
+    throw new UnsupportedError("SecurityContext constructor");
+  }
+
+  @patch
+  static SecurityContext get defaultContext {
+    throw new UnsupportedError("default SecurityContext getter");
+  }
+
+  @patch
+  static bool get alpnSupported {
+    throw new UnsupportedError("SecurityContext alpnSupported getter");
+  }
+}
+
+@patch
+class X509Certificate {
+  @patch
+  factory X509Certificate._() {
+    throw new UnsupportedError("X509Certificate constructor");
+  }
+}
+
+@patch
+class RawDatagramSocket {
+  @patch
+  static Future<RawDatagramSocket> bind(host, int port,
+      {bool reuseAddress: true, bool reusePort: false, int ttl: 1}) {
+    throw new UnsupportedError("RawDatagramSocket.bind");
+  }
+}
+
+@patch
+class _SecureFilter {
+  @patch
+  factory _SecureFilter._() {
+    throw new UnsupportedError("_SecureFilter._SecureFilter");
+  }
+}
+
+@patch
+class _StdIOUtils {
+  @patch
+  static Stdin _getStdioInputStream(int fd) {
+    throw new UnsupportedError("StdIOUtils._getStdioInputStream");
+  }
+
+  @patch
+  static _getStdioOutputStream(int fd) {
+    throw new UnsupportedError("StdIOUtils._getStdioOutputStream");
+  }
+
+  @patch
+  static int _socketType(Socket socket) {
+    throw new UnsupportedError("StdIOUtils._socketType");
+  }
+
+  @patch
+  static _getStdioHandleType(int fd) {
+    throw new UnsupportedError("StdIOUtils._getStdioHandleType");
+  }
+}
+
+@patch
+class _WindowsCodePageDecoder {
+  @patch
+  static String _decodeBytes(List<int> bytes) {
+    throw new UnsupportedError("_WindowsCodePageDecoder._decodeBytes");
+  }
+}
+
+@patch
+class _WindowsCodePageEncoder {
+  @patch
+  static List<int> _encodeString(String string) {
+    throw new UnsupportedError("_WindowsCodePageEncoder._encodeString");
+  }
+}
+
+@patch
+class RawZLibFilter {
+  @patch
+  static RawZLibFilter _makeZLibDeflateFilter(
+      bool gzip,
+      int level,
+      int windowBits,
+      int memLevel,
+      int strategy,
+      List<int> dictionary,
+      bool raw) {
+    throw new UnsupportedError("_newZLibDeflateFilter");
+  }
+
+  @patch
+  static RawZLibFilter _makeZLibInflateFilter(
+      int windowBits, List<int> dictionary, bool raw) {
+    throw new UnsupportedError("_newZLibInflateFilter");
+  }
+}
+
+@patch
+class Stdin {
+  @patch
+  int readByteSync() {
+    throw new UnsupportedError("Stdin.readByteSync");
+  }
+
+  @patch
+  bool get echoMode {
+    throw new UnsupportedError("Stdin.echoMode");
+  }
+
+  @patch
+  void set echoMode(bool enabled) {
+    throw new UnsupportedError("Stdin.echoMode");
+  }
+
+  @patch
+  bool get lineMode {
+    throw new UnsupportedError("Stdin.lineMode");
+  }
+
+  @patch
+  void set lineMode(bool enabled) {
+    throw new UnsupportedError("Stdin.lineMode");
+  }
+
+  @patch
+  bool get supportsAnsiEscapes {
+    throw new UnsupportedError("Stdin.supportsAnsiEscapes");
+  }
+}
+
+@patch
+class Stdout {
+  @patch
+  bool _hasTerminal(int fd) {
+    throw new UnsupportedError("Stdout.hasTerminal");
+  }
+
+  @patch
+  int _terminalColumns(int fd) {
+    throw new UnsupportedError("Stdout.terminalColumns");
+  }
+
+  @patch
+  int _terminalLines(int fd) {
+    throw new UnsupportedError("Stdout.terminalLines");
+  }
+
+  @patch
+  static bool _supportsAnsiEscapes(int fd) {
+    throw new UnsupportedError("Stdout.supportsAnsiEscapes");
+  }
+}
+
+@patch
+class _FileSystemWatcher {
+  @patch
+  static Stream<FileSystemEvent> _watch(
+      String path, int events, bool recursive) {
+    throw new UnsupportedError("_FileSystemWatcher.watch");
+  }
+
+  @patch
+  static bool get isSupported {
+    throw new UnsupportedError("_FileSystemWatcher.isSupported");
+  }
+}
+
+@patch
+class _IOService {
+  @patch
+  static Future _dispatch(int request, List data) {
+    throw new UnsupportedError("_IOService._dispatch");
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/isolate_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/isolate_patch.dart
new file mode 100644
index 0000000..d781e7a
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/isolate_patch.dart
@@ -0,0 +1,152 @@
+// Copyright (c) 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.
+
+// Patch file for the dart:isolate library.
+
+import "dart:async";
+import 'dart:_foreign_helper' show JS;
+import 'dart:_js_helper' show patch;
+import "dart:typed_data" show ByteData, TypedData, Uint8List;
+
+@patch
+class Isolate {
+  @patch
+  static Isolate get current {
+    throw new UnsupportedError("Isolate.current");
+  }
+
+  @patch
+  String get debugName {
+    throw new UnsupportedError("Isolate.debugName");
+  }
+
+  @patch
+  static Future<Uri> get packageRoot {
+    throw new UnsupportedError("Isolate.packageRoot");
+  }
+
+  @patch
+  static Future<Uri> get packageConfig {
+    throw new UnsupportedError("Isolate.packageConfig");
+  }
+
+  @patch
+  static Future<Uri> resolvePackageUri(Uri packageUri) {
+    throw new UnsupportedError("Isolate.resolvePackageUri");
+  }
+
+  @patch
+  static Future<Isolate> spawn<T>(void entryPoint(T message), T message,
+      {bool paused: false,
+      bool errorsAreFatal,
+      SendPort onExit,
+      SendPort onError}) {
+    throw new UnsupportedError("Isolate.spawn");
+  }
+
+  @patch
+  static Future<Isolate> spawnUri(Uri uri, List<String> args, var message,
+      {bool paused: false,
+      SendPort onExit,
+      SendPort onError,
+      bool errorsAreFatal,
+      bool checked,
+      Map<String, String> environment,
+      Uri packageRoot,
+      Uri packageConfig,
+      bool automaticPackageResolution: false}) {
+    throw new UnsupportedError("Isolate.spawnUri");
+  }
+
+  @patch
+  void _pause(Capability resumeCapability) {
+    throw new UnsupportedError("Isolate._pause");
+  }
+
+  @patch
+  void resume(Capability resumeCapability) {
+    throw new UnsupportedError("Isolate.resume");
+  }
+
+  @patch
+  void addOnExitListener(SendPort responsePort, {Object response}) {
+    throw new UnsupportedError("Isolate.addOnExitListener");
+  }
+
+  @patch
+  void removeOnExitListener(SendPort responsePort) {
+    throw new UnsupportedError("Isolate.removeOnExitListener");
+  }
+
+  @patch
+  void setErrorsFatal(bool errorsAreFatal) {
+    throw new UnsupportedError("Isolate.setErrorsFatal");
+  }
+
+  @patch
+  void kill({int priority: beforeNextEvent}) {
+    throw new UnsupportedError("Isolate.kill");
+  }
+
+  @patch
+  void ping(SendPort responsePort, {Object response, int priority: immediate}) {
+    throw new UnsupportedError("Isolate.ping");
+  }
+
+  @patch
+  void addErrorListener(SendPort port) {
+    throw new UnsupportedError("Isolate.addErrorListener");
+  }
+
+  @patch
+  void removeErrorListener(SendPort port) {
+    throw new UnsupportedError("Isolate.removeErrorListener");
+  }
+}
+
+@patch
+class ReceivePort {
+  @patch
+  factory ReceivePort() = _ReceivePortImpl;
+
+  @patch
+  factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) {
+    throw new UnsupportedError('new ReceivePort.fromRawReceivePort');
+  }
+}
+
+class _ReceivePortImpl extends Stream implements ReceivePort {
+  StreamSubscription listen(void onData(var event),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    throw new UnsupportedError("ReceivePort.listen");
+  }
+
+  void close() {}
+
+  SendPort get sendPort => throw new UnsupportedError("ReceivePort.sendPort");
+}
+
+@patch
+class RawReceivePort {
+  @patch
+  factory RawReceivePort([Function handler]) {
+    throw new UnsupportedError('new RawReceivePort');
+  }
+}
+
+@patch
+class Capability {
+  @patch
+  factory Capability() {
+    throw new UnsupportedError('new Capability');
+  }
+}
+
+@patch
+abstract class TransferableTypedData {
+  @patch
+  factory TransferableTypedData.fromList(List<TypedData> list) {
+    throw new UnsupportedError('TransferableTypedData.fromList');
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart
new file mode 100644
index 0000000..ff820d4
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart
@@ -0,0 +1,734 @@
+// Copyright (c) 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 _interceptors;
+
+class _Growable {
+  const _Growable();
+}
+
+const _ListConstructorSentinel = const _Growable();
+
+/// The interceptor class for [List]. The compiler recognizes this
+/// class as an interceptor, and changes references to [:this:] to
+/// actually use the receiver of the method, which is generated as an extra
+/// argument added to each member.
+class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
+  const JSArray();
+
+  // This factory constructor is the redirection target of the List() factory
+  // constructor. [length] has no type to permit the sentinel value.
+  factory JSArray.list([length = _ListConstructorSentinel]) {
+    if (_ListConstructorSentinel == length) {
+      return new JSArray<E>.emptyGrowable();
+    }
+    return new JSArray<E>.fixed(length);
+  }
+
+  /// Returns a fresh JavaScript Array, marked as fixed-length.
+  ///
+  /// [length] must be a non-negative integer.
+  factory JSArray.fixed(int length) {
+    // Explicit type test is necessary to guard against JavaScript conversions
+    // in unchecked mode, and against `new Array(null)` which creates a single
+    // element Array containing `null`.
+    if (length is! int) {
+      throw new ArgumentError.value(length, 'length', 'is not an integer');
+    }
+    // The JavaScript Array constructor with one argument throws if
+    // the value is not a UInt32. Give a better error message.
+    int maxJSArrayLength = 0xFFFFFFFF;
+    if (length < 0 || length > maxJSArrayLength) {
+      throw new RangeError.range(length, 0, maxJSArrayLength, 'length');
+    }
+    return new JSArray<E>.markFixed(JS('', 'new Array(#)', length));
+  }
+
+  /// Returns a fresh growable JavaScript Array of zero length length.
+  factory JSArray.emptyGrowable() => new JSArray<E>.markGrowable(JS('', '[]'));
+
+  /// Returns a fresh growable JavaScript Array with initial length.
+  ///
+  /// [validatedLength] must be a non-negative integer.
+  factory JSArray.growable(int length) {
+    // Explicit type test is necessary to guard against JavaScript conversions
+    // in unchecked mode.
+    if ((length is! int) || (length < 0)) {
+      throw new ArgumentError('Length must be a non-negative integer: $length');
+    }
+    return new JSArray<E>.markGrowable(JS('', 'new Array(#)', length));
+  }
+
+  /// Constructor for adding type parameters to an existing JavaScript Array.
+  /// The compiler specially recognizes this constructor.
+  ///
+  ///     var a = new JSArray<int>.typed(JS('JSExtendableArray', '[]'));
+  ///     a is List<int>    --> true
+  ///     a is List<String> --> false
+  ///
+  /// Usually either the [JSArray.markFixed] or [JSArray.markGrowable]
+  /// constructors is used instead.
+  ///
+  /// The input must be a JavaScript Array.  The JS form is just a re-assertion
+  /// to help type analysis when the input type is sloppy.
+  factory JSArray.typed(allocation) => JS('JSArray', '#', allocation);
+
+  factory JSArray.markFixed(allocation) =>
+      JS('JSFixedArray', '#', markFixedList(new JSArray<E>.typed(allocation)));
+
+  factory JSArray.markGrowable(allocation) =>
+      JS('JSExtendableArray', '#', new JSArray<E>.typed(allocation));
+
+  static List markFixedList(List list) {
+    // Functions are stored in the hidden class and not as properties in
+    // the object. We never actually look at the value, but only want
+    // to know if the property exists.
+    JS('void', r'#.fixed$length = Array', list);
+    return JS('JSFixedArray', '#', list);
+  }
+
+  static List markUnmodifiableList(List list) {
+    // Functions are stored in the hidden class and not as properties in
+    // the object. We never actually look at the value, but only want
+    // to know if the property exists.
+    JS('void', r'#.fixed$length = Array', list);
+    JS('void', r'#.immutable$list = Array', list);
+    return JS('JSUnmodifiableArray', '#', list);
+  }
+
+  static bool isFixedLength(JSArray a) {
+    return !JS('bool', r'!#.fixed$length', a);
+  }
+
+  static bool isUnmodifiable(JSArray a) {
+    return !JS('bool', r'!#.immutable$list', a);
+  }
+
+  static bool isGrowable(JSArray a) {
+    return !isFixedLength(a);
+  }
+
+  static bool isMutable(JSArray a) {
+    return !isUnmodifiable(a);
+  }
+
+  checkMutable(String reason) {
+    if (!isMutable(this)) {
+      throw UnsupportedError(reason);
+    }
+  }
+
+  checkGrowable(String reason) {
+    if (!isGrowable(this)) {
+      throw UnsupportedError(reason);
+    }
+  }
+
+  List<R> cast<R>() => List.castFrom<E, R>(this);
+  void add(E value) {
+    checkGrowable('add');
+    JS('void', r'#.push(#)', this, value);
+  }
+
+  E removeAt(int index) {
+    checkGrowable('removeAt');
+    if (index is! int) throw argumentErrorValue(index);
+    if (index < 0 || index >= length) {
+      throw new RangeError.value(index);
+    }
+    return JS('', r'#.splice(#, 1)[0]', this, index);
+  }
+
+  void insert(int index, E value) {
+    checkGrowable('insert');
+    if (index is! int) throw argumentErrorValue(index);
+    if (index < 0 || index > length) {
+      throw new RangeError.value(index);
+    }
+    JS('void', r'#.splice(#, 0, #)', this, index, value);
+  }
+
+  void insertAll(int index, Iterable<E> iterable) {
+    checkGrowable('insertAll');
+    RangeError.checkValueInInterval(index, 0, this.length, 'index');
+    if (iterable is! EfficientLengthIterable) {
+      iterable = iterable.toList();
+    }
+    int insertionLength = iterable.length;
+    this.length += insertionLength;
+    int end = index + insertionLength;
+    this.setRange(end, this.length, this, index);
+    this.setRange(index, end, iterable);
+  }
+
+  void setAll(int index, Iterable<E> iterable) {
+    checkMutable('setAll');
+    RangeError.checkValueInInterval(index, 0, this.length, 'index');
+    for (var element in iterable) {
+      this[index++] = element;
+    }
+  }
+
+  E removeLast() {
+    checkGrowable('removeLast');
+    if (length == 0) throw diagnoseIndexError(this, -1);
+    return JS('', r'#.pop()', this);
+  }
+
+  bool remove(Object element) {
+    checkGrowable('remove');
+    for (int i = 0; i < this.length; i++) {
+      if (this[i] == element) {
+        JS('', r'#.splice(#, 1)', this, i);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /// Removes elements matching [test] from [this] List.
+  void removeWhere(bool test(E element)) {
+    checkGrowable('removeWhere');
+    _removeWhere(test, true);
+  }
+
+  void retainWhere(bool test(E element)) {
+    checkGrowable('retainWhere');
+    _removeWhere(test, false);
+  }
+
+  void _removeWhere(bool test(E element), bool removeMatching) {
+    // Performed in two steps, to avoid exposing an inconsistent state
+    // to the [test] function. First the elements to retain are found, and then
+    // the original list is updated to contain those elements.
+
+    // TODO(sra): Replace this algorithm with one that retains a list of ranges
+    // to be removed.  Most real uses remove 0, 1 or a few clustered elements.
+
+    List retained = [];
+    int end = this.length;
+    for (int i = 0; i < end; i++) {
+      // TODO(22407): Improve bounds check elimination to allow this JS code to
+      // be replaced by indexing.
+      var element = JS<E>('', '#[#]', this, i);
+      // !test() ensures bool conversion in checked mode.
+      if (!test(element) == removeMatching) {
+        retained.add(element);
+      }
+      if (this.length != end) throw new ConcurrentModificationError(this);
+    }
+    if (retained.length == end) return;
+    this.length = retained.length;
+    for (int i = 0; i < retained.length; i++) {
+      // We don't need a bounds check or an element type check.
+      JS('', '#[#] = #', this, i, retained[i]);
+    }
+  }
+
+  Iterable<E> where(bool f(E element)) {
+    return new WhereIterable<E>(this, f);
+  }
+
+  Iterable<T> expand<T>(Iterable<T> f(E element)) {
+    return new ExpandIterable<E, T>(this, f);
+  }
+
+  void addAll(Iterable<E> collection) {
+    int i = this.length;
+    checkGrowable('addAll');
+    for (E e in collection) {
+      assert(
+          i++ == this.length || (throw new ConcurrentModificationError(this)));
+      JS('void', r'#.push(#)', this, e);
+    }
+  }
+
+  void clear() {
+    length = 0;
+  }
+
+  void forEach(void f(E element)) {
+    int end = this.length;
+    for (int i = 0; i < end; i++) {
+      // TODO(22407): Improve bounds check elimination to allow this JS code to
+      // be replaced by indexing.
+      var element = JS<E>('', '#[#]', this, i);
+      f(element);
+      if (this.length != end) throw new ConcurrentModificationError(this);
+    }
+  }
+
+  Iterable<T> map<T>(T f(E element)) {
+    return new MappedListIterable<E, T>(this, f);
+  }
+
+  String join([String separator = '']) {
+    var list = new List(this.length);
+    for (int i = 0; i < this.length; i++) {
+      list[i] = '${this[i]}';
+    }
+    return JS('String', '#.join(#)', list, separator);
+  }
+
+  Iterable<E> take(int n) {
+    return new SubListIterable<E>(this, 0, n);
+  }
+
+  Iterable<E> takeWhile(bool test(E value)) {
+    return new TakeWhileIterable<E>(this, test);
+  }
+
+  Iterable<E> skip(int n) {
+    return new SubListIterable<E>(this, n, null);
+  }
+
+  Iterable<E> skipWhile(bool test(E value)) {
+    return new SkipWhileIterable<E>(this, test);
+  }
+
+  E reduce(E combine(E previousValue, E element)) {
+    int length = this.length;
+    if (length == 0) throw IterableElementError.noElement();
+    E value = this[0];
+    for (int i = 1; i < length; i++) {
+      // TODO(22407): Improve bounds check elimination to allow this JS code to
+      // be replaced by indexing.
+      var element = JS<E>('', '#[#]', this, i);
+      value = combine(value, element);
+      if (length != this.length) throw new ConcurrentModificationError(this);
+    }
+    return value;
+  }
+
+  T fold<T>(T initialValue, T combine(T previousValue, E element)) {
+    var value = initialValue;
+    int length = this.length;
+    for (int i = 0; i < length; i++) {
+      // TODO(22407): Improve bounds check elimination to allow this JS code to
+      // be replaced by indexing.
+      var element = JS<E>('', '#[#]', this, i);
+      value = combine(value, element);
+      if (this.length != length) throw new ConcurrentModificationError(this);
+    }
+    return value;
+  }
+
+  E firstWhere(bool test(E value), {E orElse()}) {
+    var end = this.length;
+    for (int i = 0; i < end; ++i) {
+      // TODO(22407): Improve bounds check elimination to allow this JS code to
+      // be replaced by indexing.
+      var element = JS<E>('', '#[#]', this, i);
+      if (test(element)) return element;
+      if (this.length != end) throw new ConcurrentModificationError(this);
+    }
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E lastWhere(bool test(E element), {E orElse()}) {
+    int length = this.length;
+    for (int i = length - 1; i >= 0; i--) {
+      // TODO(22407): Improve bounds check elimination to allow this JS code to
+      // be replaced by indexing.
+      var element = JS<E>('', '#[#]', this, i);
+      if (test(element)) return element;
+      if (length != this.length) {
+        throw new ConcurrentModificationError(this);
+      }
+    }
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E singleWhere(bool test(E element), {E orElse()}) {
+    int length = this.length;
+    E match = null;
+    bool matchFound = false;
+    for (int i = 0; i < length; i++) {
+      // TODO(22407): Improve bounds check elimination to allow this JS code to
+      // be replaced by indexing.
+      var element = JS<E>('', '#[#]', this, i);
+      if (test(element)) {
+        if (matchFound) {
+          throw IterableElementError.tooMany();
+        }
+        matchFound = true;
+        match = element;
+      }
+      if (length != this.length) {
+        throw new ConcurrentModificationError(this);
+      }
+    }
+    if (matchFound) return match;
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E elementAt(int index) {
+    return this[index];
+  }
+
+  List<E> sublist(int start, [int end]) {
+    checkNull(start); // TODO(ahe): This is not specified but co19 tests it.
+    if (start is! int) throw argumentErrorValue(start);
+    if (start < 0 || start > length) {
+      throw new RangeError.range(start, 0, length, 'start');
+    }
+    if (end == null) {
+      end = length;
+    } else {
+      if (end is! int) throw argumentErrorValue(end);
+      if (end < start || end > length) {
+        throw new RangeError.range(end, start, length, 'end');
+      }
+    }
+    if (start == end) return <E>[];
+    return new JSArray<E>.markGrowable(
+        JS('', r'#.slice(#, #)', this, start, end));
+  }
+
+  Iterable<E> getRange(int start, int end) {
+    RangeError.checkValidRange(start, end, this.length);
+    return new SubListIterable<E>(this, start, end);
+  }
+
+  E get first {
+    if (length > 0) return this[0];
+    throw IterableElementError.noElement();
+  }
+
+  E get last {
+    if (length > 0) return this[length - 1];
+    throw IterableElementError.noElement();
+  }
+
+  E get single {
+    if (length == 1) return this[0];
+    if (length == 0) throw IterableElementError.noElement();
+    throw IterableElementError.tooMany();
+  }
+
+  void removeRange(int start, int end) {
+    checkGrowable('removeRange');
+    RangeError.checkValidRange(start, end, this.length);
+    int deleteCount = end - start;
+    JS('', '#.splice(#, #)', this, start, deleteCount);
+  }
+
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+    checkMutable('setRange');
+
+    RangeError.checkValidRange(start, end, this.length);
+    int length = end - start;
+    if (length == 0) return;
+    RangeError.checkNotNegative(skipCount, 'skipCount');
+
+    List<E> otherList;
+    int otherStart;
+    // TODO(floitsch): Make this accept more.
+    if (iterable is List) {
+      otherList = iterable;
+      otherStart = skipCount;
+    } else {
+      otherList = iterable.skip(skipCount).toList(growable: false);
+      otherStart = 0;
+    }
+    if (otherStart + length > otherList.length) {
+      throw IterableElementError.tooFew();
+    }
+    if (otherStart < start) {
+      // Copy backwards to ensure correct copy if [from] is this.
+      // TODO(sra): If [from] is the same Array as [this], we can copy without
+      // type annotation checks on the stores.
+      for (int i = length - 1; i >= 0; i--) {
+        // Use JS to avoid bounds check (the bounds check elimination
+        // optimzation is too weak). The 'E' type annotation is a store type
+        // check - we can't rely on iterable, it could be List<dynamic>.
+        E element = otherList[otherStart + i];
+        JS('', '#[#] = #', this, start + i, element);
+      }
+    } else {
+      for (int i = 0; i < length; i++) {
+        E element = otherList[otherStart + i];
+        JS('', '#[#] = #', this, start + i, element);
+      }
+    }
+  }
+
+  void fillRange(int start, int end, [E fillValue]) {
+    checkMutable('fill range');
+    RangeError.checkValidRange(start, end, this.length);
+    for (int i = start; i < end; i++) {
+      // Store is safe since [fillValue] type has been checked as parameter.
+      JS('', '#[#] = #', this, i, fillValue);
+    }
+  }
+
+  void replaceRange(int start, int end, Iterable<E> replacement) {
+    checkGrowable('replaceRange');
+    RangeError.checkValidRange(start, end, this.length);
+    if (replacement is! EfficientLengthIterable) {
+      replacement = replacement.toList();
+    }
+    int removeLength = end - start;
+    int insertLength = replacement.length;
+    if (removeLength >= insertLength) {
+      int delta = removeLength - insertLength;
+      int insertEnd = start + insertLength;
+      int newLength = this.length - delta;
+      this.setRange(start, insertEnd, replacement);
+      if (delta != 0) {
+        this.setRange(insertEnd, newLength, this, end);
+        this.length = newLength;
+      }
+    } else {
+      int delta = insertLength - removeLength;
+      int newLength = this.length + delta;
+      int insertEnd = start + insertLength; // aka. end + delta.
+      this.length = newLength;
+      this.setRange(insertEnd, newLength, this, end);
+      this.setRange(start, insertEnd, replacement);
+    }
+  }
+
+  bool any(bool test(E element)) {
+    int end = this.length;
+    for (int i = 0; i < end; i++) {
+      // TODO(22407): Improve bounds check elimination to allow this JS code to
+      // be replaced by indexing.
+      var element = JS<E>('', '#[#]', this, i);
+      if (test(element)) return true;
+      if (this.length != end) throw new ConcurrentModificationError(this);
+    }
+    return false;
+  }
+
+  bool every(bool test(E element)) {
+    int end = this.length;
+    for (int i = 0; i < end; i++) {
+      // TODO(22407): Improve bounds check elimination to allow this JS code to
+      // be replaced by indexing.
+      var element = JS<E>('', '#[#]', this, i);
+      if (!test(element)) return false;
+      if (this.length != end) throw new ConcurrentModificationError(this);
+    }
+    return true;
+  }
+
+  Iterable<E> get reversed => new ReversedListIterable<E>(this);
+
+  void sort([int compare(E a, E b)]) {
+    checkMutable('sort');
+    Sort.sort(this, compare ?? _compareAny);
+  }
+
+  static int _compareAny(a, b) {
+    // In strong mode Comparable.compare requires an implicit cast to ensure
+    // `a` and `b` are Comparable.
+    return Comparable.compare(a, b);
+  }
+
+  void shuffle([Random random]) {
+    checkMutable('shuffle');
+    if (random == null) random = new Random();
+    int length = this.length;
+    while (length > 1) {
+      int pos = random.nextInt(length);
+      length -= 1;
+      var tmp = this[length];
+      this[length] = this[pos];
+      this[pos] = tmp;
+    }
+  }
+
+  int indexOf(Object element, [int start = 0]) {
+    if (start >= this.length) {
+      return -1;
+    }
+    if (start < 0) {
+      start = 0;
+    }
+    for (int i = start; i < this.length; i++) {
+      if (this[i] == element) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  int lastIndexOf(Object element, [int startIndex]) {
+    if (startIndex == null) {
+      startIndex = this.length - 1;
+    } else {
+      if (startIndex < 0) {
+        return -1;
+      }
+      if (startIndex >= this.length) {
+        startIndex = this.length - 1;
+      }
+    }
+    for (int i = startIndex; i >= 0; i--) {
+      if (this[i] == element) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  bool contains(Object other) {
+    for (int i = 0; i < length; i++) {
+      if (this[i] == other) return true;
+    }
+    return false;
+  }
+
+  bool get isEmpty => length == 0;
+
+  bool get isNotEmpty => !isEmpty;
+
+  String toString() => ListBase.listToString(this);
+
+  List<E> toList({bool growable: true}) =>
+      growable ? _toListGrowable() : _toListFixed();
+
+  List<E> _toListGrowable() =>
+      // slice(0) is slightly faster than slice()
+      new JSArray<E>.markGrowable(JS('', '#.slice(0)', this));
+
+  List<E> _toListFixed() =>
+      new JSArray<E>.markFixed(JS('', '#.slice(0)', this));
+
+  Set<E> toSet() => new Set<E>.from(this);
+
+  Iterator<E> get iterator => new ArrayIterator<E>(this);
+
+  int get hashCode => Primitives.objectHashCode(this);
+
+  int get length => JS('JSUInt32', r'#.length', this);
+
+  set length(int newLength) {
+    checkGrowable('set length');
+    if (newLength is! int) {
+      throw new ArgumentError.value(newLength, 'newLength');
+    }
+    // TODO(sra): Remove this test and let JavaScript throw an error.
+    if (newLength < 0) {
+      throw new RangeError.range(newLength, 0, null, 'newLength');
+    }
+    // JavaScript with throw a RangeError for numbers that are too big. The
+    // message does not contain the value.
+    JS('void', r'#.length = #', this, newLength);
+  }
+
+  E operator [](int index) {
+    if (index is! int) throw diagnoseIndexError(this, index);
+    if (index >= length || index < 0) throw diagnoseIndexError(this, index);
+    return JS('', '#[#]', this, index);
+  }
+
+  void operator []=(int index, E value) {
+    checkMutable('indexed set');
+    if (index is! int) throw diagnoseIndexError(this, index);
+    if (index >= length || index < 0) throw diagnoseIndexError(this, index);
+    JS('void', r'#[#] = #', this, index, value);
+  }
+
+  Map<int, E> asMap() {
+    return new ListMapView<E>(this);
+  }
+
+  Iterable<E> followedBy(Iterable<E> other) =>
+      new FollowedByIterable<E>.firstEfficient(this, other);
+
+  Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this);
+
+  List<E> operator +(List<E> other) {
+    int totalLength = this.length + other.length;
+    return <E>[]
+      ..length = totalLength
+      ..setRange(0, this.length, this)
+      ..setRange(this.length, totalLength, other);
+  }
+
+  int indexWhere(bool test(E element), [int start = 0]) {
+    if (start >= this.length) return -1;
+    if (start < 0) start = 0;
+    for (int i = start; i < this.length; i++) {
+      if (test(this[i])) return i;
+    }
+    return -1;
+  }
+
+  int lastIndexWhere(bool test(E element), [int start]) {
+    if (start == null) start = this.length - 1;
+    if (start < 0) return -1;
+    for (int i = start; i >= 0; i--) {
+      if (test(this[i])) return i;
+    }
+    return -1;
+  }
+
+  void set first(E element) {
+    if (this.isEmpty) throw IterableElementError.noElement();
+    this[0] = element;
+  }
+
+  void set last(E element) {
+    if (this.isEmpty) throw IterableElementError.noElement();
+    this[this.length - 1] = element;
+  }
+}
+
+/// Dummy subclasses that allow the backend to track more precise
+/// information about arrays through their type. The CPA type inference
+/// relies on the fact that these classes do not override [] nor []=.
+///
+/// These classes are really a fiction, and can have no methods, since
+/// getInterceptor always returns JSArray.  We should consider pushing the
+/// 'isGrowable' and 'isMutable' checks into the getInterceptor implementation
+/// so these classes can have specialized implementations. Doing so will
+/// challenge many assumptions in the JS backend.
+class JSMutableArray<E> extends JSArray<E> implements JSMutableIndexable {}
+
+class JSFixedArray<E> extends JSMutableArray<E> {}
+
+class JSExtendableArray<E> extends JSMutableArray<E> {}
+
+class JSUnmodifiableArray<E> extends JSArray<E> {} // Already is JSIndexable.
+
+/// An [Iterator] that iterates a JSArray.
+///
+class ArrayIterator<E> implements Iterator<E> {
+  final JSArray<E> _iterable;
+  final int _length;
+  int _index;
+  E _current;
+
+  ArrayIterator(JSArray<E> iterable)
+      : _iterable = iterable,
+        _length = iterable.length,
+        _index = 0;
+
+  E get current => _current;
+
+  bool moveNext() {
+    int length = _iterable.length;
+
+    // We have to do the length check even on fixed length Arrays.  If we can
+    // inline moveNext() we might be able to GVN the length and eliminate this
+    // check on known fixed length JSArray.
+    if (_length != length) {
+      throw throwConcurrentModificationError(_iterable);
+    }
+
+    if (_index >= length) {
+      _current = null;
+      return false;
+    }
+    _current = _iterable[_index];
+    _index++;
+    return true;
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
new file mode 100644
index 0000000..8c167115
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
@@ -0,0 +1,3551 @@
+// 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 _js_helper;
+
+import 'dart:_js_embedded_names'
+    show
+        CURRENT_SCRIPT,
+        DEFERRED_LIBRARY_PARTS,
+        DEFERRED_PART_URIS,
+        DEFERRED_PART_HASHES,
+        GET_TYPE_FROM_NAME,
+        GET_ISOLATE_TAG,
+        INITIALIZE_LOADED_HUNK,
+        INTERCEPTED_NAMES,
+        INTERCEPTORS_BY_TAG,
+        IS_HUNK_LOADED,
+        IS_HUNK_INITIALIZED,
+        JsBuiltin,
+        JsGetName,
+        LEAF_TAGS,
+        NATIVE_SUPERCLASS_TAG_NAME,
+        STATIC_FUNCTION_NAME_PROPERTY_NAME;
+
+import 'dart:collection';
+
+import 'dart:async' show Completer, DeferredLoadException, Future;
+
+import 'dart:_foreign_helper'
+    show
+        DART_CLOSURE_TO_JS,
+        getInterceptor,
+        JS,
+        JS_BUILTIN,
+        JS_CONST,
+        JS_EFFECT,
+        JS_EMBEDDED_GLOBAL,
+        JS_GET_FLAG,
+        JS_GET_NAME,
+        JS_INTERCEPTOR_CONSTANT,
+        JS_STRING_CONCAT,
+        RAW_DART_FUNCTION_REF;
+
+import 'dart:_interceptors';
+import 'dart:_internal' as _symbol_dev;
+import 'dart:_internal'
+    show
+        EfficientLengthIterable,
+        MappedIterable,
+        IterableElementError,
+        SubListIterable;
+
+import 'dart:_native_typed_data';
+
+import 'dart:_js_names'
+    show
+        extractKeys,
+        unmangleGlobalNameIfPreservedAnyways,
+        unmangleAllIdentifiersIfPreservedAnyways;
+
+import 'dart:_rti' as newRti
+    show
+        createRuntimeType,
+        evalInInstance,
+        getRuntimeType,
+        getTypeFromTypesTable,
+        instanceTypeName,
+        instantiatedGenericFunctionType;
+
+part 'annotations.dart';
+part 'constant_map.dart';
+part 'instantiation.dart';
+part 'native_helper.dart';
+part 'regexp_helper.dart';
+part 'string_helper.dart';
+part 'js_rti.dart';
+part 'linked_hash_map.dart';
+
+/// Marks the internal map in dart2js, so that internal libraries can is-check
+/// them.
+abstract class InternalMap {}
+
+/// Extracts the JavaScript-constructor name from the given isCheckProperty.
+// TODO(floitsch): move this to foreign_helper.dart or similar.
+@pragma('dart2js:tryInline')
+String isCheckPropertyToJsConstructorName(String isCheckProperty) {
+  return JS_BUILTIN('returns:String;depends:none;effects:none',
+      JsBuiltin.isCheckPropertyToJsConstructorName, isCheckProperty);
+}
+
+/// Returns true if the given [type] is a function type object.
+// TODO(floitsch): move this to foreign_helper.dart or similar.
+@pragma('dart2js:tryInline')
+bool isDartFunctionType(Object type) {
+  // Function type test is using the `in` operator which doesn't work on
+  // primitive types.
+  assert(!(type == null || type is num || type is String));
+  return JS_BUILTIN(
+      'returns:bool;effects:none;depends:none', JsBuiltin.isFunctionType, type);
+}
+
+/// Returns true if the given [type] is a FutureOr type object.
+// TODO(floitsch): move this to foreign_helper.dart or similar.
+@pragma('dart2js:tryInline')
+bool isDartFutureOrType(Object type) {
+  // FutureOr test is using the `in` operator which doesn't work on primitive
+  // types.
+  assert(!(type == null || type is num || type is String));
+  return JS_BUILTIN(
+      'returns:bool;effects:none;depends:none', JsBuiltin.isFutureOrType, type);
+}
+
+@pragma('dart2js:tryInline')
+bool isDartVoidTypeRti(Object type) {
+  return JS_BUILTIN(
+      'returns:bool;effects:none;depends:none', JsBuiltin.isVoidType, type);
+}
+
+/// Retrieves the class name from type information stored on the constructor of
+/// [type].
+// TODO(floitsch): move this to foreign_helper.dart or similar.
+@pragma('dart2js:tryInline')
+String rawRtiToJsConstructorName(Object rti) {
+  return JS_BUILTIN('String', JsBuiltin.rawRtiToJsConstructorName, rti);
+}
+
+/// Given a raw constructor name, return the unminified name, if available,
+/// otherwise tag the name with `minified:`.
+String unminifyOrTag(String rawClassName) {
+  String preserved = unmangleGlobalNameIfPreservedAnyways(rawClassName);
+  if (preserved is String) return preserved;
+  if (JS_GET_FLAG('MINIFIED')) return 'minified:${rawClassName}';
+  return rawClassName;
+}
+
+/// Returns the rti from the given [constructorName].
+// TODO(floitsch): make this a builtin.
+jsConstructorNameToRti(String constructorName) {
+  var getTypeFromName = JS_EMBEDDED_GLOBAL('', GET_TYPE_FROM_NAME);
+  return JS('', '#(#)', getTypeFromName, constructorName);
+}
+
+/// Returns the raw runtime type of the given object [o].
+///
+/// The argument [o] must be the interceptor for primitive types. If
+/// necessary run it through [getInterceptor] first.
+// TODO(floitsch): move this to foreign_helper.dart or similar.
+// TODO(floitsch): we should call getInterceptor ourselves, but currently
+//    getInterceptor is not GVNed.
+@pragma('dart2js:tryInline')
+Object getRawRuntimeType(Object o) {
+  return JS_BUILTIN('', JsBuiltin.rawRuntimeType, o);
+}
+
+/// Returns whether the given [type] is a subtype of [other].
+///
+/// The argument [other] is the name of the other type, as computed by
+/// [runtimeTypeToString].
+@pragma('dart2js:tryInline')
+bool builtinIsSubtype(type, String other) {
+  return JS_BUILTIN('returns:bool;effects:none;depends:none',
+      JsBuiltin.isSubtype, other, type);
+}
+
+/// Returns true if the given [type] is _the_ `Function` type.
+// TODO(floitsch): move this to foreign_helper.dart or similar.
+@pragma('dart2js:tryInline')
+bool isDartFunctionTypeRti(Object type) {
+  return JS_BUILTIN(
+      'returns:bool;effects:none;depends:none',
+      JsBuiltin.isGivenTypeRti,
+      type,
+      JS_GET_NAME(JsGetName.FUNCTION_CLASS_TYPE_NAME));
+}
+
+/// Returns true if the given [type] is _the_ `Null` type.
+@pragma('dart2js:tryInline')
+bool isNullType(Object type) {
+  return JS_BUILTIN(
+      'returns:bool;effects:none;depends:none',
+      JsBuiltin.isGivenTypeRti,
+      type,
+      JS_GET_NAME(JsGetName.NULL_CLASS_TYPE_NAME));
+}
+
+/// Returns whether the given type is the dynamic type.
+// TODO(floitsch): move this to foreign_helper.dart or similar.
+@pragma('dart2js:tryInline')
+bool isDartDynamicTypeRti(type) {
+  return JS_BUILTIN(
+      'returns:bool;effects:none;depends:none', JsBuiltin.isDynamicType, type);
+}
+
+@pragma('dart2js:tryInline')
+bool isDartJsInteropTypeArgumentRti(type) {
+  return JS_BUILTIN('returns:bool;effects:none;depends:none',
+      JsBuiltin.isJsInteropTypeArgument, type);
+}
+
+/// Returns whether the given type is _the_ Dart Object type.
+// TODO(floitsch): move this to foreign_helper.dart or similar.
+@pragma('dart2js:tryInline')
+bool isDartObjectTypeRti(type) {
+  return JS_BUILTIN(
+      'returns:bool;effects:none;depends:none',
+      JsBuiltin.isGivenTypeRti,
+      type,
+      JS_GET_NAME(JsGetName.OBJECT_CLASS_TYPE_NAME));
+}
+
+/// Returns whether the given type is _the_ null type.
+// TODO(floitsch): move this to foreign_helper.dart or similar.
+@pragma('dart2js:tryInline')
+bool isNullTypeRti(type) {
+  return JS_BUILTIN(
+      'returns:bool;effects:none;depends:none',
+      JsBuiltin.isGivenTypeRti,
+      type,
+      JS_GET_NAME(JsGetName.NULL_CLASS_TYPE_NAME));
+}
+
+/// Returns the metadata of the given [index].
+// TODO(floitsch): move this to foreign_helper.dart or similar.
+@pragma('dart2js:tryInline')
+getMetadata(int index) {
+  return JS_BUILTIN(
+      'returns:var;effects:none;depends:none', JsBuiltin.getMetadata, index);
+}
+
+/// Returns the type of the given [index].
+// TODO(floitsch): move this to foreign_helper.dart or similar.
+@pragma('dart2js:tryInline')
+getType(int index) {
+  return JS_BUILTIN(
+      'returns:var;effects:none;depends:none', JsBuiltin.getType, index);
+}
+
+/// No-op method that is called to inform the compiler that preambles might
+/// be needed when executing the resulting JS file in a command-line
+/// JS engine.
+requiresPreamble() {}
+
+bool isJsIndexable(var object, var record) {
+  if (record != null) {
+    var result = dispatchRecordIndexability(record);
+    if (result != null) return result;
+  }
+  return object is JavaScriptIndexingBehavior;
+}
+
+String S(value) {
+  if (value is String) return value;
+  if (value is num) {
+    if (value != 0) {
+      // ""+x is faster than String(x) for integers on most browsers.
+      return JS('String', r'"" + (#)', value);
+    }
+  } else if (true == value) {
+    return 'true';
+  } else if (false == value) {
+    return 'false';
+  } else if (value == null) {
+    return 'null';
+  }
+  var res = value.toString();
+  if (res is! String) throw argumentErrorValue(value);
+  return res;
+}
+
+// Called from generated code.
+createInvocationMirror(
+    String name, internalName, kind, arguments, argumentNames, types) {
+  // TODO(sra): [types] (the number of type arguments) could be omitted in the
+  // generated stub code to save an argument. Then we would use `types ?? 0`.
+  return new JSInvocationMirror(
+      name, internalName, kind, arguments, argumentNames, types);
+}
+
+createUnmangledInvocationMirror(
+    Symbol symbol, internalName, kind, arguments, argumentNames, types) {
+  return new JSInvocationMirror(
+      symbol, internalName, kind, arguments, argumentNames, types);
+}
+
+void throwInvalidReflectionError(String memberName) {
+  throw new UnsupportedError("Can't use '$memberName' in reflection "
+      "because it is not included in a @MirrorsUsed annotation.");
+}
+
+/// Helper used to instrument calls when the compiler is invoked with
+/// `--experiment-call-instrumentation`.
+///
+/// By default, whenever a method is invoked for the first time, it prints an id
+/// and the method name to the console. This can be overriden by adding a top
+/// level `dartCallInstrumentation` hook in JavaScript.
+@pragma('dart2js:noInline')
+void traceHelper(dynamic /*int*/ id, dynamic /*String*/ qualifiedName) {
+  // Note: this method is written mostly in JavaScript to prevent a stack
+  // overflow. In particular, we use dynamic argument types because with with
+  // types, traceHelper would include type checks for the parameter types, those
+  // checks (intTypeCheck, stringTypeCheck) are themselves calls that end up
+  // invoking this traceHelper and produce a stack overflow.  Similarly if we
+  // had Dart code below using, for example, string interpolation, we would
+  // include extra calls to the Dart runtime that could also trigger a stack
+  // overflow. This approach here is simpler than making the compiler smart
+  // about how to generate traceHelper calls more carefully.
+  JS(
+      '',
+      r'''
+      (function (id, name) {
+        var hook = self.dartCallInstrumentation;
+        if (typeof hook === "function") {
+          hook(id, name);
+          return;
+        }
+        if (!this.callInstrumentationCache) {
+          this.callInstrumentationCache = Object.create(null);
+        }
+        if (!this.callInstrumentationCache[id]) {
+          console.log(id, name);
+          this.callInstrumentationCache[id] = true;
+        }
+      })(#, #)''',
+      id,
+      qualifiedName);
+}
+
+class JSInvocationMirror implements Invocation {
+  static const METHOD = 0;
+  static const GETTER = 1;
+  static const SETTER = 2;
+
+  /// 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;
+  final List _namedArgumentNames;
+  final int _typeArgumentCount;
+
+  JSInvocationMirror(this._memberName, this._internalName, this._kind,
+      this._arguments, this._namedArgumentNames, this._typeArgumentCount);
+
+  Symbol get memberName {
+    if (_memberName is Symbol) return _memberName;
+    return _memberName = new _symbol_dev.Symbol.unvalidated(_memberName);
+  }
+
+  bool get isMethod => _kind == METHOD;
+  bool get isGetter => _kind == GETTER;
+  bool get isSetter => _kind == SETTER;
+  bool get isAccessor => _kind != METHOD;
+
+  List<Type> get typeArguments {
+    if (_typeArgumentCount == 0) return const <Type>[];
+    int start = _arguments.length - _typeArgumentCount;
+    var list = <Type>[];
+    if (JS_GET_FLAG('USE_NEW_RTI')) {
+      for (int index = 0; index < _typeArgumentCount; index++) {
+        list.add(newRti.createRuntimeType(_arguments[start + index]));
+      }
+    } else {
+      for (int index = 0; index < _typeArgumentCount; index++) {
+        list.add(createRuntimeType(_arguments[start + index]));
+      }
+    }
+    return list;
+  }
+
+  List get positionalArguments {
+    if (isGetter) return const [];
+    var argumentCount =
+        _arguments.length - _namedArgumentNames.length - _typeArgumentCount;
+    if (argumentCount == 0) return const [];
+    var list = [];
+    for (var index = 0; index < argumentCount; index++) {
+      list.add(_arguments[index]);
+    }
+    return JSArray.markUnmodifiableList(list);
+  }
+
+  Map<Symbol, dynamic> get namedArguments {
+    if (isAccessor) return const <Symbol, dynamic>{};
+    int namedArgumentCount = _namedArgumentNames.length;
+    int namedArgumentsStartIndex =
+        _arguments.length - namedArgumentCount - _typeArgumentCount;
+    if (namedArgumentCount == 0) return const <Symbol, dynamic>{};
+    var map = new Map<Symbol, dynamic>();
+    for (int i = 0; i < namedArgumentCount; i++) {
+      map[new _symbol_dev.Symbol.unvalidated(_namedArgumentNames[i])] =
+          _arguments[namedArgumentsStartIndex + i];
+    }
+    return new ConstantMapView<Symbol, dynamic>(map);
+  }
+}
+
+class Primitives {
+  static int objectHashCode(object) {
+    int hash = JS('int|Null', r'#.$identityHash', object);
+    if (hash == null) {
+      hash = JS('int', '(Math.random() * 0x3fffffff) | 0');
+      JS('void', r'#.$identityHash = #', object, hash);
+    }
+    return JS('int', '#', hash);
+  }
+
+  static int parseInt(String source, int radix) {
+    checkString(source);
+    var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i');
+    var match = JS('JSExtendableArray|Null', '#.exec(#)', re, source);
+    int digitsIndex = 1;
+    int hexIndex = 2;
+    int decimalIndex = 3;
+    int nonDecimalHexIndex = 4;
+    if (match == null) {
+      // TODO(sra): It might be that the match failed due to unrecognized U+0085
+      // spaces.  We could replace them with U+0020 spaces and try matching
+      // again.
+      return null;
+    }
+    String decimalMatch = match[decimalIndex];
+    if (radix == null) {
+      if (decimalMatch != null) {
+        // Cannot fail because we know that the digits are all decimal.
+        return JS('int', r'parseInt(#, 10)', source);
+      }
+      if (match[hexIndex] != null) {
+        // Cannot fail because we know that the digits are all hex.
+        return JS('int', r'parseInt(#, 16)', source);
+      }
+      return null;
+    }
+
+    if (radix is! int) {
+      throw new ArgumentError.value(radix, 'radix', 'is not an integer');
+    }
+    if (radix < 2 || radix > 36) {
+      throw new RangeError.range(radix, 2, 36, 'radix');
+    }
+    if (radix == 10 && decimalMatch != null) {
+      // Cannot fail because we know that the digits are all decimal.
+      return JS('int', r'parseInt(#, 10)', source);
+    }
+    // If radix >= 10 and we have only decimal digits the string is safe.
+    // Otherwise we need to check the digits.
+    if (radix < 10 || decimalMatch == null) {
+      // We know that the characters must be ASCII as otherwise the
+      // regexp wouldn't have matched. Lowercasing by doing `| 0x20` is thus
+      // guaranteed to be a safe operation, since it preserves digits
+      // and lower-cases ASCII letters.
+      int maxCharCode;
+      if (radix <= 10) {
+        // Allow all digits less than the radix. For example 0, 1, 2 for
+        // radix 3.
+        // "0".codeUnitAt(0) + radix - 1;
+        maxCharCode = (0x30 - 1) + radix;
+      } else {
+        // Letters are located after the digits in ASCII. Therefore we
+        // only check for the character code. The regexp above made already
+        // sure that the string does not contain anything but digits or
+        // letters.
+        // "a".codeUnitAt(0) + (radix - 10) - 1;
+        maxCharCode = (0x61 - 10 - 1) + radix;
+      }
+      assert(match[digitsIndex] is String);
+      String digitsPart = JS('String', '#[#]', match, digitsIndex);
+      for (int i = 0; i < digitsPart.length; i++) {
+        int characterCode = digitsPart.codeUnitAt(i) | 0x20;
+        if (characterCode > maxCharCode) {
+          return null;
+        }
+      }
+    }
+    // The above matching and checks ensures the source has at least one digits
+    // and all digits are suitable for the radix, so parseInt cannot return NaN.
+    return JS('int', r'parseInt(#, #)', source, radix);
+  }
+
+  static double parseDouble(String source) {
+    checkString(source);
+    // Notice that JS parseFloat accepts garbage at the end of the string.
+    // Accept only:
+    // - [+/-]NaN
+    // - [+/-]Infinity
+    // - a Dart double literal
+    // We do allow leading or trailing whitespace.
+    if (!JS(
+        'bool',
+        r'/^\s*[+-]?(?:Infinity|NaN|'
+            r'(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(#)',
+        source)) {
+      return null;
+    }
+    var result = JS('num', r'parseFloat(#)', source);
+    if (result.isNaN) {
+      var trimmed = source.trim();
+      if (trimmed == 'NaN' || trimmed == '+NaN' || trimmed == '-NaN') {
+        return result;
+      }
+      return null;
+    }
+    return result;
+  }
+
+  /// [: r"$".codeUnitAt(0) :]
+  static const int DOLLAR_CHAR_VALUE = 36;
+
+  /// Creates a string containing the complete type for the class [className]
+  /// with the given type arguments.
+  ///
+  /// In minified mode, uses the unminified names if available.
+  ///
+  /// The given [className] string generally contains the name of the JavaScript
+  /// constructor of the given class.
+  static String formatType(String className, List typeArguments) {
+    return unmangleAllIdentifiersIfPreservedAnyways(
+        '$className${joinArguments(typeArguments, 0)}');
+  }
+
+  /// Returns the type of [object] as a string (including type arguments).
+  /// Tries to return a sensible name for non-Dart objects.
+  ///
+  /// In minified mode, uses the unminified names if available, otherwise tags
+  /// them with 'minified:'.
+  @pragma('dart2js:noInline')
+  static String objectTypeName(Object object) {
+    if (JS_GET_FLAG('USE_NEW_RTI')) {
+      return _objectTypeNameNewRti(object);
+    }
+    String className = _objectClassName(object);
+    String arguments = joinArguments(getRuntimeTypeInfo(object), 0);
+    return '${className}${arguments}';
+  }
+
+  static String _objectClassName(Object object) {
+    var interceptor = getInterceptor(object);
+    // The interceptor is either an object (self-intercepting plain Dart class),
+    // the prototype of the constructor for an Interceptor class (like
+    // `JSString.prototype`, `JSNull.prototype`), or an Interceptor object
+    // instance (`const JSString()`, should use `JSString.prototype`).
+    //
+    // These all should have a `constructor` property with a `name` property.
+    String name;
+    var interceptorConstructor = JS('', '#.constructor', interceptor);
+    if (JS('bool', 'typeof # == "function"', interceptorConstructor)) {
+      var interceptorConstructorName = JS('', '#.name', interceptorConstructor);
+      if (interceptorConstructorName is String) {
+        name = interceptorConstructorName;
+      }
+    }
+
+    if (name == null ||
+        identical(interceptor, JS_INTERCEPTOR_CONSTANT(Interceptor)) ||
+        object is UnknownJavaScriptObject) {
+      // Try to do better.  If we do not find something better, leave the name
+      // as 'UnknownJavaScriptObject' or 'Interceptor' (or the minified name).
+      //
+      // When we get here via the UnknownJavaScriptObject test (for JavaScript
+      // objects from outside the program), the object's constructor has a
+      // better name that 'UnknownJavaScriptObject'.
+      //
+      // When we get here the Interceptor test (for Native classes that are
+      // declared in the Dart program but have been 'folded' into Interceptor),
+      // the native class's constructor name is better than the generic
+      // 'Interceptor' (an abstract class).
+
+      // Try the [constructorNameFallback]. This gets the constructor name for
+      // any browser (used by [getNativeInterceptor]).
+      String dispatchName = constructorNameFallback(object);
+      name ??= dispatchName;
+      if (dispatchName == 'Object') {
+        // Try to decompile the constructor by turning it into a string and get
+        // the name out of that. If the decompiled name is a string containing
+        // an identifier, we use that instead of the very generic 'Object'.
+        var objectConstructor = JS('', '#.constructor', object);
+        if (JS('bool', 'typeof # == "function"', objectConstructor)) {
+          var match = JS('var', r'#.match(/^\s*function\s*([\w$]*)\s*\(/)',
+              JS('var', r'String(#)', objectConstructor));
+          var decompiledName = match == null ? null : JS('var', r'#[1]', match);
+          if (decompiledName is String &&
+              JS('bool', r'/^\w+$/.test(#)', decompiledName)) {
+            name = decompiledName;
+          }
+        }
+      }
+      return JS('String', '#', name);
+    }
+
+    // Type inference does not understand that [name] is now always a non-null
+    // String. (There is some imprecision in the negation of the disjunction.)
+    name = JS('String', '#', name);
+
+    // TODO(kasperl): If the namer gave us a fresh global name, we may
+    // want to remove the numeric suffix that makes it unique too.
+    if (name.length > 1 && identical(name.codeUnitAt(0), DOLLAR_CHAR_VALUE)) {
+      name = name.substring(1);
+    }
+    return unminifyOrTag(name);
+  }
+
+  /// Returns the type of [object] as a string (including type arguments).
+  /// Tries to return a sensible name for non-Dart objects.
+  ///
+  /// In minified mode, uses the unminified names if available, otherwise tags
+  /// them with 'minified:'.
+  static String _objectTypeNameNewRti(Object object) {
+    var dartObjectConstructor = JS_BUILTIN(
+        'depends:none;effects:none;', JsBuiltin.dartObjectConstructor);
+    if (JS('bool', '# instanceof #', object, dartObjectConstructor)) {
+      return newRti.instanceTypeName(object);
+    }
+
+    var interceptor = getInterceptor(object);
+    if (identical(interceptor, JS_INTERCEPTOR_CONSTANT(Interceptor)) ||
+        object is UnknownJavaScriptObject) {
+      // Try to do better.  If we do not find something better, fallthrough to
+      // Dart-type based name that leave the name as 'UnknownJavaScriptObject'
+      // or 'Interceptor' (or the minified versions thereof).
+      //
+      // When we get here via the UnknownJavaScriptObject test (for JavaScript
+      // objects from outside the program), the object's constructor has a
+      // better name that 'UnknownJavaScriptObject'.
+      //
+      // When we get here the Interceptor test (for Native classes that are
+      // declared in the Dart program but have been 'folded' into Interceptor),
+      // the native class's constructor name is better than the generic
+      // 'Interceptor' (an abstract class).
+
+      // Try the [constructorNameFallback]. This gets the constructor name for
+      // any browser (used by [getNativeInterceptor]).
+      String dispatchName = constructorNameFallback(object);
+      if (_saneNativeClassName(dispatchName)) return dispatchName;
+      var constructor = JS('', '#.constructor', object);
+      if (JS('bool', 'typeof # == "function"', constructor)) {
+        var constructorName = JS('', '#.name', constructor);
+        if (constructorName is String &&
+            _saneNativeClassName(constructorName)) {
+          return constructorName;
+        }
+      }
+    }
+
+    return newRti.instanceTypeName(object);
+  }
+
+  static bool _saneNativeClassName(name) =>
+      name != null && name != 'Object' && name != '';
+
+  /// In minified mode, uses the unminified names if available.
+  static String objectToHumanReadableString(Object object) {
+    String name = objectTypeName(object);
+    return "Instance of '$name'";
+  }
+
+  static int dateNow() => JS('int', r'Date.now()');
+
+  static void initTicker() {
+    if (timerFrequency != null) return;
+    // Start with low-resolution. We overwrite the fields if we find better.
+    timerFrequency = 1000;
+    timerTicks = dateNow;
+    if (JS('bool', 'typeof window == "undefined"')) return;
+    var window = JS('var', 'window');
+    if (window == null) return;
+    var performance = JS('var', '#.performance', window);
+    if (performance == null) return;
+    if (JS('bool', 'typeof #.now != "function"', performance)) return;
+    timerFrequency = 1000000;
+    timerTicks = () => (1000 * JS('num', '#.now()', performance)).floor();
+  }
+
+  static int timerFrequency;
+  static Function timerTicks;
+
+  static String currentUri() {
+    requiresPreamble();
+    // In a browser return self.location.href.
+    if (JS('bool', '!!self.location')) {
+      return JS('String', 'self.location.href');
+    }
+
+    return null;
+  }
+
+  /// Version of `String.fromCharCode.apply` that chunks the conversion to avoid
+  /// stack overflows due to very large argument arrays.
+  ///
+  /// [array] is pre-validated as a JSArray of int values but is not typed as
+  /// <int> so it can be called with any JSArray.
+  static String _fromCharCodeApply(List array) {
+    const kMaxApply = 500;
+    int end = array.length;
+    if (end <= kMaxApply) {
+      return JS('String', r'String.fromCharCode.apply(null, #)', array);
+    }
+    String result = '';
+    for (int i = 0; i < end; i += kMaxApply) {
+      int chunkEnd = (i + kMaxApply < end) ? i + kMaxApply : end;
+      result = JS(
+          'String',
+          r'# + String.fromCharCode.apply(null, #.slice(#, #))',
+          result,
+          array,
+          i,
+          chunkEnd);
+    }
+    return result;
+  }
+
+  static String stringFromCodePoints(codePoints) {
+    List<int> a = <int>[];
+    for (var i in codePoints) {
+      if (i is! int) throw argumentErrorValue(i);
+      if (i <= 0xffff) {
+        a.add(i);
+      } else if (i <= 0x10ffff) {
+        a.add(0xd800 + ((((i - 0x10000) >> 10) & 0x3ff)));
+        a.add(0xdc00 + (i & 0x3ff));
+      } else {
+        throw argumentErrorValue(i);
+      }
+    }
+    return _fromCharCodeApply(a);
+  }
+
+  static String stringFromCharCodes(charCodes) {
+    for (var i in charCodes) {
+      if (i is! int) throw argumentErrorValue(i);
+      if (i < 0) throw argumentErrorValue(i);
+      if (i > 0xffff) return stringFromCodePoints(charCodes);
+    }
+    return _fromCharCodeApply(charCodes);
+  }
+
+  // [start] and [end] are validated.
+  static String stringFromNativeUint8List(
+      NativeUint8List charCodes, int start, int end) {
+    const kMaxApply = 500;
+    if (end <= kMaxApply && start == 0 && end == charCodes.length) {
+      return JS('String', r'String.fromCharCode.apply(null, #)', charCodes);
+    }
+    String result = '';
+    for (int i = start; i < end; i += kMaxApply) {
+      int chunkEnd = (i + kMaxApply < end) ? i + kMaxApply : end;
+      result = JS(
+          'String',
+          r'# + String.fromCharCode.apply(null, #.subarray(#, #))',
+          result,
+          charCodes,
+          i,
+          chunkEnd);
+    }
+    return result;
+  }
+
+  static String stringFromCharCode(charCode) {
+    if (0 <= charCode) {
+      if (charCode <= 0xffff) {
+        return JS('returns:String;effects:none;depends:none',
+            'String.fromCharCode(#)', charCode);
+      }
+      if (charCode <= 0x10ffff) {
+        var bits = charCode - 0x10000;
+        var low = 0xDC00 | (bits & 0x3ff);
+        var high = 0xD800 | (bits >> 10);
+        return JS('returns:String;effects:none;depends:none',
+            'String.fromCharCode(#, #)', high, low);
+      }
+    }
+    throw new RangeError.range(charCode, 0, 0x10ffff);
+  }
+
+  static String stringConcatUnchecked(String string1, String string2) {
+    return JS_STRING_CONCAT(string1, string2);
+  }
+
+  static String flattenString(String str) {
+    return JS('returns:String;depends:none;effects:none;throws:never;gvn:true',
+        '#.charCodeAt(0) == 0 ? # : #', str, str, str);
+  }
+
+  static String getTimeZoneName(DateTime receiver) {
+    // Firefox and Chrome emit the timezone in parenthesis.
+    // Example: "Wed May 16 2012 21:13:00 GMT+0200 (CEST)".
+    // We extract this name using a regexp.
+    var d = lazyAsJsDate(receiver);
+    List match = JS('JSArray|Null', r'/\((.*)\)/.exec(#.toString())', d);
+    if (match != null) return match[1];
+
+    // Internet Explorer 10+ emits the zone name without parenthesis:
+    // Example: Thu Oct 31 14:07:44 PDT 2013
+    match = JS(
+        'JSArray|Null',
+        // Thu followed by a space.
+        r'/^[A-Z,a-z]{3}\s'
+            // Oct 31 followed by space.
+            r'[A-Z,a-z]{3}\s\d+\s'
+            // Time followed by a space.
+            r'\d{2}:\d{2}:\d{2}\s'
+            // The time zone name followed by a space.
+            r'([A-Z]{3,5})\s'
+            // The year.
+            r'\d{4}$/'
+            '.exec(#.toString())',
+        d);
+    if (match != null) return match[1];
+
+    // IE 9 and Opera don't provide the zone name. We fall back to emitting the
+    // UTC/GMT offset.
+    // Example (IE9): Wed Nov 20 09:51:00 UTC+0100 2013
+    //       (Opera): Wed Nov 20 2013 11:03:38 GMT+0100
+    match = JS('JSArray|Null', r'/(?:GMT|UTC)[+-]\d{4}/.exec(#.toString())', d);
+    if (match != null) return match[0];
+    return '';
+  }
+
+  static int getTimeZoneOffsetInMinutes(DateTime receiver) {
+    // Note that JS and Dart disagree on the sign of the offset.
+    // Subtract to avoid -0.0
+    return 0 - JS('int', r'#.getTimezoneOffset()', lazyAsJsDate(receiver));
+  }
+
+  static int valueFromDecomposedDate(
+      years, month, day, hours, minutes, seconds, milliseconds, isUtc) {
+    final int MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000;
+    checkInt(years);
+    checkInt(month);
+    checkInt(day);
+    checkInt(hours);
+    checkInt(minutes);
+    checkInt(seconds);
+    checkInt(milliseconds);
+    checkBool(isUtc);
+    var jsMonth = month - 1;
+    // The JavaScript Date constructor 'corrects' year NN to 19NN. Sidestep that
+    // correction by adjusting years out of that range and compensating with an
+    // adjustment of months. This hack should not be sensitive to leap years but
+    // use 400 just in case.
+    if (0 <= years && years < 100) {
+      years += 400;
+      jsMonth -= 400 * 12;
+    }
+    var value;
+    if (isUtc) {
+      value = JS('num', r'Date.UTC(#, #, #, #, #, #, #)', years, jsMonth, day,
+          hours, minutes, seconds, milliseconds);
+    } else {
+      value = JS('num', r'new Date(#, #, #, #, #, #, #).valueOf()', years,
+          jsMonth, day, hours, minutes, seconds, milliseconds);
+    }
+    if (value.isNaN ||
+        value < -MAX_MILLISECONDS_SINCE_EPOCH ||
+        value > MAX_MILLISECONDS_SINCE_EPOCH) {
+      return null;
+    }
+    return JS('int', '#', value);
+  }
+
+  // Lazily keep a JS Date stored in the JS object.
+  static lazyAsJsDate(DateTime receiver) {
+    if (JS('bool', r'#.date === (void 0)', receiver)) {
+      JS('void', r'#.date = new Date(#)', receiver,
+          receiver.millisecondsSinceEpoch);
+    }
+    return JS('var', r'#.date', receiver);
+  }
+
+  // The getters for date and time parts below add a positive integer to ensure
+  // that the result is really an integer, because the JavaScript implementation
+  // may return -0.0 instead of 0.
+  //
+  // They are marked as @pragma('dart2js:noThrows') because `receiver` comes from a receiver of
+  // a method on DateTime (i.e. is not `null`).
+
+  // TODO(sra): These methods are GVN-able. dart2js should implement an
+  // annotation for that.
+
+  // TODO(sra): These methods often occur in groups (e.g. day, month and
+  // year). Is it possible to factor them so that the `Date` is visible and can
+  // be GVN-ed without a lot of code bloat?
+
+  @pragma('dart2js:noSideEffects')
+  @pragma('dart2js:noThrows')
+  @pragma('dart2js:noInline')
+  static getYear(DateTime receiver) {
+    return (receiver.isUtc)
+        ? JS('int', r'(#.getUTCFullYear() + 0)', lazyAsJsDate(receiver))
+        : JS('int', r'(#.getFullYear() + 0)', lazyAsJsDate(receiver));
+  }
+
+  @pragma('dart2js:noSideEffects')
+  @pragma('dart2js:noThrows')
+  @pragma('dart2js:noInline')
+  static getMonth(DateTime receiver) {
+    return (receiver.isUtc)
+        ? JS('JSUInt31', r'#.getUTCMonth() + 1', lazyAsJsDate(receiver))
+        : JS('JSUInt31', r'#.getMonth() + 1', lazyAsJsDate(receiver));
+  }
+
+  @pragma('dart2js:noSideEffects')
+  @pragma('dart2js:noThrows')
+  @pragma('dart2js:noInline')
+  static getDay(DateTime receiver) {
+    return (receiver.isUtc)
+        ? JS('JSUInt31', r'(#.getUTCDate() + 0)', lazyAsJsDate(receiver))
+        : JS('JSUInt31', r'(#.getDate() + 0)', lazyAsJsDate(receiver));
+  }
+
+  @pragma('dart2js:noSideEffects')
+  @pragma('dart2js:noThrows')
+  @pragma('dart2js:noInline')
+  static getHours(DateTime receiver) {
+    return (receiver.isUtc)
+        ? JS('JSUInt31', r'(#.getUTCHours() + 0)', lazyAsJsDate(receiver))
+        : JS('JSUInt31', r'(#.getHours() + 0)', lazyAsJsDate(receiver));
+  }
+
+  @pragma('dart2js:noSideEffects')
+  @pragma('dart2js:noThrows')
+  @pragma('dart2js:noInline')
+  static getMinutes(DateTime receiver) {
+    return (receiver.isUtc)
+        ? JS('JSUInt31', r'(#.getUTCMinutes() + 0)', lazyAsJsDate(receiver))
+        : JS('JSUInt31', r'(#.getMinutes() + 0)', lazyAsJsDate(receiver));
+  }
+
+  @pragma('dart2js:noSideEffects')
+  @pragma('dart2js:noThrows')
+  @pragma('dart2js:noInline')
+  static getSeconds(DateTime receiver) {
+    return (receiver.isUtc)
+        ? JS('JSUInt31', r'(#.getUTCSeconds() + 0)', lazyAsJsDate(receiver))
+        : JS('JSUInt31', r'(#.getSeconds() + 0)', lazyAsJsDate(receiver));
+  }
+
+  @pragma('dart2js:noSideEffects')
+  @pragma('dart2js:noThrows')
+  @pragma('dart2js:noInline')
+  static getMilliseconds(DateTime receiver) {
+    return (receiver.isUtc)
+        ? JS(
+            'JSUInt31', r'(#.getUTCMilliseconds() + 0)', lazyAsJsDate(receiver))
+        : JS('JSUInt31', r'(#.getMilliseconds() + 0)', lazyAsJsDate(receiver));
+  }
+
+  @pragma('dart2js:noSideEffects')
+  @pragma('dart2js:noThrows')
+  @pragma('dart2js:noInline')
+  static getWeekday(DateTime receiver) {
+    int weekday = (receiver.isUtc)
+        ? JS('int', r'#.getUTCDay() + 0', lazyAsJsDate(receiver))
+        : JS('int', r'#.getDay() + 0', lazyAsJsDate(receiver));
+    // Adjust by one because JS weeks start on Sunday.
+    return (weekday + 6) % 7 + 1;
+  }
+
+  static valueFromDateString(str) {
+    if (str is! String) throw argumentErrorValue(str);
+    var value = JS('num', r'Date.parse(#)', str);
+    if (value.isNaN) throw argumentErrorValue(str);
+    return value;
+  }
+
+  static getProperty(object, key) {
+    if (object == null || object is bool || object is num || object is String) {
+      throw argumentErrorValue(object);
+    }
+    return JS('var', '#[#]', object, key);
+  }
+
+  static void setProperty(object, key, value) {
+    if (object == null || object is bool || object is num || object is String) {
+      throw argumentErrorValue(object);
+    }
+    JS('void', '#[#] = #', object, key, value);
+  }
+
+  static functionNoSuchMethod(
+      function, List positionalArguments, Map<String, dynamic> namedArguments) {
+    int argumentCount = 0;
+    List arguments = [];
+    List namedArgumentList = [];
+
+    if (positionalArguments != null) {
+      argumentCount += positionalArguments.length;
+      arguments.addAll(positionalArguments);
+    }
+
+    String names = '';
+    if (namedArguments != null && !namedArguments.isEmpty) {
+      namedArguments.forEach((String name, argument) {
+        names = '$names\$$name';
+        namedArgumentList.add(name);
+        arguments.add(argument);
+        argumentCount++;
+      });
+    }
+
+    String selectorName =
+        '${JS_GET_NAME(JsGetName.CALL_PREFIX)}\$$argumentCount$names';
+
+    return function.noSuchMethod(createUnmangledInvocationMirror(
+        #call,
+        selectorName,
+        JSInvocationMirror.METHOD,
+        arguments,
+        namedArgumentList,
+        0));
+  }
+
+  /// Implements [Function.apply] for the lazy and startup emitters.
+  ///
+  /// There are two types of closures that can reach this function:
+  ///
+  /// 1. tear-offs (including tear-offs of static functions).
+  /// 2. anonymous closures.
+  ///
+  /// They are treated differently (although there are lots of similarities).
+  /// Both have in common that they have
+  /// a [JsGetName.CALL_CATCH_ALL] and
+  /// a [JsGetName.REQUIRED_PARAMETER_PROPERTY] property.
+  ///
+  /// If the closure supports optional parameters, then they also feature
+  /// a [JsGetName.DEFAULT_VALUES_PROPERTY] property.
+  ///
+  /// The catch-all property is a method that takes all arguments (including
+  /// all optional positional or named arguments). If the function accepts
+  /// optional arguments, then the default-values property stores (potentially
+  /// wrapped in a function) the default values for the optional arguments. If
+  /// the function accepts optional positional arguments, then the value is a
+  /// JavaScript array with the default values. Otherwise, when the function
+  /// accepts optional named arguments, it is a JavaScript object.
+  ///
+  /// The default-values property may either contain the value directly, or
+  /// it can be a function that returns the default-values when invoked.
+  ///
+  /// If the function is an anonymous closure, then the catch-all property
+  /// only contains a string pointing to the property that should be used
+  /// instead. For example, if the catch-all property contains the string
+  /// "call$4", then the object's "call$4" property should be used as if it was
+  /// the value of the catch-all property.
+  static applyFunction(Function function, List positionalArguments,
+      Map<String, dynamic> namedArguments) {
+    // Fast shortcut for the common case.
+    if (JS('bool', '# instanceof Array', positionalArguments) &&
+        (namedArguments == null || namedArguments.isEmpty)) {
+      // Let the compiler know that we did a type-test.
+      List arguments = (JS('JSArray', '#', positionalArguments));
+      int argumentCount = arguments.length;
+      if (argumentCount == 0) {
+        String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX0);
+        if (JS('bool', '!!#[#]', function, selectorName)) {
+          return JS('', '#[#]()', function, selectorName);
+        }
+      } else if (argumentCount == 1) {
+        String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX1);
+        if (JS('bool', '!!#[#]', function, selectorName)) {
+          return JS('', '#[#](#[0])', function, selectorName, arguments);
+        }
+      } else if (argumentCount == 2) {
+        String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX2);
+        if (JS('bool', '!!#[#]', function, selectorName)) {
+          return JS('', '#[#](#[0],#[1])', function, selectorName, arguments,
+              arguments);
+        }
+      } else if (argumentCount == 3) {
+        String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX3);
+        if (JS('bool', '!!#[#]', function, selectorName)) {
+          return JS('', '#[#](#[0],#[1],#[2])', function, selectorName,
+              arguments, arguments, arguments);
+        }
+      } else if (argumentCount == 4) {
+        String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX4);
+        if (JS('bool', '!!#[#]', function, selectorName)) {
+          return JS('', '#[#](#[0],#[1],#[2],#[3])', function, selectorName,
+              arguments, arguments, arguments, arguments);
+        }
+      } else if (argumentCount == 5) {
+        String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX5);
+        if (JS('bool', '!!#[#]', function, selectorName)) {
+          return JS(
+              '',
+              '#[#](#[0],#[1],#[2],#[3],#[4])',
+              function,
+              selectorName,
+              arguments,
+              arguments,
+              arguments,
+              arguments,
+              arguments);
+        }
+      }
+      String selectorName =
+          '${JS_GET_NAME(JsGetName.CALL_PREFIX)}\$$argumentCount';
+      var jsStub = JS('var', r'#[#]', function, selectorName);
+      if (jsStub != null) {
+        return JS('var', '#.apply(#, #)', jsStub, function, arguments);
+      }
+    }
+
+    return _genericApplyFunction2(
+        function, positionalArguments, namedArguments);
+  }
+
+  static _genericApplyFunction2(Function function, List positionalArguments,
+      Map<String, dynamic> namedArguments) {
+    List arguments;
+    if (positionalArguments != null) {
+      if (JS('bool', '# instanceof Array', positionalArguments)) {
+        arguments = JS('JSArray', '#', positionalArguments);
+      } else {
+        arguments = new List.from(positionalArguments);
+      }
+    } else {
+      arguments = [];
+    }
+
+    int argumentCount = arguments.length;
+
+    int requiredParameterCount = JS('int', r'#[#]', function,
+        JS_GET_NAME(JsGetName.REQUIRED_PARAMETER_PROPERTY));
+
+    if (argumentCount < requiredParameterCount) {
+      return functionNoSuchMethod(function, arguments, namedArguments);
+    }
+
+    var defaultValuesClosure = JS('var', r'#[#]', function,
+        JS_GET_NAME(JsGetName.DEFAULT_VALUES_PROPERTY));
+
+    bool acceptsOptionalArguments = defaultValuesClosure != null;
+
+    // Default values are stored inside a JavaScript closure to avoid
+    // accessing them too early.
+    var defaultValues =
+        acceptsOptionalArguments ? JS('', '#()', defaultValuesClosure) : null;
+
+    var interceptor = getInterceptor(function);
+    var jsFunction =
+        JS('', '#[#]', interceptor, JS_GET_NAME(JsGetName.CALL_CATCH_ALL));
+    if (jsFunction is String) {
+      // Anonymous closures redirect to the catch-all property instead of
+      // storing the catch-all method directly in the catch-all property.
+      jsFunction = JS('', '#[#]', interceptor, jsFunction);
+    }
+
+    if (!acceptsOptionalArguments) {
+      if (namedArguments != null && namedArguments.isNotEmpty) {
+        // Tried to invoke a function that takes a fixed number of arguments
+        // with named (optional) arguments.
+        return functionNoSuchMethod(function, arguments, namedArguments);
+      }
+      if (argumentCount == requiredParameterCount) {
+        return JS('var', r'#.apply(#, #)', jsFunction, function, arguments);
+      }
+      return functionNoSuchMethod(function, arguments, namedArguments);
+    }
+
+    bool acceptsPositionalArguments =
+        JS('bool', '# instanceof Array', defaultValues);
+
+    if (acceptsPositionalArguments) {
+      if (namedArguments != null && namedArguments.isNotEmpty) {
+        // Tried to invoke a function that takes optional positional arguments
+        // with named arguments.
+        return functionNoSuchMethod(function, arguments, namedArguments);
+      }
+
+      int defaultsLength = JS('int', '#.length', defaultValues);
+      int maxArguments = requiredParameterCount + defaultsLength;
+      if (argumentCount > maxArguments) {
+        // The function expects fewer arguments.
+        return functionNoSuchMethod(function, arguments, null);
+      }
+      List missingDefaults = JS('JSArray', '#.slice(#)', defaultValues,
+          argumentCount - requiredParameterCount);
+      arguments.addAll(missingDefaults);
+      return JS('var', '#.apply(#, #)', jsFunction, function, arguments);
+    } else {
+      // Handle named arguments.
+
+      if (argumentCount > requiredParameterCount) {
+        // Tried to invoke a function that takes named parameters with
+        // too many positional arguments.
+        return functionNoSuchMethod(function, arguments, namedArguments);
+      }
+
+      List keys = JS('JSArray', r'Object.keys(#)', defaultValues);
+      if (namedArguments == null) {
+        for (String key in keys) {
+          arguments.add(JS('var', '#[#]', defaultValues, key));
+        }
+      } else {
+        int used = 0;
+        for (String key in keys) {
+          if (namedArguments.containsKey(key)) {
+            used++;
+            arguments.add(namedArguments[key]);
+          } else {
+            arguments.add(JS('var', r'#[#]', defaultValues, key));
+          }
+        }
+        if (used != namedArguments.length) {
+          return functionNoSuchMethod(function, arguments, namedArguments);
+        }
+      }
+      return JS('var', r'#.apply(#, #)', jsFunction, function, arguments);
+    }
+  }
+
+  static StackTrace extractStackTrace(Error error) {
+    return getTraceFromException(JS('', r'#.$thrownJsError', error));
+  }
+}
+
+/// Helper class for allocating and using JS object literals as caches.
+class JsCache {
+  /// Returns a JavaScript object suitable for use as a cache.
+  static allocate() {
+    var result = JS('=Object', 'Object.create(null)');
+    // Deleting a property makes V8 assume that it shouldn't create a hidden
+    // class for [result] and map transitions. Although these map transitions
+    // pay off if there are many cache hits for the same keys, it becomes
+    // really slow when there aren't many repeated hits.
+    JS('void', '#.x=0', result);
+    JS('void', 'delete #.x', result);
+    return result;
+  }
+
+  static fetch(cache, String key) {
+    return JS('', '#[#]', cache, key);
+  }
+
+  static void update(cache, String key, value) {
+    JS('void', '#[#] = #', cache, key, value);
+  }
+}
+
+/// Called by generated code to throw an illegal-argument exception,
+/// for example, if a non-integer index is given to an optimized
+/// indexed access.
+@pragma('dart2js:noInline')
+iae(argument) {
+  throw argumentErrorValue(argument);
+}
+
+/// Called by generated code to throw an index-out-of-range exception, for
+/// example, if a bounds check fails in an optimized indexed access.  This may
+/// also be called when the index is not an integer, in which case it throws an
+/// illegal-argument exception instead, like [iae], or when the receiver is
+/// null.
+@pragma('dart2js:noInline')
+ioore(receiver, index) {
+  if (receiver == null) receiver.length; // Force a NoSuchMethodError.
+  throw diagnoseIndexError(receiver, index);
+}
+
+/// Diagnoses an indexing error. Returns the ArgumentError or RangeError that
+/// describes the problem.
+@pragma('dart2js:noInline')
+Error diagnoseIndexError(indexable, index) {
+  if (index is! int) return new ArgumentError.value(index, 'index');
+  int length = indexable.length;
+  // The following returns the same error that would be thrown by calling
+  // [RangeError.checkValidIndex] with no optional parameters provided.
+  if (index < 0 || index >= length) {
+    return new RangeError.index(index, indexable, 'index', null, length);
+  }
+  // The above should always match, but if it does not, use the following.
+  return new RangeError.value(index, 'index');
+}
+
+/// Diagnoses a range error. Returns the ArgumentError or RangeError that
+/// describes the problem.
+@pragma('dart2js:noInline')
+Error diagnoseRangeError(start, end, length) {
+  if (start is! int) {
+    return new ArgumentError.value(start, 'start');
+  }
+  if (start < 0 || start > length) {
+    return new RangeError.range(start, 0, length, 'start');
+  }
+  if (end != null) {
+    if (end is! int) {
+      return new ArgumentError.value(end, 'end');
+    }
+    if (end < start || end > length) {
+      return new RangeError.range(end, start, length, 'end');
+    }
+  }
+  // The above should always match, but if it does not, use the following.
+  return new ArgumentError.value(end, 'end');
+}
+
+stringLastIndexOfUnchecked(receiver, element, start) =>
+    JS('int', r'#.lastIndexOf(#, #)', receiver, element, start);
+
+/// 'factory' for constructing ArgumentError.value to keep the call sites small.
+@pragma('dart2js:noInline')
+ArgumentError argumentErrorValue(object) {
+  return new ArgumentError.value(object);
+}
+
+checkNull(object) {
+  if (object == null) throw argumentErrorValue(object);
+  return object;
+}
+
+@pragma('dart2js:noInline')
+num checkNum(value) {
+  if (value is! num) throw argumentErrorValue(value);
+  return value;
+}
+
+int checkInt(value) {
+  if (value is! int) throw argumentErrorValue(value);
+  return value;
+}
+
+bool checkBool(value) {
+  if (value is! bool) throw argumentErrorValue(value);
+  return value;
+}
+
+String checkString(value) {
+  if (value is! String) throw argumentErrorValue(value);
+  return value;
+}
+
+/// Wrap the given Dart object and record a stack trace.
+///
+/// The code in [unwrapException] deals with getting the original Dart
+/// object out of the wrapper again.
+@pragma('dart2js:noInline')
+wrapException(ex) {
+  if (ex == null) ex = new NullThrownError();
+  var wrapper = JS('', 'new Error()');
+  // [unwrapException] looks for the property 'dartException'.
+  JS('void', '#.dartException = #', wrapper, ex);
+
+  if (JS('bool', '"defineProperty" in Object')) {
+    // Define a JavaScript getter for 'message'. This is to work around V8 bug
+    // (https://code.google.com/p/v8/issues/detail?id=2519).  The default
+    // toString on Error returns the value of 'message' if 'name' is
+    // empty. Setting toString directly doesn't work, see the bug.
+    JS('void', 'Object.defineProperty(#, "message", { get: # })', wrapper,
+        DART_CLOSURE_TO_JS(toStringWrapper));
+    JS('void', '#.name = ""', wrapper);
+  } else {
+    // In the unlikely event the browser doesn't support Object.defineProperty,
+    // hope that it just calls toString.
+    JS('void', '#.toString = #', wrapper, DART_CLOSURE_TO_JS(toStringWrapper));
+  }
+
+  return wrapper;
+}
+
+/// Do not call directly.
+toStringWrapper() {
+  // This method gets installed as toString on a JavaScript object. Due to the
+  // weird scope rules of JavaScript, JS 'this' will refer to that object.
+  return JS('', r'this.dartException').toString();
+}
+
+/// This wraps the exception and does the throw.  It is possible to call this in
+/// a JS expression context, where the throw statement is not allowed.  Helpers
+/// are never inlined, so we don't risk inlining the throw statement into an
+/// expression context.
+throwExpression(ex) {
+  JS('void', 'throw #', wrapException(ex));
+}
+
+throwRuntimeError(message) {
+  throw new RuntimeError(message);
+}
+
+throwUnsupportedError(message) {
+  throw new UnsupportedError(message);
+}
+
+throwAbstractClassInstantiationError(className) {
+  throw new AbstractClassInstantiationError(className);
+}
+
+// This is used in open coded for-in loops on arrays.
+//
+//     checkConcurrentModificationError(a.length == startLength, a)
+//
+// is replaced in codegen by:
+//
+//     a.length == startLength || throwConcurrentModificationError(a)
+//
+// TODO(sra): We would like to annotate this as @pragma('dart2js:noSideEffects') so that loops
+// with no other effects can recognize that the array length does not
+// change. However, in the usual case where the loop does have other effects,
+// that causes the length in the loop condition to be phi(startLength,a.length),
+// which causes confusion in range analysis and the insertion of a bounds check.
+@pragma('dart2js:noInline')
+checkConcurrentModificationError(sameLength, collection) {
+  if (true != sameLength) {
+    throwConcurrentModificationError(collection);
+  }
+}
+
+@pragma('dart2js:noInline')
+throwConcurrentModificationError(collection) {
+  throw new ConcurrentModificationError(collection);
+}
+
+/// Helper class for building patterns recognizing native type errors.
+class TypeErrorDecoder {
+  // Field names are private to help tree-shaking.
+
+  /// A regular expression which matches is matched against an error message.
+  final String _pattern;
+
+  /// The group index of "arguments" in [_pattern], or -1 if _pattern has no
+  /// match for "arguments".
+  final int _arguments;
+
+  /// The group index of "argumentsExpr" in [_pattern], or -1 if _pattern has
+  /// no match for "argumentsExpr".
+  final int _argumentsExpr;
+
+  /// The group index of "expr" in [_pattern], or -1 if _pattern has no match
+  /// for "expr".
+  final int _expr;
+
+  /// The group index of "method" in [_pattern], or -1 if _pattern has no match
+  /// for "method".
+  final int _method;
+
+  /// The group index of "receiver" in [_pattern], or -1 if _pattern has no
+  /// match for "receiver".
+  final int _receiver;
+
+  /// Pattern used to recognize a NoSuchMethodError error (and
+  /// possibly extract the method name).
+  static final TypeErrorDecoder noSuchMethodPattern =
+      extractPattern(provokeCallErrorOn(buildJavaScriptObject()));
+
+  /// Pattern used to recognize an "object not a closure" error (and
+  /// possibly extract the method name).
+  static final TypeErrorDecoder notClosurePattern =
+      extractPattern(provokeCallErrorOn(buildJavaScriptObjectWithNonClosure()));
+
+  /// Pattern used to recognize a NoSuchMethodError on JavaScript null
+  /// call.
+  static final TypeErrorDecoder nullCallPattern =
+      extractPattern(provokeCallErrorOn(JS('', 'null')));
+
+  /// Pattern used to recognize a NoSuchMethodError on JavaScript literal null
+  /// call.
+  static final TypeErrorDecoder nullLiteralCallPattern =
+      extractPattern(provokeCallErrorOnNull());
+
+  /// Pattern used to recognize a NoSuchMethodError on JavaScript
+  /// undefined call.
+  static final TypeErrorDecoder undefinedCallPattern =
+      extractPattern(provokeCallErrorOn(JS('', 'void 0')));
+
+  /// Pattern used to recognize a NoSuchMethodError on JavaScript literal
+  /// undefined call.
+  static final TypeErrorDecoder undefinedLiteralCallPattern =
+      extractPattern(provokeCallErrorOnUndefined());
+
+  /// Pattern used to recognize a NoSuchMethodError on JavaScript null
+  /// property access.
+  static final TypeErrorDecoder nullPropertyPattern =
+      extractPattern(provokePropertyErrorOn(JS('', 'null')));
+
+  /// Pattern used to recognize a NoSuchMethodError on JavaScript literal null
+  /// property access.
+  static final TypeErrorDecoder nullLiteralPropertyPattern =
+      extractPattern(provokePropertyErrorOnNull());
+
+  /// Pattern used to recognize a NoSuchMethodError on JavaScript
+  /// undefined property access.
+  static final TypeErrorDecoder undefinedPropertyPattern =
+      extractPattern(provokePropertyErrorOn(JS('', 'void 0')));
+
+  /// Pattern used to recognize a NoSuchMethodError on JavaScript literal
+  /// undefined property access.
+  static final TypeErrorDecoder undefinedLiteralPropertyPattern =
+      extractPattern(provokePropertyErrorOnUndefined());
+
+  TypeErrorDecoder(this._arguments, this._argumentsExpr, this._expr,
+      this._method, this._receiver, this._pattern);
+
+  /// Returns a JavaScript object literal (map) with at most the
+  /// following keys:
+  ///
+  /// * arguments: The arguments as formatted by the JavaScript
+  ///   engine. No browsers are known to provide this information.
+  ///
+  /// * argumentsExpr: The syntax of the arguments (JavaScript source
+  ///   code). No browsers are known to provide this information.
+  ///
+  /// * expr: The syntax of the receiver expression (JavaScript source
+  ///   code). Firefox provides this information, for example: "$expr$.$method$
+  ///   is not a function".
+  ///
+  /// * method: The name of the called method (mangled name). At least Firefox
+  ///   and Chrome/V8 provides this information, for example, "Object [object
+  ///   Object] has no method '$method$'".
+  ///
+  /// * receiver: The string representation of the receiver. Chrome/V8
+  ///   used to provide this information (by calling user-defined
+  ///   JavaScript toString on receiver), but it has degenerated into
+  ///   "[object Object]" in recent versions.
+  matchTypeError(message) {
+    var match = JS(
+        'JSExtendableArray|Null', 'new RegExp(#).exec(#)', _pattern, message);
+    if (match == null) return null;
+    var result = JS('', 'Object.create(null)');
+    if (_arguments != -1) {
+      JS('', '#.arguments = #[# + 1]', result, match, _arguments);
+    }
+    if (_argumentsExpr != -1) {
+      JS('', '#.argumentsExpr = #[# + 1]', result, match, _argumentsExpr);
+    }
+    if (_expr != -1) {
+      JS('', '#.expr = #[# + 1]', result, match, _expr);
+    }
+    if (_method != -1) {
+      JS('', '#.method = #[# + 1]', result, match, _method);
+    }
+    if (_receiver != -1) {
+      JS('', '#.receiver = #[# + 1]', result, match, _receiver);
+    }
+
+    return result;
+  }
+
+  /// Builds a JavaScript Object with a toString method saying
+  /// r"$receiver$".
+  static buildJavaScriptObject() {
+    return JS('', r'{ toString: function() { return "$receiver$"; } }');
+  }
+
+  /// Builds a JavaScript Object with a toString method saying
+  /// r"$receiver$". The property "$method" is defined, but is not a function.
+  static buildJavaScriptObjectWithNonClosure() {
+    return JS(
+        '',
+        r'{ $method$: null, '
+            r'toString: function() { return "$receiver$"; } }');
+  }
+
+  /// Extract a pattern from a JavaScript TypeError message.
+  ///
+  /// The patterns are extracted by forcing TypeErrors on known
+  /// objects thus forcing known strings into the error message. The
+  /// known strings are then replaced with wildcards which in theory
+  /// makes it possible to recognize the desired information even if
+  /// the error messages are reworded or translated.
+  static extractPattern(String message) {
+    // Some JavaScript implementations (V8 at least) include a
+    // representation of the receiver in the error message, however,
+    // this representation is not always [: receiver.toString() :],
+    // sometimes it is [: Object.prototype.toString(receiver) :], and
+    // sometimes it is an implementation specific method (but that
+    // doesn't seem to happen for object literals). So sometimes we
+    // get the text "[object Object]". The shortest way to get that
+    // string is using "String({})".
+    // See: http://code.google.com/p/v8/issues/detail?id=2519.
+    message = JS('String', r"#.replace(String({}), '$receiver$')", message);
+
+    // Since we want to create a new regular expression from an unknown string,
+    // we must escape all regular expression syntax.
+    message = quoteStringForRegExp(message);
+
+    // Look for the special pattern \$camelCase\$ (all the $ symbols
+    // have been escaped already), as we will soon be inserting
+    // regular expression syntax that we want interpreted by RegExp.
+    List<String> match =
+        JS('JSExtendableArray|Null', r'#.match(/\\\$[a-zA-Z]+\\\$/g)', message);
+    if (match == null) match = [];
+
+    // Find the positions within the substring matches of the error message
+    // components.  This will help us extract information later, such as the
+    // method name.
+    int arguments = JS('int', '#.indexOf(#)', match, r'\$arguments\$');
+    int argumentsExpr = JS('int', '#.indexOf(#)', match, r'\$argumentsExpr\$');
+    int expr = JS('int', '#.indexOf(#)', match, r'\$expr\$');
+    int method = JS('int', '#.indexOf(#)', match, r'\$method\$');
+    int receiver = JS('int', '#.indexOf(#)', match, r'\$receiver\$');
+
+    // Replace the patterns with a regular expression wildcard.
+    // Note: in a perfect world, one would use "(.*)", but not in
+    // JavaScript, "." does not match newlines.
+    String pattern = JS(
+        'String',
+        r"#.replace(new RegExp('\\\\\\$arguments\\\\\\$', 'g'), "
+            r"'((?:x|[^x])*)')"
+            r".replace(new RegExp('\\\\\\$argumentsExpr\\\\\\$', 'g'),  "
+            r"'((?:x|[^x])*)')"
+            r".replace(new RegExp('\\\\\\$expr\\\\\\$', 'g'),  '((?:x|[^x])*)')"
+            r".replace(new RegExp('\\\\\\$method\\\\\\$', 'g'),  '((?:x|[^x])*)')"
+            r".replace(new RegExp('\\\\\\$receiver\\\\\\$', 'g'),  "
+            r"'((?:x|[^x])*)')",
+        message);
+
+    return new TypeErrorDecoder(
+        arguments, argumentsExpr, expr, method, receiver, pattern);
+  }
+
+  /// Provokes a TypeError and returns its message.
+  ///
+  /// The error is provoked so all known variable content can be recognized and
+  /// a pattern can be inferred.
+  static String provokeCallErrorOn(expression) {
+    // This function is carefully created to maximize the possibility
+    // of decoding the TypeError message and turning it into a general
+    // pattern.
+    //
+    // The idea is to inject something known into something unknown.  The
+    // unknown entity is the error message that the browser provides with a
+    // TypeError.  It is a human readable message, possibly localized in a
+    // language no dart2js engineer understand.  We assume that $name$ would
+    // never naturally occur in a human readable error message, yet it is easy
+    // to decode.
+    //
+    // For example, evaluate this in V8 version 3.13.7.6:
+    //
+    // var $expr$ = null; $expr$.$method$()
+    //
+    // The VM throws an instance of TypeError whose message property contains
+    // "Cannot call method '$method$' of null".  We can then reasonably assume
+    // that if the string contains $method$, that's where the method name will
+    // be in general.  Call this automatically reverse engineering the error
+    // format string in V8.
+    //
+    // So the error message from V8 is turned into this regular expression:
+    //
+    // "Cannot call method '(.*)' of null"
+    //
+    // Similarly, if we evaluate:
+    //
+    // var $expr$ = {toString: function() { return '$receiver$'; }};
+    // $expr$.$method$()
+    //
+    // We get this message: "Object $receiver$ has no method '$method$'"
+    //
+    // Which is turned into this regular expression:
+    //
+    // "Object (.*) has no method '(.*)'"
+    //
+    // Firefox/jsshell is slightly different, it tries to include the source
+    // code that caused the exception, so we get this message: "$expr$.$method$
+    // is not a function" which is turned into this regular expression:
+    //
+    // "(.*)\\.(.*) is not a function"
+
+    var function = JS('', r"""function($expr$) {
+  var $argumentsExpr$ = '$arguments$';
+  try {
+    $expr$.$method$($argumentsExpr$);
+  } catch (e) {
+    return e.message;
+  }
+}""");
+    return JS('String', '(#)(#)', function, expression);
+  }
+
+  /// Similar to [provokeCallErrorOn], but provokes an error directly on
+  /// literal "null" expression.
+  static String provokeCallErrorOnNull() {
+    // See [provokeCallErrorOn] for a detailed explanation.
+    var function = JS('', r"""function() {
+  var $argumentsExpr$ = '$arguments$';
+  try {
+    null.$method$($argumentsExpr$);
+  } catch (e) {
+    return e.message;
+  }
+}""");
+    return JS('String', '(#)()', function);
+  }
+
+  /// Similar to [provokeCallErrorOnNull], but provokes an error directly on
+  /// (void 0), that is, "undefined".
+  static String provokeCallErrorOnUndefined() {
+    // See [provokeCallErrorOn] for a detailed explanation.
+    var function = JS('', r"""function() {
+  var $argumentsExpr$ = '$arguments$';
+  try {
+    (void 0).$method$($argumentsExpr$);
+  } catch (e) {
+    return e.message;
+  }
+}""");
+    return JS('String', '(#)()', function);
+  }
+
+  /// Similar to [provokeCallErrorOn], but provokes a property access
+  /// error.
+  static String provokePropertyErrorOn(expression) {
+    // See [provokeCallErrorOn] for a detailed explanation.
+    var function = JS('', r"""function($expr$) {
+  try {
+    $expr$.$method$;
+  } catch (e) {
+    return e.message;
+  }
+}""");
+    return JS('String', '(#)(#)', function, expression);
+  }
+
+  /// Similar to [provokePropertyErrorOn], but provokes an property access
+  /// error directly on literal "null" expression.
+  static String provokePropertyErrorOnNull() {
+    // See [provokeCallErrorOn] for a detailed explanation.
+    var function = JS('', r"""function() {
+  try {
+    null.$method$;
+  } catch (e) {
+    return e.message;
+  }
+}""");
+    return JS('String', '(#)()', function);
+  }
+
+  /// Similar to [provokePropertyErrorOnNull], but provokes an property access
+  /// error directly on (void 0), that is, "undefined".
+  static String provokePropertyErrorOnUndefined() {
+    // See [provokeCallErrorOn] for a detailed explanation.
+    var function = JS('', r"""function() {
+  try {
+    (void 0).$method$;
+  } catch (e) {
+    return e.message;
+  }
+}""");
+    return JS('String', '(#)()', function);
+  }
+}
+
+class NullError extends Error implements NoSuchMethodError {
+  final String _message;
+  final String _method;
+
+  NullError(this._message, match)
+      : _method = match == null ? null : JS('', '#.method', match);
+
+  String toString() {
+    if (_method == null) return 'NoSuchMethodError: $_message';
+    return "NoSuchMethodError: method not found: '$_method' on null";
+  }
+}
+
+class JsNoSuchMethodError extends Error implements NoSuchMethodError {
+  final String _message;
+  final String _method;
+  final String _receiver;
+
+  JsNoSuchMethodError(this._message, match)
+      : _method = match == null ? null : JS('String|Null', '#.method', match),
+        _receiver =
+            match == null ? null : JS('String|Null', '#.receiver', match);
+
+  String toString() {
+    if (_method == null) return 'NoSuchMethodError: $_message';
+    if (_receiver == null) {
+      return "NoSuchMethodError: method not found: '$_method' ($_message)";
+    }
+    return "NoSuchMethodError: "
+        "method not found: '$_method' on '$_receiver' ($_message)";
+  }
+}
+
+class UnknownJsTypeError extends Error {
+  final String _message;
+
+  UnknownJsTypeError(this._message);
+
+  String toString() => _message.isEmpty ? 'Error' : 'Error: $_message';
+}
+
+/// A wrapper around an exception, much like the one created by [wrapException]
+/// but with a pre-given stack-trace.
+class ExceptionAndStackTrace {
+  dynamic dartException;
+  StackTrace stackTrace;
+
+  ExceptionAndStackTrace(this.dartException, this.stackTrace);
+}
+
+/// Called from catch blocks in generated code to extract the Dart
+/// exception from the thrown value. The thrown value may have been
+/// created by [wrapException] or it may be a 'native' JS exception.
+///
+/// Some native exceptions are mapped to new Dart instances, others are
+/// returned unmodified.
+unwrapException(ex) {
+  /// If error implements Error, save [ex] in [error.$thrownJsError].
+  /// Otherwise, do nothing. Later, the stack trace can then be extracted from
+  /// [ex].
+  saveStackTrace(error) {
+    if (error is Error) {
+      var thrownStackTrace = JS('', r'#.$thrownJsError', error);
+      if (thrownStackTrace == null) {
+        JS('void', r'#.$thrownJsError = #', error, ex);
+      }
+    }
+    return error;
+  }
+
+  // Note that we are checking if the object has the property. If it
+  // has, it could be set to null if the thrown value is null.
+  if (ex == null) return null;
+  if (ex is ExceptionAndStackTrace) {
+    return saveStackTrace(ex.dartException);
+  }
+  if (JS('bool', 'typeof # !== "object"', ex)) return ex;
+
+  if (JS('bool', r'"dartException" in #', ex)) {
+    return saveStackTrace(JS('', r'#.dartException', ex));
+  } else if (!JS('bool', r'"message" in #', ex)) {
+    return ex;
+  }
+
+  // Grab hold of the exception message. This field is available on
+  // all supported browsers.
+  var message = JS('var', r'#.message', ex);
+
+  // Internet Explorer has an error number.  This is the most reliable way to
+  // detect specific errors, so check for this first.
+  if (JS('bool', '"number" in #', ex) &&
+      JS('bool', 'typeof #.number == "number"', ex)) {
+    int number = JS('int', '#.number', ex);
+
+    // From http://msdn.microsoft.com/en-us/library/ie/hc53e755(v=vs.94).aspx
+    // "number" is a 32-bit word. The error code is the low 16 bits, and the
+    // facility code is the upper 16 bits.
+    var ieErrorCode = number & 0xffff;
+    var ieFacilityNumber = (number >> 16) & 0x1fff;
+
+    // http://msdn.microsoft.com/en-us/library/aa264975(v=vs.60).aspx
+    // http://msdn.microsoft.com/en-us/library/ie/1dk3k160(v=vs.94).aspx
+    if (ieFacilityNumber == 10) {
+      switch (ieErrorCode) {
+        case 438:
+          return saveStackTrace(
+              new JsNoSuchMethodError('$message (Error $ieErrorCode)', null));
+        case 445:
+        case 5007:
+          return saveStackTrace(
+              new NullError('$message (Error $ieErrorCode)', null));
+      }
+    }
+  }
+
+  if (JS('bool', r'# instanceof TypeError', ex)) {
+    var match;
+    // Using JS to give type hints to the compiler to help tree-shaking.
+    // TODO(ahe): That should be unnecessary due to type inference.
+    var nsme = TypeErrorDecoder.noSuchMethodPattern;
+    var notClosure = TypeErrorDecoder.notClosurePattern;
+    var nullCall = TypeErrorDecoder.nullCallPattern;
+    var nullLiteralCall = TypeErrorDecoder.nullLiteralCallPattern;
+    var undefCall = TypeErrorDecoder.undefinedCallPattern;
+    var undefLiteralCall = TypeErrorDecoder.undefinedLiteralCallPattern;
+    var nullProperty = TypeErrorDecoder.nullPropertyPattern;
+    var nullLiteralProperty = TypeErrorDecoder.nullLiteralPropertyPattern;
+    var undefProperty = TypeErrorDecoder.undefinedPropertyPattern;
+    var undefLiteralProperty = TypeErrorDecoder.undefinedLiteralPropertyPattern;
+    if ((match = nsme.matchTypeError(message)) != null) {
+      return saveStackTrace(new JsNoSuchMethodError(message, match));
+    } else if ((match = notClosure.matchTypeError(message)) != null) {
+      // notClosure may match "({c:null}).c()" or "({c:1}).c()", so we
+      // cannot tell if this an attempt to invoke call on null or a
+      // non-function object.
+      // But we do know the method name is "call".
+      JS('', '#.method = "call"', match);
+      return saveStackTrace(new JsNoSuchMethodError(message, match));
+    } else if ((match = nullCall.matchTypeError(message)) != null ||
+        (match = nullLiteralCall.matchTypeError(message)) != null ||
+        (match = undefCall.matchTypeError(message)) != null ||
+        (match = undefLiteralCall.matchTypeError(message)) != null ||
+        (match = nullProperty.matchTypeError(message)) != null ||
+        (match = nullLiteralCall.matchTypeError(message)) != null ||
+        (match = undefProperty.matchTypeError(message)) != null ||
+        (match = undefLiteralProperty.matchTypeError(message)) != null) {
+      return saveStackTrace(new NullError(message, match));
+    }
+
+    // If we cannot determine what kind of error this is, we fall back
+    // to reporting this as a generic error. It's probably better than
+    // nothing.
+    return saveStackTrace(
+        new UnknownJsTypeError(message is String ? message : ''));
+  }
+
+  if (JS('bool', r'# instanceof RangeError', ex)) {
+    if (message is String && contains(message, 'call stack')) {
+      return new StackOverflowError();
+    }
+
+    // In general, a RangeError is thrown when trying to pass a number as an
+    // argument to a function that does not allow a range that includes that
+    // number. Translate to a Dart ArgumentError with the same message.
+    // TODO(sra): Translate to RangeError.
+    message = tryStringifyException(ex);
+    if (message is String) {
+      message = JS('String', r'#.replace(/^RangeError:\s*/, "")', message);
+    }
+    return saveStackTrace(new ArgumentError(message));
+  }
+
+  // Check for the Firefox specific stack overflow signal.
+  if (JS(
+      'bool',
+      r'typeof InternalError == "function" && # instanceof InternalError',
+      ex)) {
+    if (message is String && message == 'too much recursion') {
+      return new StackOverflowError();
+    }
+  }
+
+  // Just return the exception. We should not wrap it because in case
+  // the exception comes from the DOM, it is a JavaScript
+  // object backed by a native Dart class.
+  return ex;
+}
+
+String tryStringifyException(ex) {
+  // Since this function is called from [unwrapException] which is called from
+  // code injected into a catch-clause, use JavaScript try-catch to avoid a
+  // potential loop if stringifying crashes.
+  return JS(
+      'String|Null',
+      r'''
+    (function(ex) {
+      try {
+        return String(ex);
+      } catch (e) {}
+      return null;
+    })(#)
+    ''',
+      ex);
+}
+
+/// Called by generated code to fetch the stack trace from an
+/// exception. Should never return null.
+StackTrace getTraceFromException(exception) {
+  if (exception is ExceptionAndStackTrace) {
+    return exception.stackTrace;
+  }
+  if (exception == null) return new _StackTrace(exception);
+  _StackTrace trace = JS('_StackTrace|Null', r'#.$cachedTrace', exception);
+  if (trace != null) return trace;
+  trace = new _StackTrace(exception);
+  return JS('_StackTrace', r'#.$cachedTrace = #', exception, trace);
+}
+
+class _StackTrace implements StackTrace {
+  var _exception;
+  String _trace;
+  _StackTrace(this._exception);
+
+  String toString() {
+    if (_trace != null) return JS('String', '#', _trace);
+
+    String trace;
+    if (JS('bool', '# !== null', _exception) &&
+        JS('bool', 'typeof # === "object"', _exception)) {
+      trace = JS('String|Null', r'#.stack', _exception);
+    }
+    return _trace = (trace == null) ? '' : trace;
+  }
+}
+
+int objectHashCode(var object) {
+  if (object == null || JS('bool', "typeof # != 'object'", object)) {
+    return object.hashCode;
+  } else {
+    return Primitives.objectHashCode(object);
+  }
+}
+
+/// Called by generated code to build a map literal. [keyValuePairs] is
+/// a list of key, value, key, value, ..., etc.
+fillLiteralMap(keyValuePairs, Map result) {
+  // TODO(johnniwinther): Use JSArray to optimize this code instead of calling
+  // [getLength] and [getIndex].
+  int index = 0;
+  int length = getLength(keyValuePairs);
+  while (index < length) {
+    var key = getIndex(keyValuePairs, index++);
+    var value = getIndex(keyValuePairs, index++);
+    result[key] = value;
+  }
+  return result;
+}
+
+/// Called by generated code to build a set literal.
+fillLiteralSet(values, Set result) {
+  // TODO(johnniwinther): Use JSArray to optimize this code instead of calling
+  // [getLength] and [getIndex].
+  int length = getLength(values);
+  for (int index = 0; index < length; index++) {
+    result.add(getIndex(values, index));
+  }
+  return result;
+}
+
+invokeClosure(Function closure, int numberOfArguments, var arg1, var arg2,
+    var arg3, var arg4) {
+  switch (numberOfArguments) {
+    case 0:
+      return closure();
+    case 1:
+      return closure(arg1);
+    case 2:
+      return closure(arg1, arg2);
+    case 3:
+      return closure(arg1, arg2, arg3);
+    case 4:
+      return closure(arg1, arg2, arg3, arg4);
+  }
+  throw new Exception('Unsupported number of arguments for wrapped closure');
+}
+
+/// Called by generated code to convert a Dart closure to a JS
+/// closure when the Dart closure is passed to the DOM.
+convertDartClosureToJS(closure, int arity) {
+  if (closure == null) return null;
+  var function = JS('var', r'#.$identity', closure);
+  if (JS('bool', r'!!#', function)) return function;
+
+  function = JS(
+      'var',
+      r'''
+        (function(closure, arity, invoke) {
+          return function(a1, a2, a3, a4) {
+            return invoke(closure, arity, a1, a2, a3, a4);
+          };
+        })(#,#,#)''',
+      closure,
+      arity,
+      DART_CLOSURE_TO_JS(invokeClosure));
+
+  JS('void', r'#.$identity = #', closure, function);
+  return function;
+}
+
+/// Superclass for Dart closures.
+///
+/// All static, tear-off, function declaration and function expression closures
+/// extend this class, but classes that implement Function via a `call` method
+/// do not.
+abstract class Closure implements Function {
+  // TODO(ahe): These constants must be in sync with
+  // reflection_data_parser.dart.
+  static const FUNCTION_INDEX = 0;
+  static const NAME_INDEX = 1;
+  static const CALL_NAME_INDEX = 2;
+  static const REQUIRED_PARAMETER_INDEX = 3;
+  static const OPTIONAL_PARAMETER_INDEX = 4;
+  static const DEFAULT_ARGUMENTS_INDEX = 5;
+
+  /// Global counter to prevent reusing function code objects.
+  ///
+  /// V8 will share the underlying function code objects when the same string is
+  /// passed to "new Function".  Shared function code objects can lead to
+  /// sub-optimal performance due to polymorphism, and can be prevented by
+  /// ensuring the strings are different, for example, by generating a local
+  /// variable with a name dependent on [functionCounter].
+  static int functionCounter = 0;
+
+  Closure();
+
+  /// Creates a new closure class for use by implicit getters associated with a
+  /// method.
+  ///
+  /// In other words, creates a tear-off closure.
+  ///
+  /// Called from [closureFromTearOff] as well as from reflection when tearing
+  /// of a method via `getField`.
+  ///
+  /// This method assumes that [functions] was created by the JavaScript
+  /// function `addStubs` in `reflection_data_parser.dart`. That is, a list of
+  /// JavaScript function objects with properties `$stubName` and `$callName`.
+  ///
+  /// Further assumes that [reflectionInfo] is the end of the array created by
+  /// [dart2js.js_emitter.ContainerBuilder.addMemberMethod] starting with
+  /// required parameter count or, in case of the new emitter, the runtime
+  /// representation of the function's type.
+  ///
+  /// Caution: this function may be called when building constants.
+  /// TODO(ahe): Don't call this function when building constants.
+  static fromTearOff(
+    receiver,
+    List functions,
+    int applyTrampolineIndex,
+    var reflectionInfo,
+    bool isStatic,
+    bool isIntercepted,
+    String propertyName,
+  ) {
+    JS_EFFECT(() {
+      // The functions are called here to model the calls from JS forms below.
+      // The types in the JS forms in the arguments are propagated in type
+      // inference.
+      var aBoundClosure = JS('BoundClosure', '0');
+      var aString = JS('String', '0');
+      BoundClosure.receiverOf(aBoundClosure);
+      BoundClosure.selfOf(aBoundClosure);
+      BoundClosure.evalRecipeIntercepted(aBoundClosure, aString);
+      BoundClosure.evalRecipe(aBoundClosure, aString);
+      getType(JS('int', '0'));
+    });
+    // TODO(ahe): All the place below using \$ should be rewritten to go
+    // through the namer.
+    var function = JS('', '#[#]', functions, 0);
+    String name = JS('String|Null', '#.\$stubName', function);
+    String callName = JS('String|Null', '#[#]', function,
+        JS_GET_NAME(JsGetName.CALL_NAME_PROPERTY));
+
+    // This variable holds either an index into the types-table, or a function
+    // that can compute a function-rti. (The latter is necessary if the type
+    // is dependent on generic arguments).
+    var functionType = reflectionInfo;
+
+    // function tmp() {};
+    // tmp.prototype = BC.prototype;
+    // var proto = new tmp;
+    // for each computed prototype property:
+    //   proto[property] = ...;
+    // proto._init = BC;
+    // var dynClosureConstructor =
+    //     new Function('self', 'target', 'receiver', 'name',
+    //                  'this._init(self, target, receiver, name)');
+    // proto.constructor = dynClosureConstructor;
+    // dynClosureConstructor.prototype = proto;
+    // return dynClosureConstructor;
+
+    // We need to create a new subclass of TearOffClosure, one of StaticClosure
+    // or BoundClosure.  For this, we need to create an object whose prototype
+    // is the prototype is either StaticClosure.prototype or
+    // BoundClosure.prototype, respectively in pseudo JavaScript code. The
+    // simplest way to access the JavaScript construction function of a Dart
+    // class is to create an instance and access its constructor property.
+    // Creating an instance ensures that any lazy class initialization has taken
+    // place. The newly created instance could in theory be used directly as the
+    // prototype, but it might include additional fields that we don't need.  So
+    // we only use the new instance to access the constructor property and use
+    // Object.create to create the desired prototype.
+    //
+    // TODO(sra): Perhaps cache the prototype to avoid the allocation.
+    var prototype = isStatic
+        ? JS('StaticClosure', 'Object.create(#.constructor.prototype)',
+            new StaticClosure())
+        : JS('BoundClosure', 'Object.create(#.constructor.prototype)',
+            new BoundClosure(null, null, null, null));
+
+    JS('', '#.\$initialize = #', prototype, JS('', '#.constructor', prototype));
+
+    // The constructor functions have names to prevent the JavaScript
+    // implementation from inventing a name that might have special meaning
+    // (e.g. clashing with minified 'Object' or 'Interceptor').
+    var constructor = isStatic
+        ? JS('', 'function static_tear_off(){this.\$initialize()}')
+        : isCsp
+            ? JS('', 'function tear_off(a,b,c,d) {this.\$initialize(a,b,c,d)}')
+            : JS(
+                '',
+                'new Function("a,b,c,d" + #,'
+                    ' "this.\$initialize(a,b,c,d" + # + ")")',
+                functionCounter,
+                functionCounter++);
+
+    // It is necessary to set the constructor property, otherwise it will be
+    // "Object".
+    JS('', '#.constructor = #', prototype, constructor);
+
+    JS('', '#.prototype = #', constructor, prototype);
+
+    // Create a closure and "monkey" patch it with call stubs.
+    var trampoline = function;
+    if (!isStatic) {
+      trampoline = forwardCallTo(receiver, function, isIntercepted);
+      JS('', '#.\$reflectionInfo = #', trampoline, reflectionInfo);
+    } else {
+      JS('', '#[#] = #', prototype, STATIC_FUNCTION_NAME_PROPERTY_NAME,
+          propertyName);
+    }
+
+    var signatureFunction = JS_GET_FLAG('USE_NEW_RTI')
+        ? _computeSignatureFunctionNewRti(functionType, isStatic, isIntercepted)
+        : _computeSignatureFunctionLegacy(
+            functionType, isStatic, isIntercepted);
+
+    JS('', '#[#] = #', prototype, JS_GET_NAME(JsGetName.SIGNATURE_NAME),
+        signatureFunction);
+    var applyTrampoline = trampoline;
+    JS('', '#[#] = #', prototype, callName, trampoline);
+    for (int i = 1; i < functions.length; i++) {
+      var stub = functions[i];
+      var stubCallName = JS('String|Null', '#[#]', stub,
+          JS_GET_NAME(JsGetName.CALL_NAME_PROPERTY));
+      if (stubCallName != null) {
+        stub = isStatic ? stub : forwardCallTo(receiver, stub, isIntercepted);
+        JS('', '#[#] = #', prototype, stubCallName, stub);
+      }
+      if (i == applyTrampolineIndex) {
+        applyTrampoline = stub;
+        JS('', '#.\$reflectionInfo = #', applyTrampoline, reflectionInfo);
+      }
+    }
+
+    JS('', '#[#] = #', prototype, JS_GET_NAME(JsGetName.CALL_CATCH_ALL),
+        applyTrampoline);
+    String reqArgProperty = JS_GET_NAME(JsGetName.REQUIRED_PARAMETER_PROPERTY);
+    String defValProperty = JS_GET_NAME(JsGetName.DEFAULT_VALUES_PROPERTY);
+    JS('', '#.# = #.#', prototype, reqArgProperty, function, reqArgProperty);
+    JS('', '#.# = #.#', prototype, defValProperty, function, defValProperty);
+
+    return constructor;
+  }
+
+  static _computeSignatureFunctionLegacy(
+      Object functionType, bool isStatic, bool isIntercepted) {
+    if (JS('bool', 'typeof # == "number"', functionType)) {
+      // We cannot call [getType] here, since the types-metadata might not be
+      // set yet. This is, because fromTearOff might be called for constants
+      // when the program isn't completely set up yet.
+      //
+      // Note that we cannot just textually inline the call
+      // `getType(functionType)` since we cannot guarantee that the (then)
+      // captured variable `functionType` isn't reused.
+      return JS(
+          '',
+          '''(function(getType, t) {
+                    return function(){ return getType(t); };
+                })(#, #)''',
+          RAW_DART_FUNCTION_REF(getType),
+          functionType);
+    }
+    if (JS('bool', 'typeof # == "function"', functionType)) {
+      if (isStatic) {
+        return functionType;
+      } else {
+        var getReceiver = isIntercepted
+            ? RAW_DART_FUNCTION_REF(BoundClosure.receiverOf)
+            : RAW_DART_FUNCTION_REF(BoundClosure.selfOf);
+        return JS(
+            '',
+            'function(f,r){'
+                'return function(){'
+                'return f.apply({\$receiver:r(this)},arguments)'
+                '}'
+                '}(#,#)',
+            functionType,
+            getReceiver);
+      }
+    }
+    throw 'Error in functionType of tearoff';
+  }
+
+  static _computeSignatureFunctionNewRti(
+      Object functionType, bool isStatic, bool isIntercepted) {
+    if (JS('bool', 'typeof # == "number"', functionType)) {
+      // Index into types table.
+      //
+      // We cannot call [getTypeFromTypesTable] here, since the types-metadata
+      // might not be set yet. This is, because fromTearOff might be called for
+      // constants when the program isn't completely set up yet. We also want to
+      // avoid creating lots of types at startup.
+      return JS(
+          '',
+          '''(function(getType, t) {
+                 return function(){ return getType(t); };
+             })(#, #)''',
+          RAW_DART_FUNCTION_REF(newRti.getTypeFromTypesTable),
+          functionType);
+    }
+    if (JS('bool', 'typeof # == "string"', functionType)) {
+      // A recipe to evaluate against the instance type.
+      if (isStatic) {
+        throw 'TODO: Recipe for static tearoff.';
+      }
+      var typeEvalMethod = isIntercepted
+          ? RAW_DART_FUNCTION_REF(BoundClosure.evalRecipeIntercepted)
+          : RAW_DART_FUNCTION_REF(BoundClosure.evalRecipe);
+      return JS(
+          '',
+          '    function(recipe, evalOnReceiver) {'
+              '  return function() {'
+              '    return evalOnReceiver(this, recipe);'
+              '  };'
+              '}(#,#)',
+          functionType,
+          typeEvalMethod);
+    }
+    throw 'Error in functionType of tearoff';
+  }
+
+  static cspForwardCall(
+      int arity, bool isSuperCall, String stubName, function) {
+    var getSelf = RAW_DART_FUNCTION_REF(BoundClosure.selfOf);
+    // Handle intercepted stub-names with the default slow case.
+    if (isSuperCall) arity = -1;
+    switch (arity) {
+      case 0:
+        return JS(
+            '',
+            'function(n,S){'
+                'return function(){'
+                'return S(this)[n]()'
+                '}'
+                '}(#,#)',
+            stubName,
+            getSelf);
+      case 1:
+        return JS(
+            '',
+            'function(n,S){'
+                'return function(a){'
+                'return S(this)[n](a)'
+                '}'
+                '}(#,#)',
+            stubName,
+            getSelf);
+      case 2:
+        return JS(
+            '',
+            'function(n,S){'
+                'return function(a,b){'
+                'return S(this)[n](a,b)'
+                '}'
+                '}(#,#)',
+            stubName,
+            getSelf);
+      case 3:
+        return JS(
+            '',
+            'function(n,S){'
+                'return function(a,b,c){'
+                'return S(this)[n](a,b,c)'
+                '}'
+                '}(#,#)',
+            stubName,
+            getSelf);
+      case 4:
+        return JS(
+            '',
+            'function(n,S){'
+                'return function(a,b,c,d){'
+                'return S(this)[n](a,b,c,d)'
+                '}'
+                '}(#,#)',
+            stubName,
+            getSelf);
+      case 5:
+        return JS(
+            '',
+            'function(n,S){'
+                'return function(a,b,c,d,e){'
+                'return S(this)[n](a,b,c,d,e)'
+                '}'
+                '}(#,#)',
+            stubName,
+            getSelf);
+      default:
+        return JS(
+            '',
+            'function(f,s){'
+                'return function(){'
+                'return f.apply(s(this),arguments)'
+                '}'
+                '}(#,#)',
+            function,
+            getSelf);
+    }
+  }
+
+  static bool get isCsp => JS_GET_FLAG('USE_CONTENT_SECURITY_POLICY');
+
+  static forwardCallTo(receiver, function, bool isIntercepted) {
+    if (isIntercepted) return forwardInterceptedCallTo(receiver, function);
+    String stubName = JS('String|Null', '#.\$stubName', function);
+    int arity = JS('int', '#.length', function);
+    var lookedUpFunction = JS('', '#[#]', receiver, stubName);
+    // The receiver[stubName] may not be equal to the function if we try to
+    // forward to a super-method. Especially when we create a bound closure
+    // of a super-call we need to make sure that we don't forward back to the
+    // dynamically looked up function.
+    bool isSuperCall = !identical(function, lookedUpFunction);
+
+    if (isCsp || isSuperCall || arity >= 27) {
+      return cspForwardCall(arity, isSuperCall, stubName, function);
+    }
+
+    if (arity == 0) {
+      // Incorporate functionCounter into a local.
+      String selfName = 'self${functionCounter++}';
+      return JS(
+          '',
+          '(new Function(#))()',
+          'return function(){'
+              'var $selfName = this.${BoundClosure.selfFieldName()};'
+              'return $selfName.$stubName();'
+              '}');
+    }
+    assert(1 <= arity && arity < 27);
+    String arguments = JS('String',
+        '"abcdefghijklmnopqrstuvwxyz".split("").splice(0,#).join(",")', arity);
+    arguments += '${functionCounter++}';
+    return JS(
+        '',
+        '(new Function(#))()',
+        'return function($arguments){'
+            'return this.${BoundClosure.selfFieldName()}.$stubName($arguments);'
+            '}');
+  }
+
+  static cspForwardInterceptedCall(
+      int arity, bool isSuperCall, String name, function) {
+    var getSelf = RAW_DART_FUNCTION_REF(BoundClosure.selfOf);
+    var getReceiver = RAW_DART_FUNCTION_REF(BoundClosure.receiverOf);
+    // Handle intercepted stub-names with the default slow case.
+    if (isSuperCall) arity = -1;
+    switch (arity) {
+      case 0:
+        // Intercepted functions always takes at least one argument (the
+        // receiver).
+        throw new RuntimeError('Intercepted function with no arguments.');
+      case 1:
+        return JS(
+            '',
+            'function(n,s,r){'
+                'return function(){'
+                'return s(this)[n](r(this))'
+                '}'
+                '}(#,#,#)',
+            name,
+            getSelf,
+            getReceiver);
+      case 2:
+        return JS(
+            '',
+            'function(n,s,r){'
+                'return function(a){'
+                'return s(this)[n](r(this),a)'
+                '}'
+                '}(#,#,#)',
+            name,
+            getSelf,
+            getReceiver);
+      case 3:
+        return JS(
+            '',
+            'function(n,s,r){'
+                'return function(a,b){'
+                'return s(this)[n](r(this),a,b)'
+                '}'
+                '}(#,#,#)',
+            name,
+            getSelf,
+            getReceiver);
+      case 4:
+        return JS(
+            '',
+            'function(n,s,r){'
+                'return function(a,b,c){'
+                'return s(this)[n](r(this),a,b,c)'
+                '}'
+                '}(#,#,#)',
+            name,
+            getSelf,
+            getReceiver);
+      case 5:
+        return JS(
+            '',
+            'function(n,s,r){'
+                'return function(a,b,c,d){'
+                'return s(this)[n](r(this),a,b,c,d)'
+                '}'
+                '}(#,#,#)',
+            name,
+            getSelf,
+            getReceiver);
+      case 6:
+        return JS(
+            '',
+            'function(n,s,r){'
+                'return function(a,b,c,d,e){'
+                'return s(this)[n](r(this),a,b,c,d,e)'
+                '}'
+                '}(#,#,#)',
+            name,
+            getSelf,
+            getReceiver);
+      default:
+        return JS(
+            '',
+            'function(f,s,r,a){'
+                'return function(){'
+                'a=[r(this)];'
+                'Array.prototype.push.apply(a,arguments);'
+                'return f.apply(s(this),a)'
+                '}'
+                '}(#,#,#)',
+            function,
+            getSelf,
+            getReceiver);
+    }
+  }
+
+  static forwardInterceptedCallTo(receiver, function) {
+    String selfField = BoundClosure.selfFieldName();
+    String receiverField = BoundClosure.receiverFieldName();
+    String stubName = JS('String|Null', '#.\$stubName', function);
+    int arity = JS('int', '#.length', function);
+    bool isCsp = JS_GET_FLAG('USE_CONTENT_SECURITY_POLICY');
+    var lookedUpFunction = JS('', '#[#]', receiver, stubName);
+    // The receiver[stubName] may not be equal to the function if we try to
+    // forward to a super-method. Especially when we create a bound closure
+    // of a super-call we need to make sure that we don't forward back to the
+    // dynamically looked up function.
+    bool isSuperCall = !identical(function, lookedUpFunction);
+
+    if (isCsp || isSuperCall || arity >= 28) {
+      return cspForwardInterceptedCall(arity, isSuperCall, stubName, function);
+    }
+    if (arity == 1) {
+      return JS(
+          '',
+          '(new Function(#))()',
+          'return function(){'
+              'return this.$selfField.$stubName(this.$receiverField);'
+              '${functionCounter++}'
+              '}');
+    }
+    assert(1 < arity && arity < 28);
+    String arguments = JS(
+        'String',
+        '"abcdefghijklmnopqrstuvwxyz".split("").splice(0,#).join(",")',
+        arity - 1);
+    return JS(
+        '',
+        '(new Function(#))()',
+        'return function($arguments){'
+            'return this.$selfField.$stubName(this.$receiverField, $arguments);'
+            '${functionCounter++}'
+            '}');
+  }
+
+  // The backend adds a special getter of the form
+  //
+  // Closure get call => this;
+  //
+  // to allow tearing off a closure from itself. We do this magically in the
+  // backend rather than simply adding it here, as we do not want this getter
+  // to be visible to resolution and the generation of extra stubs.
+
+  String toString() {
+    String name;
+    if (JS_GET_FLAG('USE_NEW_RTI')) {
+      var constructor = JS('', '#.constructor', this);
+      name =
+          constructor == null ? null : JS('String|Null', '#.name', constructor);
+      if (name == null) name = 'unknown';
+    } else {
+      name = Primitives.objectTypeName(this);
+      // Mirrors puts a space in front of some names, so remove it.
+      name = JS('String', '#.trim()', name);
+    }
+    return "Closure '$name'";
+  }
+}
+
+/// Called from implicit method getter (aka tear-off).
+closureFromTearOff(receiver, functions, applyTrampolineIndex, reflectionInfo,
+    isStatic, isIntercepted, name) {
+  return Closure.fromTearOff(
+      receiver,
+      JS('JSArray', '#', functions),
+      JS('int|Null', '#', applyTrampolineIndex),
+      reflectionInfo,
+      JS('bool', '!!#', isStatic),
+      JS('bool', '!!#', isIntercepted),
+      JS('String', '#', name));
+}
+
+/// Represents an implicit closure of a function.
+abstract class TearOffClosure extends Closure {}
+
+class StaticClosure extends TearOffClosure {
+  String toString() {
+    String name =
+        JS('String|Null', '#[#]', this, STATIC_FUNCTION_NAME_PROPERTY_NAME);
+    if (name == null) return 'Closure of unknown static method';
+    return "Closure '${unminifyOrTag(name)}'";
+  }
+}
+
+/// Represents a 'tear-off' or property extraction closure of an instance
+/// method, that is an instance method bound to a specific receiver (instance).
+class BoundClosure extends TearOffClosure {
+  /// The receiver or interceptor.
+  // TODO(ahe): This could just be the interceptor, we always know if
+  // we need the interceptor when generating the call method.
+  final _self;
+
+  /// The method.
+  final _target;
+
+  /// The receiver. Null if [_self] is not an interceptor.
+  final _receiver;
+
+  /// The name of the function. Only used by the mirror system.
+  final String _name;
+
+  BoundClosure(this._self, this._target, this._receiver, this._name);
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! BoundClosure) return false;
+    return JS('bool', '# === #', _self, other._self) &&
+        JS('bool', '# === #', _target, other._target) &&
+        JS('bool', '# === #', _receiver, other._receiver);
+  }
+
+  int get hashCode {
+    int receiverHashCode;
+    if (_receiver == null) {
+      // A bound closure on a regular Dart object, just use the
+      // identity hash code.
+      receiverHashCode = Primitives.objectHashCode(_self);
+    } else if (JS('String', 'typeof #', _receiver) != 'object') {
+      // A bound closure on a primitive JavaScript type. We
+      // use the hashCode method we define for those primitive types.
+      receiverHashCode = _receiver.hashCode;
+    } else {
+      // A bound closure on an intercepted native class, just use the
+      // identity hash code.
+      receiverHashCode = Primitives.objectHashCode(_receiver);
+    }
+    return receiverHashCode ^ Primitives.objectHashCode(_target);
+  }
+
+  toString() {
+    var receiver = _receiver == null ? _self : _receiver;
+    // TODO(sra): When minified, mark [_name] with a tag,
+    // e.g. 'minified-property:' so that it can be unminified.
+    return "Closure '$_name' of "
+        "${Primitives.objectToHumanReadableString(receiver)}";
+  }
+
+  static evalRecipe(BoundClosure closure, String recipe) {
+    return newRti.evalInInstance(closure._self, recipe);
+  }
+
+  static evalRecipeIntercepted(BoundClosure closure, String recipe) {
+    return newRti.evalInInstance(closure._receiver, recipe);
+  }
+
+  @pragma('dart2js:noInline')
+  static selfOf(BoundClosure closure) => closure._self;
+
+  static targetOf(BoundClosure closure) => closure._target;
+
+  @pragma('dart2js:noInline')
+  static receiverOf(BoundClosure closure) => closure._receiver;
+
+  static nameOf(BoundClosure closure) => closure._name;
+
+  static String selfFieldNameCache;
+
+  static String selfFieldName() {
+    if (selfFieldNameCache == null) {
+      selfFieldNameCache = computeFieldNamed('self');
+    }
+    return selfFieldNameCache;
+  }
+
+  static String receiverFieldNameCache;
+
+  static String receiverFieldName() {
+    if (receiverFieldNameCache == null) {
+      receiverFieldNameCache = computeFieldNamed('receiver');
+    }
+    return receiverFieldNameCache;
+  }
+
+  @pragma('dart2js:noInline')
+  @pragma('dart2js:noSideEffects')
+  static String computeFieldNamed(String fieldName) {
+    var template = new BoundClosure('self', 'target', 'receiver', 'name');
+    var names = JSArray.markFixedList(
+        JS('', 'Object.getOwnPropertyNames(#)', template));
+    for (int i = 0; i < names.length; i++) {
+      var name = names[i];
+      if (JS('bool', '#[#] === #', template, name, fieldName)) {
+        return JS('String', '#', name);
+      }
+    }
+  }
+}
+
+bool jsHasOwnProperty(var jsObject, String property) {
+  return JS('bool', r'#.hasOwnProperty(#)', jsObject, property);
+}
+
+jsPropertyAccess(var jsObject, String property) {
+  return JS('var', r'#[#]', jsObject, property);
+}
+
+/// Called at the end of unaborted switch cases to get the singleton
+/// FallThroughError exception that will be thrown.
+getFallThroughError() => new FallThroughErrorImplementation();
+
+/// A metadata annotation describing the types instantiated by a native element.
+///
+/// The annotation is valid on a native method and a field of a native class.
+///
+/// By default, a field of a native class is seen as an instantiation point for
+/// all native classes that are a subtype of the field's type, and a native
+/// method is seen as an instantiation point fo all native classes that are a
+/// subtype of the method's return type, or the argument types of the declared
+/// type of the method's callback parameter.
+///
+/// An @[Creates] annotation overrides the default set of instantiated types.
+/// If one or more @[Creates] annotations are present, the type of the native
+/// element is ignored, and the union of @[Creates] annotations is used instead.
+/// The names in the strings are resolved and the program will fail to compile
+/// with dart2js if they do not name types.
+///
+/// The argument to [Creates] is a string.  The string is parsed as the names of
+/// one or more types, separated by vertical bars `|`.  There are some special
+/// names:
+///
+/// * `=Object`. This means 'exactly Object', which is a plain JavaScript object
+///   with properties and none of the subtypes of Object.
+///
+/// Example: we may know that a method always returns a specific implementation:
+///
+///     @Creates('_NodeList')
+///     List<Node> getElementsByTagName(String tag) native;
+///
+/// Useful trick: A method can be marked as not instantiating any native classes
+/// with the annotation `@Creates('Null')`.  This is useful for fields on native
+/// classes that are used only in Dart code.
+///
+///     @Creates('Null')
+///     var _cachedFoo;
+class Creates {
+  final String types;
+  const Creates(this.types);
+}
+
+/// A metadata annotation describing the types returned or yielded by a native
+/// element.
+///
+/// The annotation is valid on a native method and a field of a native class.
+///
+/// By default, a native method or field is seen as returning or yielding all
+/// subtypes if the method return type or field type.  This annotation allows a
+/// more precise set of types to be specified.
+///
+/// See [Creates] for the syntax of the argument.
+///
+/// Example: IndexedDB keys are numbers, strings and JavaScript Arrays of keys.
+///
+///     @Returns('String|num|JSExtendableArray')
+///     dynamic key;
+///
+///     // Equivalent:
+///     @Returns('String') @Returns('num') @Returns('JSExtendableArray')
+///     dynamic key;
+class Returns {
+  final String types;
+  const Returns(this.types);
+}
+
+/// A metadata annotation placed on native methods and fields of native classes
+/// to specify the JavaScript name.
+///
+/// This example declares a Dart field + getter + setter called `$dom_title`
+/// that corresponds to the JavaScript property `title`.
+///
+///     class Document native "*Foo" {
+///       @JSName('title')
+///       String $dom_title;
+///     }
+class JSName {
+  final String name;
+  const JSName(this.name);
+}
+
+/// The following methods are called by the runtime to implement checked mode
+/// and casts. We specialize each primitive type (eg int, bool), and use the
+/// compiler's convention to do is-checks on regular objects.
+boolConversionCheck(value) {
+  // The value from kernel should always be true, false, or null.
+  if (value == null) assertThrow('boolean expression must not be null');
+  return value;
+}
+
+stringTypeCheck(value) {
+  if (value == null) return value;
+  if (value is String) return value;
+  throw new TypeErrorImplementation(value, 'String');
+}
+
+stringTypeCast(value) {
+  if (value is String || value == null) return value;
+  throw new CastErrorImplementation(value, 'String');
+}
+
+doubleTypeCheck(value) {
+  if (value == null) return value;
+  if (value is double) return value;
+  throw new TypeErrorImplementation(value, 'double');
+}
+
+doubleTypeCast(value) {
+  if (value is double || value == null) return value;
+  throw new CastErrorImplementation(value, 'double');
+}
+
+numTypeCheck(value) {
+  if (value == null) return value;
+  if (value is num) return value;
+  throw new TypeErrorImplementation(value, 'num');
+}
+
+numTypeCast(value) {
+  if (value is num || value == null) return value;
+  throw new CastErrorImplementation(value, 'num');
+}
+
+boolTypeCheck(value) {
+  if (value == null) return value;
+  if (value is bool) return value;
+  throw new TypeErrorImplementation(value, 'bool');
+}
+
+boolTypeCast(value) {
+  if (value is bool || value == null) return value;
+  throw new CastErrorImplementation(value, 'bool');
+}
+
+intTypeCheck(value) {
+  if (value == null) return value;
+  if (value is int) return value;
+  throw new TypeErrorImplementation(value, 'int');
+}
+
+intTypeCast(value) {
+  if (value is int || value == null) return value;
+  throw new CastErrorImplementation(value, 'int');
+}
+
+void propertyTypeError(value, property) {
+  String name = isCheckPropertyToJsConstructorName(property);
+  throw new TypeErrorImplementation(value, unminifyOrTag(name));
+}
+
+void propertyTypeCastError(value, property) {
+  // Cuts the property name to the class name.
+  String name = isCheckPropertyToJsConstructorName(property);
+  throw new CastErrorImplementation(value, unminifyOrTag(name));
+}
+
+/// For types that are not supertypes of native (eg DOM) types,
+/// we emit a simple property check to check that an object implements
+/// that type.
+propertyTypeCheck(value, property) {
+  if (value == null) return value;
+  if (JS('bool', '!!#[#]', value, property)) return value;
+  propertyTypeError(value, property);
+}
+
+/// For types that are not supertypes of native (eg DOM) types,
+/// we emit a simple property check to check that an object implements
+/// that type.
+propertyTypeCast(value, property) {
+  if (value == null || JS('bool', '!!#[#]', value, property)) return value;
+  propertyTypeCastError(value, property);
+}
+
+/// For types that are supertypes of native (eg DOM) types, we use the
+/// interceptor for the class because we cannot add a JS property to the
+/// prototype at load time.
+interceptedTypeCheck(value, property) {
+  if (value == null) return value;
+  if ((JS('bool', 'typeof # === "object"', value) ||
+          JS('bool', 'typeof # === "function"', value)) &&
+      JS('bool', '#[#]', getInterceptor(value), property)) {
+    return value;
+  }
+  propertyTypeError(value, property);
+}
+
+/// For types that are supertypes of native (eg DOM) types, we use the
+/// interceptor for the class because we cannot add a JS property to the
+/// prototype at load time.
+interceptedTypeCast(value, property) {
+  if (value == null ||
+      ((JS('bool', 'typeof # === "object"', value) ||
+              JS('bool', 'typeof # === "function"', value)) &&
+          JS('bool', '#[#]', getInterceptor(value), property))) {
+    return value;
+  }
+  propertyTypeCastError(value, property);
+}
+
+/// Specialization of the type check for num and String and their
+/// supertype since [value] can be a JS primitive.
+numberOrStringSuperTypeCheck(value, property) {
+  if (value == null) return value;
+  if (value is String) return value;
+  if (value is num) return value;
+  if (JS('bool', '!!#[#]', value, property)) return value;
+  propertyTypeError(value, property);
+}
+
+numberOrStringSuperTypeCast(value, property) {
+  if (value is String) return value;
+  if (value is num) return value;
+  return propertyTypeCast(value, property);
+}
+
+numberOrStringSuperNativeTypeCheck(value, property) {
+  if (value == null) return value;
+  if (value is String) return value;
+  if (value is num) return value;
+  if (JS('bool', '#[#]', getInterceptor(value), property)) return value;
+  propertyTypeError(value, property);
+}
+
+numberOrStringSuperNativeTypeCast(value, property) {
+  if (value == null) return value;
+  if (value is String) return value;
+  if (value is num) return value;
+  if (JS('bool', '#[#]', getInterceptor(value), property)) return value;
+  propertyTypeCastError(value, property);
+}
+
+/// Specialization of the type check for String and its supertype
+/// since [value] can be a JS primitive.
+stringSuperTypeCheck(value, property) {
+  if (value == null) return value;
+  if (value is String) return value;
+  if (JS('bool', '!!#[#]', value, property)) return value;
+  propertyTypeError(value, property);
+}
+
+stringSuperTypeCast(value, property) {
+  if (value is String) return value;
+  return propertyTypeCast(value, property);
+}
+
+stringSuperNativeTypeCheck(value, property) {
+  if (value == null) return value;
+  if (value is String) return value;
+  if (JS('bool', '#[#]', getInterceptor(value), property)) return value;
+  propertyTypeError(value, property);
+}
+
+stringSuperNativeTypeCast(value, property) {
+  if (value is String || value == null) return value;
+  if (JS('bool', '#[#]', getInterceptor(value), property)) return value;
+  propertyTypeCastError(value, property);
+}
+
+/// Specialization of the type check for List and its supertypes,
+/// since [value] can be a JS array.
+listTypeCheck(value) {
+  if (value == null) return value;
+  if (value is List) return value;
+  throw new TypeErrorImplementation(value, 'List<dynamic>');
+}
+
+listTypeCast(value) {
+  if (value is List || value == null) return value;
+  throw new CastErrorImplementation(value, 'List<dynamic>');
+}
+
+listSuperTypeCheck(value, property) {
+  if (value == null) return value;
+  if (value is List) return value;
+  if (JS('bool', '!!#[#]', value, property)) return value;
+  propertyTypeError(value, property);
+}
+
+listSuperTypeCast(value, property) {
+  if (value is List) return value;
+  return propertyTypeCast(value, property);
+}
+
+listSuperNativeTypeCheck(value, property) {
+  if (value == null) return value;
+  if (value is List) return value;
+  if (JS('bool', '#[#]', getInterceptor(value), property)) return value;
+  propertyTypeError(value, property);
+}
+
+listSuperNativeTypeCast(value, property) {
+  if (value is List || value == null) return value;
+  if (JS('bool', '#[#]', getInterceptor(value), property)) return value;
+  propertyTypeCastError(value, property);
+}
+
+extractFunctionTypeObjectFrom(o) {
+  var interceptor = getInterceptor(o);
+  return extractFunctionTypeObjectFromInternal(interceptor);
+}
+
+extractFunctionTypeObjectFromInternal(o) {
+  var signatureName = JS_GET_NAME(JsGetName.SIGNATURE_NAME);
+  if (JS('bool', '# in #', signatureName, o)) {
+    var signature = JS('', '#[#]', o, signatureName);
+    if (JS('bool', 'typeof # == "number"', signature)) {
+      return getType(signature);
+    } else {
+      return JS('', '#[#]()', o, signatureName);
+    }
+  }
+  return null;
+}
+
+functionTypeTest(value, functionTypeRti) {
+  if (value == null) return false;
+  if (JS('bool', 'typeof # == "function"', value)) {
+    // JavaScript functions do not have an attached type, but for convenient
+    // JS-interop, we pretend they can be any function type.
+    // TODO(sra): Tighten this up to disallow matching function types with
+    // features inaccessible from JavaScript, i.e.  optional named parameters
+    // and type parameters functions.
+    // TODO(sra): If the JavaScript function was the output of `dart:js`'s
+    // `allowInterop` then we have access to the wrapped function.
+    return true;
+  }
+  var functionTypeObject = extractFunctionTypeObjectFrom(value);
+  if (functionTypeObject == null) return false;
+  return isFunctionSubtype(functionTypeObject, functionTypeRti);
+}
+
+// Declared as 'var' to avoid assignment checks.
+var _inTypeAssertion = false;
+
+functionTypeCheck(value, functionTypeRti) {
+  if (value == null) return value;
+
+  // The function type test code contains type assertions for function
+  // types. This leads to unbounded recursion, so disable the type checking of
+  // function types while checking function types.
+
+  if (true == _inTypeAssertion) return value;
+
+  _inTypeAssertion = true;
+  try {
+    if (functionTypeTest(value, functionTypeRti)) return value;
+    var self = runtimeTypeToString(functionTypeRti);
+    throw new TypeErrorImplementation(value, self);
+  } finally {
+    _inTypeAssertion = false;
+  }
+}
+
+functionTypeCast(value, functionTypeRti) {
+  if (value == null) return value;
+  if (functionTypeTest(value, functionTypeRti)) return value;
+
+  var self = runtimeTypeToString(functionTypeRti);
+  throw new CastErrorImplementation(value, self);
+}
+
+futureOrTest(o, futureOrRti) => checkSubtypeOfRuntimeType(o, futureOrRti);
+
+futureOrCheck(o, futureOrRti) => assertSubtypeOfRuntimeType(o, futureOrRti);
+
+futureOrCast(o, futureOrRti) => subtypeOfRuntimeTypeCast(o, futureOrRti);
+
+@pragma('dart2js:noInline')
+void checkDeferredIsLoaded(String loadId, String uri) {
+  if (!_loadedLibraries.contains(loadId)) {
+    throw new DeferredNotLoadedError(uri);
+  }
+}
+
+/// Special interface recognized by the compiler and implemented by DOM
+/// objects that support integer indexing. This interface is not
+/// visible to anyone, and is only injected into special libraries.
+abstract class JavaScriptIndexingBehavior<E> extends JSMutableIndexable<E> {}
+
+// TODO(lrn): These exceptions should be implemented in core.
+// When they are, remove the 'Implementation' here.
+
+/// Thrown by type assertions that fail.
+class TypeErrorImplementation extends Error implements TypeError {
+  final String message;
+
+  /// Normal type error caused by a failed subtype test.
+  TypeErrorImplementation(Object value, String type)
+      : message = "TypeError: ${Error.safeToString(value)}: type "
+            "'${_typeDescription(value)}' is not a subtype of type '$type'";
+
+  TypeErrorImplementation.fromMessage(String this.message);
+
+  String toString() => message;
+}
+
+/// Thrown by the 'as' operator if the cast isn't valid.
+class CastErrorImplementation extends Error implements CastError {
+  // TODO(lrn): Rename to CastError (and move implementation into core).
+  final String message;
+
+  /// Normal cast error caused by a failed type cast.
+  CastErrorImplementation(Object value, Object type)
+      : message = "CastError: ${Error.safeToString(value)}: type "
+            "'${_typeDescription(value)}' is not a subtype of type '$type'";
+
+  String toString() => message;
+}
+
+String _typeDescription(value) {
+  if (value is Closure) {
+    var functionTypeObject = extractFunctionTypeObjectFrom(value);
+    if (functionTypeObject != null) {
+      return runtimeTypeToString(functionTypeObject);
+    }
+    return 'Closure';
+  }
+  return Primitives.objectTypeName(value);
+}
+
+class FallThroughErrorImplementation extends FallThroughError {
+  FallThroughErrorImplementation();
+  String toString() => 'Switch case fall-through.';
+}
+
+/// Helper function for implementing asserts. The compiler treats this
+/// specially.
+///
+/// Returns the negation of the condition. That is: `true` if the assert should
+/// fail.
+bool assertTest(condition) {
+  // Do bool success check first, it is common and faster than 'is Function'.
+  if (true == condition) return false;
+  if (condition is bool) return !condition;
+  throw new TypeErrorImplementation(condition, 'bool');
+}
+
+/// Helper function for implementing asserts with messages.
+/// The compiler treats this specially.
+void assertThrow(Object message) {
+  throw new _AssertionError(message);
+}
+
+/// Helper function for implementing asserts without messages.
+/// The compiler treats this specially.
+@pragma('dart2js:noInline')
+void assertHelper(condition) {
+  if (assertTest(condition)) throw new AssertionError();
+}
+
+/// Called by generated code when a method that must be statically
+/// resolved cannot be found.
+void throwNoSuchMethod(obj, name, arguments, expectedArgumentNames) {
+  Symbol memberName = new _symbol_dev.Symbol.unvalidated(name);
+  throw new NoSuchMethodError(obj, memberName, arguments,
+      new Map<Symbol, dynamic>(), expectedArgumentNames);
+}
+
+/// Called by generated code when a static field's initializer references the
+/// field that is currently being initialized.
+void throwCyclicInit(String staticName) {
+  throw new CyclicInitializationError(staticName);
+}
+
+/// Error thrown when a runtime error occurs.
+class RuntimeError extends Error {
+  final message;
+  RuntimeError(this.message);
+  String toString() => 'RuntimeError: $message';
+}
+
+class DeferredNotLoadedError extends Error implements NoSuchMethodError {
+  String libraryName;
+
+  DeferredNotLoadedError(this.libraryName);
+
+  String toString() {
+    return 'Deferred library $libraryName was not loaded.';
+  }
+}
+
+// TODO(ahe): Remove this class and call noSuchMethod instead.
+class UnimplementedNoSuchMethodError extends Error
+    implements NoSuchMethodError {
+  final String _message;
+
+  UnimplementedNoSuchMethodError(this._message);
+
+  String toString() => 'Unsupported operation: $_message';
+}
+
+/// Creates a random number with 64 bits of randomness.
+///
+/// This will be truncated to the 53 bits available in a double.
+int random64() {
+  // TODO(lrn): Use a secure random source.
+  int int32a = JS('int', '(Math.random() * 0x100000000) >>> 0');
+  int int32b = JS('int', '(Math.random() * 0x100000000) >>> 0');
+  return int32a + int32b * 0x100000000;
+}
+
+String jsonEncodeNative(String string) {
+  return JS('String', 'JSON.stringify(#)', string);
+}
+
+/// Returns a property name for placing data on JavaScript objects shared
+/// between DOM isolates.  This happens when multiple programs are loaded in the
+/// same JavaScript context (i.e. page).  The name is based on [name] but with
+/// an additional part that is unique for each isolate.
+///
+/// The form of the name is '___dart_$name_$id'.
+String getIsolateAffinityTag(String name) {
+  var isolateTagGetter = JS_EMBEDDED_GLOBAL('', GET_ISOLATE_TAG);
+  return JS('String', '#(#)', isolateTagGetter, name);
+}
+
+typedef Future<Null> LoadLibraryFunctionType();
+
+LoadLibraryFunctionType _loadLibraryWrapper(String loadId) {
+  return () => loadDeferredLibrary(loadId);
+}
+
+final Map<String, Future<Null>> _loadingLibraries = <String, Future<Null>>{};
+final Set<String> _loadedLibraries = new Set<String>();
+
+/// Events used to diagnose failures from deferred loading requests.
+final List<String> _eventLog = <String>[];
+
+typedef void DeferredLoadCallback();
+
+// Function that will be called every time a new deferred import is loaded.
+DeferredLoadCallback deferredLoadHook;
+
+Future<Null> loadDeferredLibrary(String loadId) {
+  // For each loadId there is a list of parts to load. The parts are represented
+  // by an index. There are two arrays, one that maps the index into a Uri and
+  // another that maps the index to a hash.
+  var partsMap = JS_EMBEDDED_GLOBAL('', DEFERRED_LIBRARY_PARTS);
+  List indexes = JS('JSExtendableArray|Null', '#[#]', partsMap, loadId);
+  if (indexes == null) return new Future.value(null);
+  List<String> uris = <String>[];
+  List<String> hashes = <String>[];
+  List index2uri = JS_EMBEDDED_GLOBAL('JSArray', DEFERRED_PART_URIS);
+  List index2hash = JS_EMBEDDED_GLOBAL('JSArray', DEFERRED_PART_HASHES);
+  for (int i = 0; i < indexes.length; i++) {
+    int index = JS('int', '#[#]', indexes, i);
+    uris.add(JS('String', '#[#]', index2uri, index));
+    hashes.add(JS('String', '#[#]', index2hash, index));
+  }
+
+  int total = hashes.length;
+  assert(total == uris.length);
+  List<bool> waitingForLoad = new List.filled(total, true);
+  int nextHunkToInitialize = 0;
+  var isHunkLoaded = JS_EMBEDDED_GLOBAL('', IS_HUNK_LOADED);
+  var isHunkInitialized = JS_EMBEDDED_GLOBAL('', IS_HUNK_INITIALIZED);
+  var initializer = JS_EMBEDDED_GLOBAL('', INITIALIZE_LOADED_HUNK);
+
+  void initializeSomeLoadedHunks() {
+    for (int i = nextHunkToInitialize; i < total; ++i) {
+      // A hunk is initialized only if all the preceeding hunks have been
+      // initialized.
+      if (waitingForLoad[i]) return;
+      nextHunkToInitialize++;
+
+      // It is possible for a hash to be repeated. This happens when two
+      // different parts both end up empty. Checking in the loop rather than
+      // pre-filtering prevents duplicate hashes leading to duplicated
+      // initializations.
+      // TODO(29572): Merge small parts.
+      // TODO(29635): Remove duplicate parts from tables and output files.
+      var uri = uris[i];
+      var hash = hashes[i];
+      if (JS('bool', '#(#)', isHunkInitialized, hash)) {
+        _eventLog.add(' - already initialized: $uri ($hash)');
+        continue;
+      }
+      // On strange scenarios, e.g. if js encounters parse errors, we might get
+      // an "success" callback on the script load but the hunk will be null.
+      if (JS('bool', '#(#)', isHunkLoaded, hash)) {
+        _eventLog.add(' - initialize: $uri ($hash)');
+        JS('void', '#(#)', initializer, hash);
+      } else {
+        _eventLog.add(' - missing hunk: $uri ($hash)');
+        throw new DeferredLoadException("Loading ${uris[i]} failed: "
+            "the code with hash '${hash}' was not loaded.\n"
+            "event log:\n${_eventLog.join("\n")}\n");
+      }
+    }
+  }
+
+  Future loadAndInitialize(int i) {
+    if (JS('bool', '#(#)', isHunkLoaded, hashes[i])) {
+      waitingForLoad[i] = false;
+      return new Future.value();
+    }
+    return _loadHunk(uris[i]).then((_) {
+      waitingForLoad[i] = false;
+      initializeSomeLoadedHunks();
+    });
+  }
+
+  return Future.wait(new List.generate(total, loadAndInitialize)).then((_) {
+    initializeSomeLoadedHunks();
+    // At this point all hunks have been loaded, so there should be no pending
+    // initializations to do.
+    assert(nextHunkToInitialize == total);
+    bool updated = _loadedLibraries.add(loadId);
+    if (updated && deferredLoadHook != null) {
+      deferredLoadHook();
+    }
+  });
+}
+
+/// The `nonce` value on the current script used for strict-CSP, if any.
+String _cspNonce = _computeCspNonce();
+
+String _computeCspNonce() {
+  var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT);
+  if (currentScript == null) return null;
+  String nonce = JS('String|Null', '#.nonce', currentScript);
+  return (nonce != null && nonce != '')
+      ? nonce
+      : JS('String|Null', '#.getAttribute("nonce")', currentScript);
+}
+
+/// The 'crossOrigin' value on the current script used for CORS, if any.
+String _crossOrigin = _computeCrossOrigin();
+
+String _computeCrossOrigin() {
+  var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT);
+  if (currentScript == null) return null;
+  return JS('String|Null', '#.crossOrigin', currentScript);
+}
+
+/// Returns true if we are currently in a worker context.
+bool _isWorker() {
+  requiresPreamble();
+  return JS('', '!self.window && !!self.postMessage');
+}
+
+/// The src url for the script tag that loaded this code.
+String thisScript = _computeThisScript();
+
+/// The src url for the script tag that loaded this function.
+///
+/// Used to create JavaScript workers and load deferred libraries.
+String _computeThisScript() {
+  var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT);
+  if (currentScript != null) {
+    return JS('String', 'String(#.src)', currentScript);
+  }
+  // A worker has no script tag - so get an url from a stack-trace.
+  if (_isWorker()) return _computeThisScriptFromTrace();
+  // An isolate that doesn't support workers, but doesn't have a
+  // currentScript either. This is most likely a Chrome extension.
+  return null;
+}
+
+String _computeThisScriptFromTrace() {
+  var stack = JS('String|Null', 'new Error().stack');
+  if (stack == null) {
+    // According to Internet Explorer documentation, the stack
+    // property is not set until the exception is thrown. The stack
+    // property was not provided until IE10.
+    stack = JS(
+        'String|Null',
+        '(function() {'
+            'try { throw new Error() } catch(e) { return e.stack }'
+            '})()');
+    if (stack == null) throw new UnsupportedError('No stack trace');
+  }
+  var pattern, matches;
+
+  // This pattern matches V8, Chrome, and Internet Explorer stack
+  // traces that look like this:
+  // Error
+  //     at methodName (URI:LINE:COLUMN)
+  pattern = JS('', r'new RegExp("^ *at [^(]*\\((.*):[0-9]*:[0-9]*\\)$", "m")');
+
+  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('JSExtendableArray|Null', '#.match(#)', stack, pattern);
+  if (matches != null) return JS('String', '#[1]', matches);
+
+  throw new UnsupportedError('Cannot extract URI from "$stack"');
+}
+
+Future<Null> _loadHunk(String hunkName) {
+  Future<Null> future = _loadingLibraries[hunkName];
+  _eventLog.add(' - _loadHunk: $hunkName');
+  if (future != null) {
+    _eventLog.add('reuse: $hunkName');
+    return future.then((_) => null);
+  }
+
+  String uri = thisScript;
+
+  int index = uri.lastIndexOf('/');
+  uri = '${uri.substring(0, index + 1)}$hunkName';
+  _eventLog.add(' - download: $hunkName from $uri');
+
+  var deferredLibraryLoader = JS('', 'self.dartDeferredLibraryLoader');
+  Completer<Null> completer = new Completer<Null>();
+
+  void success() {
+    _eventLog.add(' - download success: $hunkName');
+    completer.complete(null);
+  }
+
+  void failure(error, String context, StackTrace stackTrace) {
+    _eventLog.add(' - download failed: $hunkName (context: $context)');
+    _loadingLibraries[hunkName] = null;
+    stackTrace ??= StackTrace.current;
+    completer.completeError(
+        new DeferredLoadException('Loading $uri failed: $error\n'
+            'event log:\n${_eventLog.join("\n")}\n'),
+        stackTrace);
+  }
+
+  var jsSuccess = convertDartClosureToJS(success, 0);
+  var jsFailure = convertDartClosureToJS((error) {
+    failure(unwrapException(error), 'js-failure-wrapper',
+        getTraceFromException(error));
+  }, 1);
+
+  if (JS('bool', 'typeof # === "function"', deferredLibraryLoader)) {
+    try {
+      JS('void', '#(#, #, #)', deferredLibraryLoader, uri, jsSuccess,
+          jsFailure);
+    } catch (error, stackTrace) {
+      failure(error, "invoking dartDeferredLibraryLoader hook", stackTrace);
+    }
+  } else if (_isWorker()) {
+    // We are in a web worker. Load the code with an XMLHttpRequest.
+    int index = uri.lastIndexOf('/');
+    uri = '${uri.substring(0, index + 1)}$hunkName';
+    var xhr = JS('var', 'new XMLHttpRequest()');
+    JS('void', '#.open("GET", #)', xhr, uri);
+    JS(
+        'void',
+        '#.addEventListener("load", #, false)',
+        xhr,
+        convertDartClosureToJS((event) {
+          int status = JS('int', '#.status', xhr);
+          if (status != 200) {
+            failure('Request status: $status', 'worker xhr', null);
+          }
+          String code = JS('String', '#.responseText', xhr);
+          try {
+            // Create a new function to avoid getting access to current function
+            // context.
+            JS('void', '(new Function(#))()', code);
+            success();
+          } catch (error, stackTrace) {
+            failure(error, 'evaluating the code in worker xhr', stackTrace);
+          }
+        }, 1));
+
+    JS('void', '#.addEventListener("error", #, false)', xhr, (e) {
+      failure(e, 'xhr error handler', null);
+    });
+    JS('void', '#.addEventListener("abort", #, false)', xhr, (e) {
+      failure(e, 'xhr abort handler', null);
+    });
+    JS('void', '#.send()', xhr);
+  } else {
+    // We are in a dom-context.
+    // Inject a script tag.
+    var script = JS('', 'document.createElement("script")');
+    JS('', '#.type = "text/javascript"', script);
+    JS('', '#.src = #', script, uri);
+    if (_cspNonce != null && _cspNonce != '') {
+      JS('', '#.nonce = #', script, _cspNonce);
+      JS('', '#.setAttribute("nonce", #)', script, _cspNonce);
+    }
+    if (_crossOrigin != null && _crossOrigin != '') {
+      JS('', '#.crossOrigin = #', script, _crossOrigin);
+    }
+    JS('', '#.addEventListener("load", #, false)', script, jsSuccess);
+    JS('', '#.addEventListener("error", #, false)', script, jsFailure);
+    JS('', 'document.body.appendChild(#)', script);
+  }
+  _loadingLibraries[hunkName] = completer.future;
+  return completer.future;
+}
+
+class MainError extends Error implements NoSuchMethodError {
+  final String _message;
+
+  MainError(this._message);
+
+  String toString() => 'NoSuchMethodError: $_message';
+}
+
+void missingMain() {
+  throw new MainError("No top-level function named 'main'.");
+}
+
+void badMain() {
+  throw new MainError("'main' is not a function.");
+}
+
+void mainHasTooManyParameters() {
+  throw new MainError("'main' expects too many parameters.");
+}
+
+class _AssertionError extends AssertionError {
+  _AssertionError(Object message) : super(message);
+
+  String toString() => "Assertion failed: " + Error.safeToString(message);
+}
+
+// [_UnreachableError] is a separate class because we always resolve
+// [assertUnreachable] and want to reduce the impact of resolving possibly
+// unneeded code.
+class _UnreachableError extends AssertionError {
+  _UnreachableError();
+  String toString() => 'Assertion failed: Reached dead code';
+}
+
+@pragma('dart2js:noInline')
+void assertUnreachable() {
+  throw new _UnreachableError();
+}
+
+// Hook to register new global object if necessary.
+// This is currently a no-op in dart2js.
+void registerGlobalObject(object) {}
+
+// Hook to register new browser classes.
+// This is currently a no-op in dart2js.
+void applyExtension(name, nativeObject) {}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_names.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_names.dart
new file mode 100644
index 0000000..cb4aa0e
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_names.dart
@@ -0,0 +1,167 @@
+// 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 dart._js_names;
+
+import 'dart:_js_embedded_names'
+    show JsGetName, MANGLED_GLOBAL_NAMES, MANGLED_NAMES;
+
+import 'dart:_foreign_helper' show JS, JS_EMBEDDED_GLOBAL, JS_GET_NAME;
+
+import 'dart:_js_helper' show JsCache, NoInline;
+
+import 'dart:_interceptors' show JSArray;
+
+/// No-op method that is called to inform the compiler that unmangled named
+/// must be preserved.
+preserveNames() {}
+
+/// A map from mangled names to "reflective" names, that is, unmangled names
+/// with some additional information, such as, number of required arguments.
+/// This map is for mangled names used as instance members.
+final _LazyMangledNamesMap mangledNames = new _LazyMangledInstanceNamesMap(
+    JS_EMBEDDED_GLOBAL('=Object', MANGLED_NAMES));
+
+/// A map from "reflective" names to mangled names (the reverse of
+/// [mangledNames]).
+final _LazyReflectiveNamesMap reflectiveNames = new _LazyReflectiveNamesMap(
+    JS_EMBEDDED_GLOBAL('=Object', MANGLED_NAMES), true);
+
+/// A map from mangled names to "reflective" names (see [mangledNames]).  This
+/// map is for globals, that is, static and top-level members.
+final _LazyMangledNamesMap mangledGlobalNames = new _LazyMangledNamesMap(
+    JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES));
+
+/// A map from "reflective" names to mangled names (the reverse of
+/// [mangledGlobalNames]).
+final _LazyReflectiveNamesMap reflectiveGlobalNames =
+    new _LazyReflectiveNamesMap(
+        JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES), false);
+
+/// Implements a mapping from mangled names to their reflective counterparts.
+/// The propertiy names of [_jsMangledNames] are the mangled names, and the
+/// values are the "reflective" names.
+class _LazyMangledNamesMap {
+  /// [_jsMangledNames] is a JavaScript object literal.
+  var _jsMangledNames;
+
+  _LazyMangledNamesMap(this._jsMangledNames);
+
+  String operator [](String key) {
+    var result = JS('var', '#[#]', _jsMangledNames, key);
+    // Filter out all non-string values to protect against polution from
+    // ancillary fields in [_jsMangledNames].
+    bool filter = JS('bool', 'typeof # !== "string"', result);
+    // To ensure that the inferrer sees that result is a String, we explicitly
+    // give it a better type here.
+    return filter ? null : JS('String', '#', result);
+  }
+}
+
+/// Extends [_LazyMangledNamesMap] with additional support for adding mappings
+/// from mangled setter names to their reflective counterpart by rewriting a
+/// corresponding entry for a getter name, if it exists.
+class _LazyMangledInstanceNamesMap extends _LazyMangledNamesMap {
+  _LazyMangledInstanceNamesMap(_jsMangledNames) : super(_jsMangledNames);
+
+  String operator [](String key) {
+    String result = super[key];
+    String setterPrefix = JS_GET_NAME(JsGetName.SETTER_PREFIX);
+    if (result == null && key.startsWith(setterPrefix)) {
+      String getterPrefix = JS_GET_NAME(JsGetName.GETTER_PREFIX);
+      int setterPrefixLength = setterPrefix.length;
+
+      // Generate the setter name from the getter name.
+      key = '$getterPrefix${key.substring(setterPrefixLength)}';
+      result = super[key];
+      return (result != null) ? "${result}=" : null;
+    }
+    return result;
+  }
+}
+
+/// Implements the inverse of [_LazyMangledNamesMap]. As it would be too
+/// expensive to search the mangled names map for a value that corresponds to
+/// the lookup key on each invocation, we compute the full mapping in demand
+/// and cache it. The cache is invalidated when the underlying [_jsMangledNames]
+/// object changes its length. This condition is sufficient as the name mapping
+/// can only grow over time.
+/// When [_isInstance] is true, we also apply the inverse of the setter/getter
+/// name conversion implemented by [_LazyMangledInstanceNamesMap].
+class _LazyReflectiveNamesMap {
+  /// [_jsMangledNames] is a JavaScript object literal.
+  final _jsMangledNames;
+  final bool _isInstance;
+  int _cacheLength = 0;
+  Map<String, String> _cache;
+
+  _LazyReflectiveNamesMap(this._jsMangledNames, this._isInstance);
+
+  Map<String, String> _updateReflectiveNames() {
+    preserveNames();
+    Map<String, String> result = <String, String>{};
+    List keys = JS('List', 'Object.keys(#)', _jsMangledNames);
+    for (String key in keys) {
+      var reflectiveName = JS('var', '#[#]', _jsMangledNames, key);
+      // Filter out all non-string values to protect against polution from
+      // ancillary fields in [_jsMangledNames].
+      bool filter = JS('bool', 'typeof # !== "string"', reflectiveName);
+      if (filter) continue;
+      result[reflectiveName] = JS('String', '#', key);
+
+      String getterPrefix = JS_GET_NAME(JsGetName.GETTER_PREFIX);
+      if (_isInstance && key.startsWith(getterPrefix)) {
+        int getterPrefixLength = getterPrefix.length;
+        String setterPrefix = JS_GET_NAME(JsGetName.SETTER_PREFIX);
+        result['$reflectiveName='] =
+            '$setterPrefix${key.substring(getterPrefixLength)}';
+      }
+    }
+    return result;
+  }
+
+  int get _jsMangledNamesLength =>
+      JS('int', 'Object.keys(#).length', _jsMangledNames);
+
+  String operator [](String key) {
+    if (_cache == null || _jsMangledNamesLength != _cacheLength) {
+      _cache = _updateReflectiveNames();
+      _cacheLength = _jsMangledNamesLength;
+    }
+    return _cache[key];
+  }
+}
+
+@pragma('dart2js:noInline')
+List extractKeys(victim) {
+  var result = JS('', '# ? Object.keys(#) : []', victim, victim);
+  return new JSArray.markFixed(result);
+}
+
+/// Returns the (global) unmangled version of [name].
+///
+/// Normally, you should use [mangledGlobalNames] directly, but this method
+/// doesn't tell the compiler to preserve names. So this method only returns a
+/// non-null value if some other component has made the compiler preserve names.
+///
+/// This is used, for example, to return unmangled names from TypeImpl.toString
+/// *if* names are being preserved for other reasons (use of dart:mirrors, for
+/// example).
+String unmangleGlobalNameIfPreservedAnyways(String name) {
+  var names = JS_EMBEDDED_GLOBAL('', MANGLED_GLOBAL_NAMES);
+  return JS('String|Null', '#', JsCache.fetch(names, name));
+}
+
+String unmangleAllIdentifiersIfPreservedAnyways(String str) {
+  return JS(
+      'String',
+      r'''
+        (function(str, names) {
+          return str.replace(
+              /[^<,> ]+/g,
+              function(m) { return names[m] || m; });
+        })(#, #)''',
+      str,
+      JS_EMBEDDED_GLOBAL('', MANGLED_GLOBAL_NAMES));
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_number.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_number.dart
new file mode 100644
index 0000000..918c1ba
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_number.dart
@@ -0,0 +1,707 @@
+// Copyright (c) 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 _interceptors;
+
+/// The super interceptor class for [JSInt] and [JSDouble]. The compiler
+/// recognizes this class as an interceptor, and changes references to
+/// [:this:] to actually use the receiver of the method, which is
+/// generated as an extra argument added to each member.
+///
+/// Note that none of the methods here delegate to a method defined on JSInt or
+/// JSDouble.  This is exploited in [tryComputeConstantInterceptor].
+class JSNumber extends Interceptor implements double {
+  const JSNumber();
+
+  int compareTo(num b) {
+    if (b is! num) throw argumentErrorValue(b);
+    if (this < b) {
+      return -1;
+    } else if (this > b) {
+      return 1;
+    } else if (this == b) {
+      if (this == 0) {
+        bool bIsNegative = b.isNegative;
+        if (isNegative == bIsNegative) return 0;
+        if (isNegative) return -1;
+        return 1;
+      }
+      return 0;
+    } else if (isNaN) {
+      if (b.isNaN) {
+        return 0;
+      }
+      return 1;
+    } else {
+      return -1;
+    }
+  }
+
+  bool get isNegative => (this == 0) ? (1 / this) < 0 : this < 0;
+
+  bool get isNaN => JS(
+      'returns:bool;effects:none;depends:none;throws:never;gvn:true',
+      r'isNaN(#)',
+      this);
+
+  bool get isInfinite {
+    return JS('bool', r'# == (1/0)', this) || JS('bool', r'# == (-1/0)', this);
+  }
+
+  bool get isFinite => JS(
+      'returns:bool;effects:none;depends:none;throws:never;gvn:true',
+      r'isFinite(#)',
+      this);
+
+  JSNumber remainder(num b) {
+    if (b is! num) throw argumentErrorValue(b);
+    return JS('num', r'# % #', this, b);
+  }
+
+  // Use invoke_dynamic_specializer instead of inlining.
+  @pragma('dart2js:noInline')
+  JSNumber abs() => JS(
+      'returns:num;effects:none;depends:none;throws:never;gvn:true',
+      r'Math.abs(#)',
+      this);
+
+  JSNumber get sign => this > 0 ? 1 : this < 0 ? -1 : this;
+
+  static const int _MIN_INT32 = -0x80000000;
+  static const int _MAX_INT32 = 0x7FFFFFFF;
+
+  int toInt() {
+    if (this >= _MIN_INT32 && this <= _MAX_INT32) {
+      // 0 and -0.0 handled here.
+      return JS('int', '# | 0', this);
+    }
+    if (JS('bool', r'isFinite(#)', this)) {
+      return JS('int', r'# + 0', truncateToDouble()); // Converts -0.0 to +0.0.
+    }
+    // [this] is either NaN, Infinity or -Infinity.
+    throw new UnsupportedError(JS('String', '"" + # + ".toInt()"', this));
+  }
+
+  int truncate() => toInt();
+
+  int ceil() {
+    if (this >= 0) {
+      if (this <= _MAX_INT32) {
+        int truncated = JS('int', '# | 0', this); // converts -0.0 to 0.
+        return this == truncated ? truncated : truncated + 1;
+      }
+    } else {
+      if (this >= _MIN_INT32) {
+        return JS('int', '# | 0', this);
+      }
+    }
+    var d = JS('num', 'Math.ceil(#)', this);
+    if (JS('bool', r'isFinite(#)', d)) {
+      return JS('int', r'#', d);
+    }
+    // [this] is either NaN, Infinity or -Infinity.
+    throw new UnsupportedError(JS('String', '"" + # + ".ceil()"', this));
+  }
+
+  int floor() {
+    if (this >= 0) {
+      if (this <= _MAX_INT32) {
+        return JS('int', '# | 0', this);
+      }
+    } else {
+      if (this >= _MIN_INT32) {
+        int truncated = JS('int', '# | 0', this);
+        return this == truncated ? truncated : truncated - 1;
+      }
+    }
+    var d = JS('num', 'Math.floor(#)', this);
+    if (JS('bool', r'isFinite(#)', d)) {
+      return JS('int', r'#', d);
+    }
+    // [this] is either NaN, Infinity or -Infinity.
+    throw new UnsupportedError(JS('String', '"" + # + ".floor()"', this));
+  }
+
+  int round() {
+    if (this > 0) {
+      // This path excludes the special cases -0.0, NaN and -Infinity, leaving
+      // only +Infinity, for which a direct test is faster than [isFinite].
+      if (JS('bool', r'# !== (1/0)', this)) {
+        return JS('int', r'Math.round(#)', this);
+      }
+    } else if (JS('bool', '# > (-1/0)', this)) {
+      // This test excludes NaN and -Infinity, leaving only -0.0.
+      //
+      // Subtraction from zero rather than negation forces -0.0 to 0.0 so code
+      // inside Math.round and code to handle result never sees -0.0, which on
+      // some JavaScript VMs can be a slow path.
+      return JS('int', r'0 - Math.round(0 - #)', this);
+    }
+    // [this] is either NaN, Infinity or -Infinity.
+    throw new UnsupportedError(JS('String', '"" + # + ".round()"', this));
+  }
+
+  double ceilToDouble() => JS('num', r'Math.ceil(#)', this);
+
+  double floorToDouble() => JS('num', r'Math.floor(#)', this);
+
+  double roundToDouble() {
+    if (this < 0) {
+      return JS('num', r'-Math.round(-#)', this);
+    } else {
+      return JS('num', r'Math.round(#)', this);
+    }
+  }
+
+  double truncateToDouble() => this < 0 ? ceilToDouble() : floorToDouble();
+
+  num clamp(lowerLimit, upperLimit) {
+    if (lowerLimit is! num) throw argumentErrorValue(lowerLimit);
+    if (upperLimit is! num) throw argumentErrorValue(upperLimit);
+    if (lowerLimit.compareTo(upperLimit) > 0) {
+      throw argumentErrorValue(lowerLimit);
+    }
+    if (this.compareTo(lowerLimit) < 0) return lowerLimit;
+    if (this.compareTo(upperLimit) > 0) return upperLimit;
+    return this;
+  }
+
+  // The return type is intentionally omitted to avoid type checker warnings
+  // from assigning JSNumber to double.
+  toDouble() => this;
+
+  String toStringAsFixed(int fractionDigits) {
+    checkInt(fractionDigits);
+    if (fractionDigits < 0 || fractionDigits > 20) {
+      throw new RangeError.range(fractionDigits, 0, 20, 'fractionDigits');
+    }
+    String result = JS('String', r'#.toFixed(#)', this, fractionDigits);
+    if (this == 0 && isNegative) return '-$result';
+    return result;
+  }
+
+  String toStringAsExponential([int fractionDigits]) {
+    String result;
+    if (fractionDigits != null) {
+      checkInt(fractionDigits);
+      if (fractionDigits < 0 || fractionDigits > 20) {
+        throw new RangeError.range(fractionDigits, 0, 20, 'fractionDigits');
+      }
+      result = JS('String', r'#.toExponential(#)', this, fractionDigits);
+    } else {
+      result = JS('String', r'#.toExponential()', this);
+    }
+    if (this == 0 && isNegative) return '-$result';
+    return result;
+  }
+
+  String toStringAsPrecision(int precision) {
+    checkInt(precision);
+    if (precision < 1 || precision > 21) {
+      throw new RangeError.range(precision, 1, 21, 'precision');
+    }
+    String result = JS('String', r'#.toPrecision(#)', this, precision);
+    if (this == 0 && isNegative) return '-$result';
+    return result;
+  }
+
+  String toRadixString(int radix) {
+    checkInt(radix);
+    if (radix < 2 || radix > 36) {
+      throw new RangeError.range(radix, 2, 36, 'radix');
+    }
+    String result = JS('String', r'#.toString(#)', this, radix);
+    const int rightParenCode = 0x29;
+    if (result.codeUnitAt(result.length - 1) != rightParenCode) {
+      return result;
+    }
+    return _handleIEtoString(result);
+  }
+
+  static String _handleIEtoString(String result) {
+    // Result is probably IE's untraditional format for large numbers,
+    // e.g., "8.0000000000008(e+15)" for 0x8000000000000800.toString(16).
+    var match = JS('JSArray|Null',
+        r'/^([\da-z]+)(?:\.([\da-z]+))?\(e\+(\d+)\)$/.exec(#)', result);
+    if (match == null) {
+      // Then we don't know how to handle it at all.
+      throw new UnsupportedError('Unexpected toString result: $result');
+    }
+    result = JS('String', '#', match[1]);
+    int exponent = JS('int', '+#', match[3]);
+    if (match[2] != null) {
+      result = JS('String', '# + #', result, match[2]);
+      exponent -= JS('int', '#.length', match[2]);
+    }
+    return result + '0' * exponent;
+  }
+
+  // Note: if you change this, also change the function [S].
+  String toString() {
+    if (this == 0 && JS('bool', '(1 / #) < 0', this)) {
+      return '-0.0';
+    } else {
+      return JS('String', r'"" + (#)', this);
+    }
+  }
+
+  int get hashCode {
+    int intValue = JS('int', '# | 0', this);
+    // Fast exit for integers in signed 32-bit range. Masking converts -0.0 to 0
+    // and ensures that result fits in JavaScript engine's Smi range.
+    if (this == intValue) return 0x1FFFFFFF & intValue;
+
+    // We would like to access the exponent and mantissa as integers but there
+    // are no JavaScript operations that do this, so use log2-floor-pow-divide
+    // to extract the values.
+    num absolute = JS('num', 'Math.abs(#)', this);
+    num lnAbsolute = JS('num', 'Math.log(#)', absolute);
+    num log2 = lnAbsolute / ln2;
+    // Floor via '# | 0' converts NaN to zero so the final result is not NaN.
+    int floorLog2 = JS('int', '# | 0', log2);
+    num factor = JS('num', 'Math.pow(2, #)', floorLog2);
+    num scaled = absolute < 1 ? absolute / factor : factor / absolute;
+    // [scaled] is in the range [0.5, 1].
+
+    // Multiply and truncate to pick up all the mantissa bits. Multiplying by
+    // 0x20000000000000 (which has 53 zero bits) converts the mantissa into an
+    // integer. There are interesting subsets where all the bit variance is in
+    // the most significant bits of the mantissa (e.g. 0.5, 0.625, 0.75), so we
+    // need to mix in the most significant bits. We do this by scaling with a
+    // constant that has many bits set to use the multiplier to mix in bits from
+    // all over the mantissa into low positions.
+    num rescaled1 = scaled * 0x20000000000000;
+    num rescaled2 = scaled * 0x0C95A6C285A6C9;
+    int d1 = JS('int', '# | 0', rescaled1);
+    int d2 = JS('int', '# | 0', rescaled2);
+    // Mix in exponent to distinguish e.g. 1.25 from 2.5.
+    int d3 = floorLog2;
+    int h = 0x1FFFFFFF & ((d1 + d2) * (601 * 997) + d3 * (1259));
+    return h;
+  }
+
+  JSNumber operator -() => JS('num', r'-#', this);
+
+  JSNumber operator +(num other) {
+    if (other is! num) throw argumentErrorValue(other);
+    return JS('num', '# + #', this, other);
+  }
+
+  JSNumber operator -(num other) {
+    if (other is! num) throw argumentErrorValue(other);
+    return JS('num', '# - #', this, other);
+  }
+
+  double operator /(num other) {
+    if (other is! num) throw argumentErrorValue(other);
+    return JS('num', '# / #', this, other);
+  }
+
+  JSNumber operator *(num other) {
+    if (other is! num) throw argumentErrorValue(other);
+    return JS('num', '# * #', this, other);
+  }
+
+  JSNumber operator %(num other) {
+    if (other is! num) throw argumentErrorValue(other);
+    // Euclidean Modulo.
+    num result = JS('num', r'# % #', this, other);
+    if (result == 0) return JS('num', '0'); // Make sure we don't return -0.0.
+    if (result > 0) return result;
+    if (JS('num', '#', other) < 0) {
+      return result - JS('num', '#', other);
+    } else {
+      return result + JS('num', '#', other);
+    }
+  }
+
+  bool _isInt32(value) => JS('bool', '(# | 0) === #', value, value);
+
+  int operator ~/(num other) {
+    if (other is! num) throw argumentErrorValue(other);
+    if (false) _tdivFast(other); // Ensure resolution.
+    if (_isInt32(this)) {
+      if (other >= 1 || other < -1) {
+        return JS('int', r'(# / #) | 0', this, other);
+      }
+    }
+    return _tdivSlow(other);
+  }
+
+  int _tdivFast(num other) {
+    // [other] is known to be a number outside the range [-1, 1).
+    return _isInt32(this)
+        ? JS('int', r'(# / #) | 0', this, other)
+        : _tdivSlow(other);
+  }
+
+  int _tdivSlow(num other) {
+    var quotient = JS('num', r'# / #', this, other);
+    if (quotient >= _MIN_INT32 && quotient <= _MAX_INT32) {
+      // This path includes -0.0 and +0.0.
+      return JS('int', '# | 0', quotient);
+    }
+    if (quotient > 0) {
+      // This path excludes the special cases -0.0, NaN and -Infinity, leaving
+      // only +Infinity, for which a direct test is faster than [isFinite].
+      if (JS('bool', r'# !== (1/0)', quotient)) {
+        return JS('int', r'Math.floor(#)', quotient);
+      }
+    } else if (JS('bool', '# > (-1/0)', quotient)) {
+      // This test excludes NaN and -Infinity.
+      return JS('int', r'Math.ceil(#)', quotient);
+    }
+
+    // [quotient] is either NaN, Infinity or -Infinity.
+    throw new UnsupportedError(
+        'Result of truncating division is $quotient: $this ~/ $other');
+  }
+
+  // TODO(ngeoffray): Move the bit operations below to [JSInt] and
+  // make them take an int. Because this will make operations slower,
+  // we define these methods on number for now but we need to decide
+  // the grain at which we do the type checks.
+
+  num operator <<(num other) {
+    if (other is! num) throw argumentErrorValue(other);
+    if (JS('num', '#', other) < 0) throw argumentErrorValue(other);
+    return _shlPositive(other);
+  }
+
+  num _shlPositive(num other) {
+    // JavaScript only looks at the last 5 bits of the shift-amount. Shifting
+    // by 33 is hence equivalent to a shift by 1.
+    return JS('bool', r'# > 31', other)
+        ? 0
+        : JS('JSUInt32', r'(# << #) >>> 0', this, other);
+  }
+
+  num operator >>(num other) {
+    if (false) _shrReceiverPositive(other);
+    if (other is! num) throw argumentErrorValue(other);
+    if (JS('num', '#', other) < 0) throw argumentErrorValue(other);
+    return _shrOtherPositive(other);
+  }
+
+  num _shrOtherPositive(num other) {
+    return JS('num', '#', this) > 0
+        ? _shrBothPositive(other)
+        // For negative numbers we just clamp the shift-by amount.
+        // `this` could be negative but not have its 31st bit set.
+        // The ">>" would then shift in 0s instead of 1s. Therefore
+        // we cannot simply return 0xFFFFFFFF.
+        : JS('JSUInt32', r'(# >> #) >>> 0', this, other > 31 ? 31 : other);
+  }
+
+  num _shrReceiverPositive(num other) {
+    if (JS('num', '#', other) < 0) throw argumentErrorValue(other);
+    return _shrBothPositive(other);
+  }
+
+  num _shrBothPositive(num other) {
+    return JS('bool', r'# > 31', other)
+        // JavaScript only looks at the last 5 bits of the shift-amount. In JS
+        // shifting by 33 is hence equivalent to a shift by 1. Shortcut the
+        // computation when that happens.
+        ? 0
+        // Given that `this` is positive we must not use '>>'. Otherwise a
+        // number that has the 31st bit set would be treated as negative and
+        // shift in ones.
+        : JS('JSUInt32', r'# >>> #', this, other);
+  }
+
+  num operator &(num other) {
+    if (other is! num) throw argumentErrorValue(other);
+    return JS('JSUInt32', r'(# & #) >>> 0', this, other);
+  }
+
+  num operator |(num other) {
+    if (other is! num) throw argumentErrorValue(other);
+    return JS('JSUInt32', r'(# | #) >>> 0', this, other);
+  }
+
+  num operator ^(num other) {
+    if (other is! num) throw argumentErrorValue(other);
+    return JS('JSUInt32', r'(# ^ #) >>> 0', this, other);
+  }
+
+  bool operator <(num other) {
+    if (other is! num) throw argumentErrorValue(other);
+    return JS('bool', '# < #', this, other);
+  }
+
+  bool operator >(num other) {
+    if (other is! num) throw argumentErrorValue(other);
+    return JS('bool', '# > #', this, other);
+  }
+
+  bool operator <=(num other) {
+    if (other is! num) throw argumentErrorValue(other);
+    return JS('bool', '# <= #', this, other);
+  }
+
+  bool operator >=(num other) {
+    if (other is! num) throw argumentErrorValue(other);
+    return JS('bool', '# >= #', this, other);
+  }
+
+  Type get runtimeType => num;
+}
+
+/// The interceptor class for [int]s.
+///
+/// This class implements double (indirectly through JSNumber) since in
+/// JavaScript all numbers are doubles, so while we want to treat `2.0` as an
+/// integer for some operations, its interceptor should answer `true` to `is
+/// double`.
+class JSInt extends JSNumber implements int {
+  const JSInt();
+
+  @override
+  // Use invoke_dynamic_specializer instead of inlining.
+  @pragma('dart2js:noInline')
+  JSInt abs() => JS(
+      'returns:int;effects:none;depends:none;throws:never;gvn:true',
+      r'Math.abs(#)',
+      this);
+
+  @override
+  JSInt get sign => this > 0 ? 1 : this < 0 ? -1 : this;
+
+  @override
+  JSInt operator -() => JS('int', r'-#', this);
+
+  bool get isEven => (this & 1) == 0;
+
+  bool get isOdd => (this & 1) == 1;
+
+  int toUnsigned(int width) {
+    return this & ((1 << width) - 1);
+  }
+
+  int toSigned(int width) {
+    int signMask = 1 << (width - 1);
+    return (this & (signMask - 1)) - (this & signMask);
+  }
+
+  int get bitLength {
+    JSInt nonneg = this < 0 ? -this - 1 : this;
+    int wordBits = 32;
+    while (nonneg >= 0x100000000) {
+      nonneg = nonneg ~/ 0x100000000;
+      wordBits += 32;
+    }
+    return wordBits - _clz32(nonneg);
+  }
+
+  static int _clz32(int uint32) {
+    // TODO(sra): Use `Math.clz32(uint32)` (not available on IE11).
+    return 32 - _bitCount(_spread(uint32));
+  }
+
+  // Returns pow(this, e) % m.
+  int modPow(int e, int m) {
+    if (e is! int) {
+      throw ArgumentError.value(e, 'exponent', 'not an integer');
+    }
+    if (m is! int) {
+      throw ArgumentError.value(m, 'modulus', 'not an integer');
+    }
+    if (e < 0) throw RangeError.range(e, 0, null, 'exponent');
+    if (m <= 0) throw RangeError.range(m, 1, null, 'modulus');
+    if (e == 0) return 1;
+
+    const int maxPreciseInteger = 9007199254740991;
+
+    // Reject inputs that are outside the range of integer values that can be
+    // represented precisely as a Number (double).
+    if (this < -maxPreciseInteger || this > maxPreciseInteger) {
+      throw RangeError.range(
+          this, -maxPreciseInteger, maxPreciseInteger, 'receiver');
+    }
+    if (e > maxPreciseInteger) {
+      throw RangeError.range(e, 0, maxPreciseInteger, 'exponent');
+    }
+    if (m > maxPreciseInteger) {
+      throw RangeError.range(e, 1, maxPreciseInteger, 'modulus');
+    }
+
+    // This is floor(sqrt(maxPreciseInteger)).
+    const int maxValueThatCanBeSquaredWithoutTruncation = 94906265;
+    if (m > maxValueThatCanBeSquaredWithoutTruncation) {
+      // Use BigInt version to avoid truncation in multiplications below. The
+      // 'maxPreciseInteger' check on [m] ensures that toInt() does not round.
+      return BigInt.from(this).modPow(BigInt.from(e), BigInt.from(m)).toInt();
+    }
+
+    int b = this;
+    if (b < 0 || b > m) {
+      b %= m;
+    }
+    int r = 1;
+    while (e > 0) {
+      if (e.isOdd) {
+        r = (r * b) % m;
+      }
+      e ~/= 2;
+      b = (b * b) % m;
+    }
+    return r;
+  }
+
+  // If inv is false, returns gcd(x, y).
+  // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1.
+  // If inv is true and gcd(x, y) != 1, throws Exception("Not coprime").
+  static int _binaryGcd(int x, int y, bool inv) {
+    int s = 1;
+    if (!inv) {
+      while (x.isEven && y.isEven) {
+        x ~/= 2;
+        y ~/= 2;
+        s *= 2;
+      }
+      if (y.isOdd) {
+        var t = x;
+        x = y;
+        y = t;
+      }
+    }
+    final bool ac = x.isEven;
+    int u = x;
+    int v = y;
+    int a = 1, b = 0, c = 0, d = 1;
+    do {
+      while (u.isEven) {
+        u ~/= 2;
+        if (ac) {
+          if (!a.isEven || !b.isEven) {
+            a += y;
+            b -= x;
+          }
+          a ~/= 2;
+        } else if (!b.isEven) {
+          b -= x;
+        }
+        b ~/= 2;
+      }
+      while (v.isEven) {
+        v ~/= 2;
+        if (ac) {
+          if (!c.isEven || !d.isEven) {
+            c += y;
+            d -= x;
+          }
+          c ~/= 2;
+        } else if (!d.isEven) {
+          d -= x;
+        }
+        d ~/= 2;
+      }
+      if (u >= v) {
+        u -= v;
+        if (ac) a -= c;
+        b -= d;
+      } else {
+        v -= u;
+        if (ac) c -= a;
+        d -= b;
+      }
+    } while (u != 0);
+    if (!inv) return s * v;
+    if (v != 1) throw new Exception('Not coprime');
+    if (d < 0) {
+      d += x;
+      if (d < 0) d += x;
+    } else if (d > x) {
+      d -= x;
+      if (d > x) d -= x;
+    }
+    return d;
+  }
+
+  // Returns 1/this % m, with m > 0.
+  int modInverse(int m) {
+    if (m is! int) {
+      throw new ArgumentError.value(m, 'modulus', 'not an integer');
+    }
+    if (m <= 0) throw new RangeError.range(m, 1, null, 'modulus');
+    if (m == 1) return 0;
+    int t = this;
+    if ((t < 0) || (t >= m)) t %= m;
+    if (t == 1) return 1;
+    if ((t == 0) || (t.isEven && m.isEven)) {
+      throw new Exception('Not coprime');
+    }
+    return _binaryGcd(m, t, true);
+  }
+
+  // Returns gcd of abs(this) and abs(other).
+  int gcd(int other) {
+    if (other is! int) {
+      throw new ArgumentError.value(other, 'other', 'not an integer');
+    }
+    int x = this.abs();
+    int y = other.abs();
+    if (x == 0) return y;
+    if (y == 0) return x;
+    if ((x == 1) || (y == 1)) return 1;
+    return _binaryGcd(x, y, false);
+  }
+
+  // Assumes i is <= 32-bit and unsigned.
+  static int _bitCount(int i) {
+    // See "Hacker's Delight", section 5-1, "Counting 1-Bits".
+
+    // The basic strategy is to use "divide and conquer" to
+    // add pairs (then quads, etc.) of bits together to obtain
+    // sub-counts.
+    //
+    // A straightforward approach would look like:
+    //
+    // i = (i & 0x55555555) + ((i >>  1) & 0x55555555);
+    // i = (i & 0x33333333) + ((i >>  2) & 0x33333333);
+    // i = (i & 0x0F0F0F0F) + ((i >>  4) & 0x0F0F0F0F);
+    // i = (i & 0x00FF00FF) + ((i >>  8) & 0x00FF00FF);
+    // i = (i & 0x0000FFFF) + ((i >> 16) & 0x0000FFFF);
+    //
+    // The code below removes unnecessary &'s and uses a
+    // trick to remove one instruction in the first line.
+
+    i = _shru(i, 0) - (_shru(i, 1) & 0x55555555);
+    i = (i & 0x33333333) + (_shru(i, 2) & 0x33333333);
+    i = 0x0F0F0F0F & (i + _shru(i, 4));
+    i += _shru(i, 8);
+    i += _shru(i, 16);
+    return (i & 0x0000003F);
+  }
+
+  static int _shru(int value, int shift) => JS('int', '# >>> #', value, shift);
+  static int _shrs(int value, int shift) => JS('int', '# >> #', value, shift);
+  static int _ors(int a, int b) => JS('int', '# | #', a, b);
+
+  // Assumes i is <= 32-bit
+  static int _spread(int i) {
+    i = _ors(i, _shrs(i, 1));
+    i = _ors(i, _shrs(i, 2));
+    i = _ors(i, _shrs(i, 4));
+    i = _ors(i, _shrs(i, 8));
+    i = _shru(_ors(i, _shrs(i, 16)), 0);
+    return i;
+  }
+
+  Type get runtimeType => int;
+
+  int operator ~() => JS('JSUInt32', r'(~#) >>> 0', this);
+}
+
+class JSDouble extends JSNumber implements double {
+  const JSDouble();
+  Type get runtimeType => double;
+}
+
+class JSPositiveInt extends JSInt {}
+
+class JSUInt32 extends JSPositiveInt {}
+
+class JSUInt31 extends JSUInt32 {}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_primitives.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_primitives.dart
new file mode 100644
index 0000000..97577a0
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_primitives.dart
@@ -0,0 +1,47 @@
+// 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.
+
+/// dart2js "primitives", that is, features that cannot be implemented without
+/// access to JavaScript features.
+library dart2js._js_primitives;
+
+import 'dart:_foreign_helper' show JS;
+
+/// This is the low-level method that is used to implement [print].  It is
+/// possible to override this function from JavaScript by defining a function in
+/// JavaScript called "dartPrint".
+///
+/// Notice that it is also possible to intercept calls to [print] from within a
+/// Dart program using zones. This means that there is no guarantee that a call
+/// to print ends in this method.
+void printString(String string) {
+  if (JS('bool', r'typeof dartPrint == "function"')) {
+    // Support overriding print from JavaScript.
+    JS('void', r'dartPrint(#)', string);
+    return;
+  }
+
+  // Inside browser or nodejs.
+  if (JS('bool', r'typeof console == "object"') &&
+      JS('bool', r'typeof console.log != "undefined"')) {
+    JS('void', r'console.log(#)', string);
+    return;
+  }
+
+  // Don't throw inside IE, the console is only defined if dev tools is open.
+  if (JS('bool', r'typeof window == "object"')) {
+    return;
+  }
+
+  // Running in d8, the V8 developer shell, or in Firefox' js-shell.
+  if (JS('bool', r'typeof print == "function"')) {
+    JS('void', r'print(#)', string);
+    return;
+  }
+
+  // This is somewhat nasty, but we don't want to drag in a bunch of
+  // dependencies to handle a situation that cannot happen. So we
+  // avoid using Dart [:throw:] and Dart [toString].
+  JS('void', 'throw "Unable to print message: " + String(#)', string);
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart
new file mode 100644
index 0000000..fd82931
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart
@@ -0,0 +1,1125 @@
+// 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 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 JavaScript array: the first entry is of type 1 and contains the
+///     subtyping flags and the substitution of the type and the rest of the
+///     array are the type arguments.
+///  3) `null`: the dynamic type.
+///  4) a JavaScript object representing the function type. For instance, it has
+///     the form {ret: rti, args: [rti], opt: [rti], named: {name: rti}} for a
+///     function with a return type, regular, optional and named arguments.
+///     Generic function types have a 'bounds' property.
+///
+/// To check subtype relations between generic classes we use a JavaScript
+/// expression that describes the necessary substitution for type arguments.
+/// Such a substitution expression 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. The function may also return null, which is equivalent
+///     to an array containing only null values.
+
+part of _js_helper;
+
+/// Called from generated code.
+Type createRuntimeType(rti) {
+  return new TypeImpl(rti);
+}
+
+class TypeImpl implements Type {
+  final dynamic _rti;
+  String __typeName;
+  String _unmangledName;
+  int _hashCode;
+
+  TypeImpl(this._rti);
+
+  String get _typeName => __typeName ??= runtimeTypeToString(_rti);
+
+  String toString() => _typeName;
+
+  // TODO(ahe): This is a poor hashCode as it collides with its name.
+  int get hashCode => _hashCode ??= _typeName.hashCode;
+
+  @pragma('dart2js:noInline')
+  bool operator ==(other) {
+    return (other is TypeImpl) && _typeName == other._typeName;
+  }
+}
+
+/// Represents a type variable.
+///
+/// This class holds the information needed when reflecting on generic classes
+/// and their members.
+class TypeVariable {
+  final Type owner;
+  final String name;
+  final int bound;
+
+  const TypeVariable(this.owner, this.name, this.bound);
+}
+
+getMangledTypeName(Type t) {
+  TypeImpl type = t;
+  return type._typeName;
+}
+
+/// Sets the runtime type information on [target]. [rti] is a type
+/// representation of type 4 or 5, that is, either a JavaScript array or `null`.
+///
+/// Called from generated code.
+///
+/// This is used only for marking JavaScript Arrays (JSArray) with the element
+/// type.
+// Don't inline.  Let the JS engine inline this.  The call expression is much
+// more compact that the inlined expansion.
+@pragma('dart2js:noInline')
+Object setRuntimeTypeInfo(Object target, var rti) {
+  assert(rti == null || isJsArray(rti));
+  String rtiName = JS_GET_NAME(JsGetName.RTI_NAME);
+  JS('var', r'#[#] = #', target, rtiName, rti);
+  return target;
+}
+
+/// Returns the runtime type information of [target]. The returned value is a
+/// list of type representations for the type arguments.
+///
+/// Called from generated code.
+getRuntimeTypeInfo(Object target) {
+  if (target == null) return null;
+  String rtiName = JS_GET_NAME(JsGetName.RTI_NAME);
+  return JS('var', r'#[#]', target, rtiName);
+}
+
+/// Returns the type arguments of [object] as an instance of [substitutionName].
+getRuntimeTypeArguments(interceptor, object, substitutionName) {
+  var substitution = getField(interceptor,
+      '${JS_GET_NAME(JsGetName.OPERATOR_AS_PREFIX)}$substitutionName');
+  return substitute(substitution, getRuntimeTypeInfo(object));
+}
+
+/// Returns the [index]th type argument of [target] as an instance of
+/// [substitutionName].
+///
+/// Called from generated code.
+@pragma('dart2js:noThrows')
+@pragma('dart2js:noSideEffects')
+@pragma('dart2js:noInline')
+getRuntimeTypeArgumentIntercepted(
+    interceptor, Object target, String substitutionName, int index) {
+  var arguments =
+      getRuntimeTypeArguments(interceptor, target, substitutionName);
+  return arguments == null ? null : getIndex(arguments, index);
+}
+
+/// Returns the [index]th type argument of [target] as an instance of
+/// [substitutionName].
+///
+/// Called from generated code.
+@pragma('dart2js:noThrows')
+@pragma('dart2js:noSideEffects')
+@pragma('dart2js:noInline')
+getRuntimeTypeArgument(Object target, String substitutionName, int index) {
+  var arguments = getRuntimeTypeArguments(target, target, substitutionName);
+  return arguments == null ? null : getIndex(arguments, index);
+}
+
+/// Returns the [index]th type argument of [target].
+///
+/// Called from generated code.
+@pragma('dart2js:noThrows')
+@pragma('dart2js:noSideEffects')
+@pragma('dart2js:noInline')
+getTypeArgumentByIndex(Object target, int index) {
+  var rti = getRuntimeTypeInfo(target);
+  return rti == null ? null : getIndex(rti, index);
+}
+
+/// Retrieves the class name from type information stored on the constructor
+/// of [object].
+String getClassName(var object) {
+  return rawRtiToJsConstructorName(getRawRuntimeType(getInterceptor(object)));
+}
+
+String _getRuntimeTypeAsString(var rti, List<String> genericContext) {
+  assert(isJsArray(rti));
+  String className = unminifyOrTag(rawRtiToJsConstructorName(getIndex(rti, 0)));
+  return '$className${_joinArguments(rti, 1, genericContext)}';
+}
+
+/// Returns a human-readable representation of the type representation [rti].
+///
+/// Called from generated code.
+@pragma('dart2js:noInline')
+String runtimeTypeToString(var rti) {
+  return _runtimeTypeToString(rti, null);
+}
+
+String _runtimeTypeToString(var rti, List<String> genericContext) {
+  if (isDartDynamicTypeRti(rti)) {
+    return 'dynamic';
+  }
+  if (isDartVoidTypeRti(rti)) {
+    return 'void';
+  }
+  if (isJsArray(rti)) {
+    // A list representing a type with arguments.
+    return _getRuntimeTypeAsString(rti, genericContext);
+  }
+  if (isJsFunction(rti)) {
+    // A reference to the constructor.
+    return unminifyOrTag(rawRtiToJsConstructorName(rti));
+  }
+  if (isDartJsInteropTypeArgumentRti(rti)) {
+    return 'dynamic';
+  }
+  if (isGenericFunctionTypeParameter(rti)) {
+    int index = rti;
+    if (genericContext == null || index < 0 || index >= genericContext.length) {
+      return 'unexpected-generic-index:${index}';
+    }
+    return '${genericContext[genericContext.length - index - 1]}';
+  }
+  if (isDartFunctionType(rti)) {
+    // TODO(sra): If there is a typedef tag, use the typedef name.
+    return _functionRtiToString(rti, genericContext);
+  }
+  if (isDartFutureOrType(rti)) {
+    var typeArgument = getFutureOrArgument(rti);
+    return 'FutureOr<${_runtimeTypeToString(typeArgument, genericContext)}>';
+  }
+  // We should not get here.
+  return 'unknown-reified-type';
+}
+
+// Returns a formatted String version of a function type.
+//
+// [genericContext] is list of the names of generic type parameters for generic
+// function types. The de Bruijn indexing scheme references the type variables
+// from the inner scope out. The parameters for each scope are pushed in
+// reverse, e.g.  `<P,Q>(<R,S,T>(R))` creates the list `[Q,P,T,S,R]`. This
+// allows the de Bruijn index to simply index backwards from the end of
+// [genericContext], e.g. in the outer scope index `0` is P and `1` is Q, and in
+// the inner scope index `0` is R, `3` is P, and `4` is Q.
+//
+// [genericContext] is initially `null`.
+String _functionRtiToString(var rti, List<String> genericContext) {
+  String typeParameters = '';
+  int outerContextLength;
+
+  String boundsTag = JS_GET_NAME(JsGetName.FUNCTION_TYPE_GENERIC_BOUNDS_TAG);
+  if (hasField(rti, boundsTag)) {
+    List boundsRti = JS('JSFixedArray', '#[#]', rti, boundsTag);
+    if (genericContext == null) {
+      genericContext = <String>[];
+    } else {
+      outerContextLength = genericContext.length;
+    }
+    int offset = genericContext.length;
+    for (int i = boundsRti.length; i > 0; i--) {
+      genericContext.add('T${offset + i}');
+    }
+    // All variables are in scope in the bounds.
+    String typeSep = '';
+    typeParameters = '<';
+    for (int i = 0; i < boundsRti.length; i++) {
+      typeParameters += typeSep;
+      typeParameters += genericContext[genericContext.length - i - 1];
+      typeSep = ', ';
+      var boundRti = boundsRti[i];
+      if (isInterestingBound(boundRti)) {
+        typeParameters +=
+            ' extends ' + _runtimeTypeToString(boundRti, genericContext);
+      }
+    }
+    typeParameters += '>';
+  }
+
+  String returnTypeText;
+  String voidTag = JS_GET_NAME(JsGetName.FUNCTION_TYPE_VOID_RETURN_TAG);
+  if (JS('bool', '!!#[#]', rti, voidTag)) {
+    returnTypeText = 'void';
+  } else {
+    String returnTypeTag = JS_GET_NAME(JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG);
+    var returnRti = JS('', '#[#]', rti, returnTypeTag);
+    returnTypeText = _runtimeTypeToString(returnRti, genericContext);
+  }
+
+  String argumentsText = '';
+  String sep = '';
+
+  String requiredParamsTag =
+      JS_GET_NAME(JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG);
+  if (hasField(rti, requiredParamsTag)) {
+    List arguments = JS('JSFixedArray', '#[#]', rti, requiredParamsTag);
+    for (var argument in arguments) {
+      argumentsText += sep;
+      argumentsText += _runtimeTypeToString(argument, genericContext);
+      sep = ', ';
+    }
+  }
+
+  String optionalParamsTag =
+      JS_GET_NAME(JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG);
+  bool hasOptionalArguments = JS('bool', '# in #', optionalParamsTag, rti);
+  if (hasOptionalArguments) {
+    List optionalArguments = JS('JSFixedArray', '#[#]', rti, optionalParamsTag);
+    argumentsText += '$sep[';
+    sep = '';
+    for (var argument in optionalArguments) {
+      argumentsText += sep;
+      argumentsText += _runtimeTypeToString(argument, genericContext);
+      sep = ', ';
+    }
+    argumentsText += ']';
+  }
+
+  String namedParamsTag =
+      JS_GET_NAME(JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG);
+  bool hasNamedArguments = JS('bool', '# in #', namedParamsTag, rti);
+  if (hasNamedArguments) {
+    var namedArguments = JS('', '#[#]', rti, namedParamsTag);
+    argumentsText += '$sep{';
+    sep = '';
+    for (String name in extractKeys(namedArguments)) {
+      argumentsText += sep;
+      argumentsText += _runtimeTypeToString(
+          JS('', '#[#]', namedArguments, name), genericContext);
+      argumentsText += ' $name';
+      sep = ', ';
+    }
+    argumentsText += '}';
+  }
+
+  if (outerContextLength != null) {
+    // Pop all of the generic type parameters.
+    JS('', '#.length = #', genericContext, outerContextLength);
+  }
+
+  // TODO(sra): Below is the same format as the VM. Change to:
+  //
+  //     return '${returnTypeText} Function${typeParameters}(${argumentsText})';
+  //
+  return '${typeParameters}(${argumentsText}) => ${returnTypeText}';
+}
+
+/// 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) {
+  return _joinArguments(types, startIndex, null);
+}
+
+String _joinArguments(var types, int startIndex, List<String> genericContext) {
+  if (types == null) return '';
+  assert(isJsArray(types));
+  var separator = '';
+  bool allDynamic = true;
+  StringBuffer buffer = new StringBuffer('');
+  for (int index = startIndex; index < getLength(types); index++) {
+    buffer.write(separator);
+    separator = ', ';
+    var argument = getIndex(types, index);
+    if (argument != null) {
+      allDynamic = false;
+    }
+    buffer.write(_runtimeTypeToString(argument, genericContext));
+  }
+  return '<$buffer>';
+}
+
+/// Returns a human-readable representation of the type of [object].
+///
+/// In minified mode does *not* use unminified identifiers (even when present).
+String getRuntimeTypeString(var object) {
+  if (object is Closure) {
+    // This excludes classes that implement Function via a `call` method, but
+    // includes classes generated to represent closures in closure conversion.
+    var functionRti = extractFunctionTypeObjectFrom(object);
+    if (functionRti != null) {
+      return runtimeTypeToString(functionRti);
+    }
+  }
+  String className = getClassName(object);
+  if (object == null) return className;
+  String rtiName = JS_GET_NAME(JsGetName.RTI_NAME);
+  var rti = JS('var', r'#[#]', object, rtiName);
+  return "$className${joinArguments(rti, 0)}";
+}
+
+/// Returns the full type of [o] in the runtime type representation.
+getRti(o) {
+  if (o is Closure) {
+    // This excludes classes that implement Function via a `call` method, but
+    // includes classes generated to represent closures in closure conversion.
+    var functionRti = extractFunctionTypeObjectFrom(o);
+    if (functionRti != null) return functionRti;
+  }
+  var interceptor = getInterceptor(o);
+  var type = getRawRuntimeType(interceptor);
+  if (o == null) return type;
+  if (JS('bool', 'typeof # != "object"', o)) return type;
+  var rti = getRuntimeTypeInfo(o);
+  if (rti != null) {
+    // 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.
+    rti = JS('JSExtendableArray', '#.slice()', rti); // Make a copy.
+    JS('', '#.splice(0, 0, #)', rti, type); // Insert type at position 0.
+    type = rti;
+  }
+  return type;
+}
+
+Type getRuntimeType(var object) {
+  if (JS_GET_FLAG('USE_NEW_RTI')) return newRti.getRuntimeType(object);
+  return new TypeImpl(getRti(object));
+}
+
+/// 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 == null) return arguments;
+  assert(isJsFunction(substitution));
+  assert(arguments == null || isJsArray(arguments));
+  substitution = invoke(substitution, arguments);
+  if (substitution == null) return null;
+  if (isJsArray(substitution)) {
+    // Substitutions are generated too late to mark Array as used, so use a
+    // tautological JS 'cast' to mark Array as used. This is needed only in
+    // some tiny tests where the substition is the only thing that creates an
+    // Array.
+    return JS('JSArray', '#', substitution);
+  }
+  if (isJsFunction(substitution)) {
+    // TODO(johnniwinther): Check if this is still needed.
+    return invoke(substitution, arguments);
+  }
+  return arguments;
+}
+
+/// Perform a type check with arguments on the Dart object [object].
+///
+/// Parameters:
+/// - [isField]: the name of the flag/function to check if the object
+///   is of the correct class.
+/// - [checks]: the (JavaScript) list of type representations for the
+///   arguments to check against.
+/// - [asField]: the name of the function that transforms the type
+///   arguments of [objects] to an instance of the class that we check
+///   against.
+bool checkSubtype(Object object, String isField, List checks, String asField) {
+  if (object == null) return false;
+  var arguments = getRuntimeTypeInfo(object);
+  // Interceptor is needed for JSArray and native classes.
+  // TODO(sra): It could be a more specialized interceptor since [object] is not
+  // `null` or a primitive.
+  var interceptor = getInterceptor(object);
+  var isSubclass = getField(interceptor, isField);
+  // When we read the field and it is not there, [isSubclass] will be `null`.
+  if (isSubclass == null) return false;
+  // Should the asField function be passed the receiver?
+  var substitution = getField(interceptor, asField);
+  return checkArguments(substitution, arguments, null, checks, null);
+}
+
+/// Returns the field's type name.
+///
+/// In minified mode, uses the unminified names if available.
+String computeTypeName(String isField, List arguments) {
+  // Extract the class name from the is field and append the textual
+  // representation of the type arguments.
+  return Primitives.formatType(
+      unminifyOrTag(isCheckPropertyToJsConstructorName(isField)), arguments);
+}
+
+/// Called from generated code.
+Object subtypeCast(Object object, String isField, List checks, String asField) {
+  if (object == null) return object;
+  if (checkSubtype(object, isField, checks, asField)) return object;
+  String typeName = computeTypeName(isField, checks);
+  throw new CastErrorImplementation(object, typeName);
+}
+
+/// Called from generated code.
+Object assertSubtype(
+    Object object, String isField, List checks, String asField) {
+  if (object == null) return object;
+  if (checkSubtype(object, isField, checks, asField)) return object;
+  String typeName = computeTypeName(isField, checks);
+  throw new TypeErrorImplementation(object, typeName);
+}
+
+/// Checks that the type represented by [subtype] is a subtype of [supertype].
+/// If not a type error is thrown using [prefix], [infix], [suffix] and the
+/// runtime types [subtype] and [supertype] to generate the error message.
+///
+/// Called from generated code.
+assertIsSubtype(
+    var subtype, var supertype, String prefix, String infix, String suffix) {
+  if (!isSubtype(subtype, supertype)) {
+    String message = "TypeError: "
+        "$prefix${runtimeTypeToString(subtype)}$infix"
+        "${runtimeTypeToString(supertype)}$suffix";
+    throwTypeError(message);
+  }
+}
+
+throwTypeError(message) {
+  throw new TypeErrorImplementation.fromMessage(message);
+}
+
+bool checkArguments(
+    var substitution, var arguments, var sEnv, var checks, var tEnv) {
+  return areSubtypes(substitute(substitution, arguments), sEnv, checks, tEnv);
+}
+
+/// 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 sEnv, var t, var tEnv) {
+  // `null` means a raw type.
+  if (t == null) return true;
+  if (s == null) {
+    int len = getLength(t);
+    for (int i = 0; i < len; i++) {
+      if (!_isSubtype(null, null, getIndex(t, i), tEnv)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  assert(isJsArray(s));
+  assert(isJsArray(t));
+  assert(getLength(s) == getLength(t));
+
+  int len = getLength(s);
+  for (int i = 0; i < len; i++) {
+    if (!_isSubtype(getIndex(s, i), sEnv, getIndex(t, i), tEnv)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+/// 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 interceptor = getInterceptor(context);
+  var typeArguments =
+      getRuntimeTypeArguments(interceptor, context, contextName);
+  return invokeOn(signature, context, typeArguments);
+}
+
+/// Returns `true` if the runtime type representation [type] is a top type.
+/// That is, either `dynamic`, `void` or `Object`.
+@pragma('dart2js:tryInline')
+bool isTopType(var type) {
+  return isDartDynamicTypeRti(type) ||
+      isDartVoidTypeRti(type) ||
+      isDartObjectTypeRti(type) ||
+      isDartJsInteropTypeArgumentRti(type);
+}
+
+/// Returns `true` if the runtime type representation [type] is a supertype of
+/// [Null].
+@pragma('dart2js:tryInline')
+bool isSupertypeOfNull(var type) {
+  return isSupertypeOfNullBase(type) || isSupertypeOfNullRecursive(type);
+}
+
+/// Returns `true` if the runtime type representation [type] is a simple
+/// supertype of [Null].
+///
+/// This method doesn't handle `FutureOr<Null>`. This is handle by
+/// [isSupertypeOfNullRecursive] because it requires a recursive check.
+@pragma('dart2js:tryInline')
+bool isSupertypeOfNullBase(var type) {
+  return isDartDynamicTypeRti(type) ||
+      isDartObjectTypeRti(type) ||
+      isNullTypeRti(type) ||
+      isDartVoidTypeRti(type) ||
+      isDartJsInteropTypeArgumentRti(type);
+}
+
+/// Returns `true` if the runtime type representation [type] is a `FutureOr`
+/// type that is a supertype of [Null].
+///
+/// This method is recursive to be able to handle both `FutureOr<Null>` and
+/// `FutureOr<FutureOr<Null>>` etc.
+bool isSupertypeOfNullRecursive(var type) {
+  if (isGenericFunctionTypeParameter(type)) {
+    // We need to check for function type variables because `isDartFutureOrType`
+    // doesn't work on numbers.
+    return false;
+  }
+  if (isDartFutureOrType(type)) {
+    var typeArgument = getFutureOrArgument(type);
+    return isSupertypeOfNullBase(type) ||
+        isSupertypeOfNullRecursive(typeArgument);
+  }
+  return false;
+}
+
+/// Returns the type argument of the `FutureOr` runtime type representation
+/// [type].
+///
+/// For instance `num` of `FutureOr<num>`.
+@pragma('dart2js:tryInline')
+Object getFutureOrArgument(var type) {
+  assert(isDartFutureOrType(type));
+  var typeArgumentTag = JS_GET_NAME(JsGetName.FUTURE_OR_TYPE_ARGUMENT_TAG);
+  return hasField(type, typeArgumentTag)
+      ? getField(type, typeArgumentTag)
+      : null;
+}
+
+/// Tests whether the Dart object [o] is a subtype of the runtime type
+/// representation [t].
+///
+/// See the comment in the beginning of this file for a description of type
+/// representations.
+bool checkSubtypeOfRuntimeType(o, t) {
+  if (o == null) return isSupertypeOfNull(t);
+  if (isTopType(t)) return true;
+  if (JS('bool', 'typeof # == "object"', t)) {
+    if (isDartFutureOrType(t)) {
+      // `o is FutureOr<T>` is equivalent to
+      //
+      //     o is T || o is Future<T>
+      //
+      // T might be a function type, requiring extracting the closure's
+      // signature, so do the `o is T` check here and let the `Future` interface
+      // type test fall through to the `isSubtype` check at the end of this
+      // function.
+      var tTypeArgument = getFutureOrArgument(t);
+      if (checkSubtypeOfRuntimeType(o, tTypeArgument)) return true;
+    }
+
+    if (isDartFunctionType(t)) {
+      return functionTypeTest(o, t);
+    }
+  }
+
+  var interceptor = getInterceptor(o);
+  var type = getRawRuntimeType(interceptor);
+  var rti = getRuntimeTypeInfo(o);
+  if (rti != null) {
+    // 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.
+    rti = JS('JSExtendableArray', '#.slice()', rti); // Make a copy.
+    JS('', '#.splice(0, 0, #)', rti, type); // Insert type at position 0.
+    type = rti;
+  }
+  return isSubtype(type, t);
+}
+
+/// Called from generated code.
+Object subtypeOfRuntimeTypeCast(Object object, var type) {
+  if (object != null && !checkSubtypeOfRuntimeType(object, type)) {
+    throw new CastErrorImplementation(object, runtimeTypeToString(type));
+  }
+  return object;
+}
+
+/// Called from generated code.
+Object assertSubtypeOfRuntimeType(Object object, var type) {
+  if (object != null && !checkSubtypeOfRuntimeType(object, type)) {
+    throw new TypeErrorImplementation(object, runtimeTypeToString(type));
+  }
+  return object;
+}
+
+/// 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].
+///
+/// See the comment in the beginning of this file for a description of type
+/// representations.
+///
+/// The arguments [s] and [t] must be types, usually represented by the
+/// constructor of the class, or an array (for generic class types).
+bool isSubtype(var s, var t) {
+  return _isSubtype(s, null, t, null);
+}
+
+bool _isSubtype(var s, var sEnv, var t, var tEnv) {
+  // Subtyping is reflexive.
+  if (isIdentical(s, t)) return true;
+
+  // [t] is a top type?
+  if (isTopType(t)) return true;
+
+  if (isDartJsInteropTypeArgumentRti(s)) return true;
+
+  // [s] is a top type?
+  if (isTopType(s)) {
+    if (isGenericFunctionTypeParameter(t)) {
+      // We need to check for function type variables because
+      // `isDartFutureOrType` doesn't work on numbers.
+      return false;
+    }
+    if (isDartFutureOrType(t)) {
+      // [t] is FutureOr<T>. Check [s] <: T.
+      var tTypeArgument = getFutureOrArgument(t);
+      return _isSubtype(s, sEnv, tTypeArgument, tEnv);
+    }
+    return false;
+  }
+
+  // Generic function type parameters must match exactly, which would have
+  // exited earlier. The de Bruijn indexing ensures the representation as a
+  // small number can be used for type comparison.
+  if (isGenericFunctionTypeParameter(s)) {
+    // TODO(sra): Use the bound of the type variable.
+    return false;
+  }
+  if (isGenericFunctionTypeParameter(t)) return false;
+
+  if (isNullType(s)) return true;
+
+  // Get the object describing the class and check for the subtyping flag
+  // constructed from the type of [s].
+  var typeOfS = isJsArray(s) ? getIndex(s, 0) : s;
+
+  if (isDartFutureOrType(t)) {
+    // [t] is FutureOr<T>
+    var tTypeArgument = getFutureOrArgument(t);
+    if (isDartFutureOrType(s)) {
+      // [S] is FutureOr<S>. Check S <: T
+      var sTypeArgument = getFutureOrArgument(s);
+      return _isSubtype(sTypeArgument, sEnv, tTypeArgument, tEnv);
+    } else if (_isSubtype(s, sEnv, tTypeArgument, tEnv)) {
+      // `true` because [s] <: T.
+      return true;
+    } else {
+      // Check [s] <: Future<T>.
+      String futureClass = JS_GET_NAME(JsGetName.FUTURE_CLASS_TYPE_NAME);
+      if (!builtinIsSubtype(typeOfS, futureClass)) {
+        // [s] doesn't implement Future.
+        return false;
+      }
+      var typeOfSPrototype = JS('', '#.prototype', typeOfS);
+      var field = '${JS_GET_NAME(JsGetName.OPERATOR_AS_PREFIX)}${futureClass}';
+      var futureSubstitution = getField(typeOfSPrototype, field);
+      var futureArguments = substitute(futureSubstitution, getArguments(s));
+      var futureArgument =
+          isJsArray(futureArguments) ? getIndex(futureArguments, 0) : null;
+      // [s] implements Future<S>. Check S <: T.
+      return _isSubtype(futureArgument, sEnv, tTypeArgument, tEnv);
+    }
+  }
+
+  if (isDartFunctionType(t)) {
+    return _isFunctionSubtype(s, sEnv, t, tEnv);
+  }
+
+  if (isDartFunctionType(s)) {
+    // Check function types against the `Function` class (`Object` is also a
+    // supertype, but is tested above with other 'top' types.).
+    return isDartFunctionTypeRti(t);
+  }
+
+  // Get the object describing the class and check for the subtyping flag
+  // constructed from the type of [t].
+  var typeOfT = isJsArray(t) ? getIndex(t, 0) : t;
+
+  // Check for a subtyping flag.
+  // Get the necessary substitution of the type arguments, if there is one.
+  var substitution;
+  if (isNotIdentical(typeOfT, typeOfS)) {
+    String typeOfTString = rawRtiToJsConstructorName(typeOfT);
+    if (!builtinIsSubtype(typeOfS, typeOfTString)) {
+      return false;
+    }
+    var typeOfSPrototype = JS('', '#.prototype', typeOfS);
+    var field = '${JS_GET_NAME(JsGetName.OPERATOR_AS_PREFIX)}${typeOfTString}';
+    substitution = getField(typeOfSPrototype, field);
+  }
+  // The class of [s] is a subclass of the class of [t]. If [t] has no
+  // type arguments, it used as a raw type and [s] is a subtype of [t].
+  if (!isJsArray(t)) {
+    return true;
+  }
+  // Recursively check the type arguments.
+  return checkArguments(
+      substitution, getArguments(s), sEnv, getArguments(t), tEnv);
+}
+
+/// Top-level function subtype check when [t] is known to be a function type
+/// rti.
+bool isFunctionSubtype(var s, var t) {
+  return _isFunctionSubtype(s, null, t, null);
+}
+
+bool _isFunctionSubtype(var s, var sEnv, var t, var tEnv) {
+  assert(isDartFunctionType(t));
+  if (!isDartFunctionType(s)) return false;
+  var genericBoundsTag =
+      JS_GET_NAME(JsGetName.FUNCTION_TYPE_GENERIC_BOUNDS_TAG);
+  var voidReturnTag = JS_GET_NAME(JsGetName.FUNCTION_TYPE_VOID_RETURN_TAG);
+  var returnTypeTag = JS_GET_NAME(JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG);
+
+  // Generic function types must agree on number of type parameters and bounds.
+  if (hasField(s, genericBoundsTag)) {
+    if (hasNoField(t, genericBoundsTag)) return false;
+    var sBounds = getField(s, genericBoundsTag);
+    var tBounds = getField(t, genericBoundsTag);
+    int sGenericParameters = getLength(sBounds);
+    int tGenericParameters = getLength(tBounds);
+    if (sGenericParameters != tGenericParameters) return false;
+    // TODO(sra): Compare bounds, which should be 'equal' trees due to the de
+    // Bruijn numbering of type parameters.
+    // TODO(sra): Extend [sEnv] and [tEnv] with bindings for the [s] and [t]
+    // type parameters to enable checking the bound against non-type-parameter
+    // terms.
+  } else if (hasField(t, genericBoundsTag)) {
+    return false;
+  }
+
+  var sReturnType = getField(s, returnTypeTag);
+  var tReturnType = getField(t, returnTypeTag);
+  if (!_isSubtype(sReturnType, sEnv, tReturnType, tEnv)) return false;
+
+  var requiredParametersTag =
+      JS_GET_NAME(JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG);
+  var sParameterTypes = getField(s, requiredParametersTag);
+  var tParameterTypes = getField(t, requiredParametersTag);
+
+  var optionalParametersTag =
+      JS_GET_NAME(JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG);
+  var sOptionalParameterTypes = getField(s, optionalParametersTag);
+  var tOptionalParameterTypes = getField(t, optionalParametersTag);
+
+  int sParametersLen = sParameterTypes != null ? getLength(sParameterTypes) : 0;
+  int tParametersLen = tParameterTypes != null ? getLength(tParameterTypes) : 0;
+
+  int sOptionalParametersLen =
+      sOptionalParameterTypes != null ? getLength(sOptionalParameterTypes) : 0;
+  int tOptionalParametersLen =
+      tOptionalParameterTypes != null ? 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;
+  }
+
+  int pos = 0;
+  // Check all required parameters of [s].
+  for (; pos < sParametersLen; pos++) {
+    if (!_isSubtype(getIndex(tParameterTypes, pos), tEnv,
+        getIndex(sParameterTypes, pos), sEnv)) {
+      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 (!_isSubtype(getIndex(tParameterTypes, tPos), tEnv,
+        getIndex(sOptionalParameterTypes, sPos), sEnv)) {
+      return false;
+    }
+  }
+  tPos = 0;
+  // Check the optional parameters of [t] with the remaining optional
+  // parameters of [s]:
+  for (; tPos < tOptionalParametersLen; sPos++, tPos++) {
+    if (!_isSubtype(getIndex(tOptionalParameterTypes, tPos), tEnv,
+        getIndex(sOptionalParameterTypes, sPos), sEnv)) {
+      return false;
+    }
+  }
+
+  var namedParametersTag =
+      JS_GET_NAME(JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG);
+  var sNamedParameters = getField(s, namedParametersTag);
+  var tNamedParameters = getField(t, namedParametersTag);
+  if (tNamedParameters == null) return true;
+  if (sNamedParameters == null) return false;
+  return namedParametersSubtypeCheck(
+      sNamedParameters, sEnv, tNamedParameters, tEnv);
+}
+
+bool namedParametersSubtypeCheck(var s, var sEnv, var t, var tEnv) {
+  assert(isJsObject(s));
+  assert(isJsObject(t));
+
+  // Each named parameter in [t] must exist in [s] and be a subtype of the type
+  // in [s].
+  List names = JS('JSFixedArray', 'Object.getOwnPropertyNames(#)', t);
+  for (int i = 0; i < names.length; i++) {
+    var name = names[i];
+    if (JS('bool', '!Object.hasOwnProperty.call(#, #)', s, name)) {
+      return false;
+    }
+    var tType = JS('', '#[#]', t, name);
+    var sType = JS('', '#[#]', s, name);
+    if (!_isSubtype(tType, tEnv, sType, sEnv)) return false;
+  }
+  return true;
+}
+
+/// Returns whether [type] is the representation of a generic function type
+/// parameter. Generic function type parameters are represented de Bruijn
+/// indexes.
+///
+/// This test is only valid if [type] is known _not_ to be the void rti, whose
+/// runtime representation is -1.
+bool isGenericFunctionTypeParameter(var type) {
+  assert(!isDartVoidTypeRti(type));
+  return type is num; // Actually int, but 'is num' is faster.
+}
+
+/// Returns [genericFunctionRti] with type parameters bound to [parameters].
+///
+/// [genericFunctionRti] must be an rti representation with a number of generic
+/// type parameters matching the number of types in [parameters].
+///
+/// Called from generated code.
+@pragma('dart2js:noInline')
+instantiatedGenericFunctionType(genericFunctionRti, parameters) {
+  if (genericFunctionRti == null) return null;
+
+  assert(isDartFunctionType(genericFunctionRti));
+
+  var genericBoundsTag =
+      JS_GET_NAME(JsGetName.FUNCTION_TYPE_GENERIC_BOUNDS_TAG);
+
+  assert(hasField(genericFunctionRti, genericBoundsTag));
+  var bounds = getField(genericFunctionRti, genericBoundsTag);
+
+  // Generic function types must agree on number of type parameters and bounds.
+  int boundLength = getLength(bounds);
+  int parametersLength = getLength(parameters);
+  assert(boundLength == parametersLength);
+
+  var result = JS('', '{#:1}', JS_GET_NAME(JsGetName.FUNCTION_TYPE_TAG));
+  return finishBindInstantiatedFunctionType(
+      genericFunctionRti, result, parameters, 0);
+}
+
+bindInstantiatedFunctionType(rti, parameters, int depth) {
+  var result = JS('', '{#:1}', JS_GET_NAME(JsGetName.FUNCTION_TYPE_TAG));
+
+  var genericBoundsTag =
+      JS_GET_NAME(JsGetName.FUNCTION_TYPE_GENERIC_BOUNDS_TAG);
+  if (hasField(rti, genericBoundsTag)) {
+    var bounds = getField(rti, genericBoundsTag);
+    depth += getLength(bounds);
+    setField(result, genericBoundsTag,
+        bindInstantiatedTypes(bounds, parameters, depth));
+  }
+
+  return finishBindInstantiatedFunctionType(rti, result, parameters, depth);
+}
+
+/// Common code for function types that copies all non-bounds parts of the
+/// function [rti] into [result].
+finishBindInstantiatedFunctionType(rti, result, parameters, int depth) {
+  var voidReturnTag = JS_GET_NAME(JsGetName.FUNCTION_TYPE_VOID_RETURN_TAG);
+  var returnTypeTag = JS_GET_NAME(JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG);
+
+  if (hasField(rti, voidReturnTag)) {
+    setField(result, voidReturnTag, getField(rti, voidReturnTag));
+  } else if (hasField(rti, returnTypeTag)) {
+    setField(result, returnTypeTag,
+        bindInstantiatedType(getField(rti, returnTypeTag), parameters, depth));
+  }
+
+  var requiredParametersTag =
+      JS_GET_NAME(JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG);
+  if (hasField(rti, requiredParametersTag)) {
+    setField(
+        result,
+        requiredParametersTag,
+        bindInstantiatedTypes(
+            getField(rti, requiredParametersTag), parameters, depth));
+  }
+
+  String optionalParametersTag =
+      JS_GET_NAME(JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG);
+  if (hasField(rti, optionalParametersTag)) {
+    setField(
+        result,
+        optionalParametersTag,
+        bindInstantiatedTypes(
+            getField(rti, optionalParametersTag), parameters, depth));
+  }
+
+  String namedParametersTag =
+      JS_GET_NAME(JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG);
+  if (hasField(rti, namedParametersTag)) {
+    var namedParameters = getField(rti, namedParametersTag);
+    var boundNamed = JS('', '{}');
+    var names = JS('JSFixedArray', 'Object.keys(#)', namedParameters);
+    for (var name in names) {
+      setField(
+          boundNamed,
+          name,
+          bindInstantiatedType(
+              getField(namedParameters, name), parameters, depth));
+    }
+    setField(result, namedParametersTag, boundNamed);
+  }
+
+  return result;
+}
+
+/// Copies [rti], substituting generic type parameters from [parameters].
+///
+/// Generic type parameters are de Bruijn indexes counting up through the
+/// generic function type parameters scopes to index into [parameters].
+///
+/// [depth] is the number of subsequent generic function parameters that are in
+/// scope. This is subtracted off the de Bruijn index for the type parameter to
+/// arrive at an potential index into [parameters].
+bindInstantiatedType(rti, parameters, int depth) {
+  if (isDartDynamicTypeRti(rti)) return rti; // dynamic.
+  if (isDartVoidTypeRti(rti)) return rti; // void.
+  // Functions are constructors denoting the class of the constructor.
+  if (isJsFunction(rti)) return rti;
+
+  // de Bruijn type indexes.
+  if (isGenericFunctionTypeParameter(rti)) {
+    if (rti < depth) return rti;
+    return JS('', '#[#]', parameters, rti - depth);
+  }
+  // Other things encoded as numbers.
+  if (rti is num) return rti;
+
+  if (isJsArray(rti)) {
+    // An array is a parameterized class type, e.g. the list of three
+    // constructor functions [Map, String, int] represents `Map<String, int>`.
+    // Since the 'head' of the term and the arguments are encoded in the same
+    // scheme, it is sufficient to walk all the types.
+    return bindInstantiatedTypes(rti, parameters, depth);
+  }
+  if (isDartFunctionType(rti)) {
+    return bindInstantiatedFunctionType(rti, parameters, depth);
+  }
+
+  // Can't include the bad [rti] since it is not a Dart value.
+  throw new ArgumentError('Unknown RTI format in bindInstantiatedType.');
+}
+
+/// Returns a copy of array [rti] with each type bound.
+bindInstantiatedTypes(rti, parameters, int depth) {
+  List array = JS('JSFixedArray', '#.slice()', rti);
+  for (int i = 0; i < array.length; i++) {
+    array[i] = bindInstantiatedType(array[i], parameters, depth);
+  }
+  return array;
+}
+
+/// 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(arguments == null || 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);
+}
+
+setField(var object, String name, var value) {
+  JS('', '#[#] = #', object, name, value);
+}
+
+setIndex(var array, int index, var value) {
+  JS('', '#[#] = #', array, index, value);
+}
+
+/// 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'# in #', name, object);
+
+hasNoField(var object, var name) => !hasField(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 the JavaScript values [s] and [t] are identical. We use
+/// this helper instead of [identical] because `identical` needs to merge
+/// `null` and `undefined` (which we can avoid).
+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 instead of [identical] because `identical` needs to merge
+/// `null` and `undefined` (which we can avoid).
+bool isNotIdentical(var s, var t) => JS('bool', '# !== #', s, t);
+
+/// 'Top' bounds are uninteresting: null/undefined and Object.
+bool isInterestingBound(rti) =>
+    rti != null &&
+    isNotIdentical(
+        rti,
+        JS_BUILTIN(
+            'depends:none;effects:none;', JsBuiltin.dartObjectConstructor));
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_string.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_string.dart
new file mode 100644
index 0000000..39370d7
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_string.dart
@@ -0,0 +1,470 @@
+// Copyright (c) 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 _interceptors;
+
+/// The interceptor class for [String]. The compiler recognizes this
+/// class as an interceptor, and changes references to [:this:] to
+/// actually use the receiver of the method, which is generated as an extra
+/// argument added to each member.
+class JSString extends Interceptor implements String, JSIndexable {
+  const JSString();
+
+  @pragma('dart2js:noInline')
+  int codeUnitAt(int index) {
+    if (index is! int) throw diagnoseIndexError(this, index);
+    if (index < 0) throw diagnoseIndexError(this, index);
+    return _codeUnitAt(index);
+  }
+
+  int _codeUnitAt(int index) {
+    if (index >= length) throw diagnoseIndexError(this, index);
+    return JS('JSUInt31', r'#.charCodeAt(#)', this, index);
+  }
+
+  Iterable<Match> allMatches(String string, [int start = 0]) {
+    checkString(string);
+    checkInt(start);
+    if (0 > start || start > string.length) {
+      throw new RangeError.range(start, 0, string.length);
+    }
+    return allMatchesInStringUnchecked(this, string, start);
+  }
+
+  Match matchAsPrefix(String string, [int start = 0]) {
+    if (start < 0 || start > string.length) {
+      throw new RangeError.range(start, 0, string.length);
+    }
+    if (start + this.length > string.length) return null;
+    // TODO(lrn): See if this can be optimized.
+    for (int i = 0; i < this.length; i++) {
+      if (string.codeUnitAt(start + i) != this.codeUnitAt(i)) {
+        return null;
+      }
+    }
+    return new StringMatch(start, string, this);
+  }
+
+  String operator +(String other) {
+    if (other is! String) throw new ArgumentError.value(other);
+    return JS('String', r'# + #', this, other);
+  }
+
+  bool endsWith(String other) {
+    checkString(other);
+    int otherLength = other.length;
+    if (otherLength > length) return false;
+    return other == substring(length - otherLength);
+  }
+
+  String replaceAll(Pattern from, String to) {
+    return stringReplaceAllUnchecked(this, from, checkString(to));
+  }
+
+  String replaceAllMapped(Pattern from, String convert(Match match)) {
+    return this.splitMapJoin(from, onMatch: convert);
+  }
+
+  String splitMapJoin(Pattern from,
+      {String onMatch(Match match), String onNonMatch(String nonMatch)}) {
+    return stringReplaceAllFuncUnchecked(this, from, onMatch, onNonMatch);
+  }
+
+  String replaceFirst(Pattern from, String to, [int startIndex = 0]) {
+    checkString(to);
+    checkInt(startIndex);
+    RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex");
+    return stringReplaceFirstUnchecked(this, from, to, startIndex);
+  }
+
+  String replaceFirstMapped(Pattern from, String replace(Match match),
+      [int startIndex = 0]) {
+    checkNull(replace);
+    checkInt(startIndex);
+    RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex");
+    return stringReplaceFirstMappedUnchecked(this, from, replace, startIndex);
+  }
+
+  List<String> split(Pattern pattern) {
+    checkNull(pattern);
+    if (pattern is String) {
+      return stringSplitUnchecked(this, pattern);
+    } else if (pattern is JSSyntaxRegExp && regExpCaptureCount(pattern) == 0) {
+      var re = regExpGetNative(pattern);
+      return stringSplitUnchecked(this, re);
+    } else {
+      return _defaultSplit(pattern);
+    }
+  }
+
+  String replaceRange(int start, int end, String replacement) {
+    checkString(replacement);
+    checkInt(start);
+    end = RangeError.checkValidRange(start, end, this.length);
+    checkInt(end);
+    return stringReplaceRangeUnchecked(this, start, end, replacement);
+  }
+
+  List<String> _defaultSplit(Pattern pattern) {
+    List<String> result = <String>[];
+    // End of most recent match. That is, start of next part to add to result.
+    int start = 0;
+    // Length of most recent match.
+    // Set >0, so no match on the empty string causes the result to be [""].
+    int length = 1;
+    for (var match in pattern.allMatches(this)) {
+      int matchStart = match.start;
+      int matchEnd = match.end;
+      length = matchEnd - matchStart;
+      if (length == 0 && start == matchStart) {
+        // An empty match right after another match is ignored.
+        // This includes an empty match at the start of the string.
+        continue;
+      }
+      int end = matchStart;
+      result.add(this.substring(start, end));
+      start = matchEnd;
+    }
+    if (start < this.length || length > 0) {
+      // An empty match at the end of the string does not cause a "" at the end.
+      // A non-empty match ending at the end of the string does add a "".
+      result.add(this.substring(start));
+    }
+    return result;
+  }
+
+  bool startsWith(Pattern pattern, [int index = 0]) {
+    checkInt(index);
+    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;
+      int endIndex = index + otherLength;
+      if (endIndex > length) return false;
+      return other == JS('String', r'#.substring(#, #)', this, index, endIndex);
+    }
+    return pattern.matchAsPrefix(this, index) != null;
+  }
+
+  String substring(int startIndex, [int endIndex]) {
+    checkInt(startIndex);
+    if (endIndex == null) endIndex = length;
+    checkInt(endIndex);
+    if (startIndex < 0) throw new RangeError.value(startIndex);
+    if (startIndex > endIndex) throw new RangeError.value(startIndex);
+    if (endIndex > length) throw new RangeError.value(endIndex);
+    return JS('String', r'#.substring(#, #)', this, startIndex, endIndex);
+  }
+
+  String toLowerCase() {
+    return JS('returns:String;effects:none;depends:none;throws:null(1)',
+        r'#.toLowerCase()', this);
+  }
+
+  String toUpperCase() {
+    return JS('returns:String;effects:none;depends:none;throws:null(1)',
+        r'#.toUpperCase()', this);
+  }
+
+  // Characters with Whitespace property (Unicode 6.3).
+  // 0009..000D    ; White_Space # Cc       <control-0009>..<control-000D>
+  // 0020          ; White_Space # Zs       SPACE
+  // 0085          ; White_Space # Cc       <control-0085>
+  // 00A0          ; White_Space # Zs       NO-BREAK SPACE
+  // 1680          ; White_Space # Zs       OGHAM SPACE MARK
+  // 2000..200A    ; White_Space # Zs       EN QUAD..HAIR SPACE
+  // 2028          ; White_Space # Zl       LINE SEPARATOR
+  // 2029          ; White_Space # Zp       PARAGRAPH SEPARATOR
+  // 202F          ; White_Space # Zs       NARROW NO-BREAK SPACE
+  // 205F          ; White_Space # Zs       MEDIUM MATHEMATICAL SPACE
+  // 3000          ; White_Space # Zs       IDEOGRAPHIC SPACE
+  //
+  // BOM: 0xFEFF
+  static bool _isWhitespace(int codeUnit) {
+    // Most codeUnits should be less than 256. Special case with a smaller
+    // switch.
+    if (codeUnit < 256) {
+      switch (codeUnit) {
+        case 0x09:
+        case 0x0A:
+        case 0x0B:
+        case 0x0C:
+        case 0x0D:
+        case 0x20:
+        case 0x85:
+        case 0xA0:
+          return true;
+        default:
+          return false;
+      }
+    }
+    switch (codeUnit) {
+      case 0x1680:
+      case 0x2000:
+      case 0x2001:
+      case 0x2002:
+      case 0x2003:
+      case 0x2004:
+      case 0x2005:
+      case 0x2006:
+      case 0x2007:
+      case 0x2008:
+      case 0x2009:
+      case 0x200A:
+      case 0x2028:
+      case 0x2029:
+      case 0x202F:
+      case 0x205F:
+      case 0x3000:
+      case 0xFEFF:
+        return true;
+      default:
+        return false;
+    }
+  }
+
+  /// Finds the index of the first non-whitespace character, or the
+  /// end of the string. Start looking at position [index].
+  static int _skipLeadingWhitespace(String string, int index) {
+    const int SPACE = 0x20;
+    const int CARRIAGE_RETURN = 0x0D;
+    while (index < string.length) {
+      int codeUnit = string.codeUnitAt(index);
+      if (codeUnit != SPACE &&
+          codeUnit != CARRIAGE_RETURN &&
+          !_isWhitespace(codeUnit)) {
+        break;
+      }
+      index++;
+    }
+    return index;
+  }
+
+  /// Finds the index after the last non-whitespace character, or 0.
+  /// Start looking at position [index - 1].
+  static int _skipTrailingWhitespace(String string, int index) {
+    const int SPACE = 0x20;
+    const int CARRIAGE_RETURN = 0x0D;
+    while (index > 0) {
+      int codeUnit = string.codeUnitAt(index - 1);
+      if (codeUnit != SPACE &&
+          codeUnit != CARRIAGE_RETURN &&
+          !_isWhitespace(codeUnit)) {
+        break;
+      }
+      index--;
+    }
+    return index;
+  }
+
+  // Dart2js can't use JavaScript trim directly,
+  // because JavaScript does not trim
+  // the NEXT LINE (NEL) character (0x85).
+  String trim() {
+    const int NEL = 0x85;
+
+    // Start by doing JS trim. Then check if it leaves a NEL at
+    // either end of the string.
+    String result = JS('String', '#.trim()', this);
+    if (result.length == 0) return result;
+    int firstCode = result.codeUnitAt(0);
+    int startIndex = 0;
+    if (firstCode == NEL) {
+      startIndex = _skipLeadingWhitespace(result, 1);
+      if (startIndex == result.length) return "";
+    }
+
+    int endIndex = result.length;
+    // We know that there is at least one character that is non-whitespace.
+    // Therefore we don't need to verify that endIndex > startIndex.
+    int lastCode = result.codeUnitAt(endIndex - 1);
+    if (lastCode == NEL) {
+      endIndex = _skipTrailingWhitespace(result, endIndex - 1);
+    }
+    if (startIndex == 0 && endIndex == result.length) return result;
+    return JS('String', r'#.substring(#, #)', result, startIndex, endIndex);
+  }
+
+  // Dart2js can't use JavaScript trimLeft directly,
+  // because it is not in ES5, so not every browser implements it,
+  // and because those that do will not trim the NEXT LINE character (0x85).
+  String trimLeft() {
+    const int NEL = 0x85;
+
+    // Start by doing JS trim. Then check if it leaves a NEL at
+    // the beginning of the string.
+    String result;
+    int startIndex = 0;
+    if (JS('bool', 'typeof #.trimLeft != "undefined"', this)) {
+      result = JS('String', '#.trimLeft()', this);
+      if (result.length == 0) return result;
+      int firstCode = result.codeUnitAt(0);
+      if (firstCode == NEL) {
+        startIndex = _skipLeadingWhitespace(result, 1);
+      }
+    } else {
+      result = this;
+      startIndex = _skipLeadingWhitespace(this, 0);
+    }
+    if (startIndex == 0) return result;
+    if (startIndex == result.length) return "";
+    return JS('String', r'#.substring(#)', result, startIndex);
+  }
+
+  // Dart2js can't use JavaScript trimRight directly,
+  // because it is not in ES5 and because JavaScript does not trim
+  // the NEXT LINE character (0x85).
+  String trimRight() {
+    const int NEL = 0x85;
+
+    // Start by doing JS trim. Then check if it leaves a NEL or BOM at
+    // the end of the string.
+    String result;
+    int endIndex;
+    // trimRight is implemented by Firefox and Chrome/Blink,
+    // so use it if it is there.
+    if (JS('bool', 'typeof #.trimRight != "undefined"', this)) {
+      result = JS('String', '#.trimRight()', this);
+      endIndex = result.length;
+      if (endIndex == 0) return result;
+      int lastCode = result.codeUnitAt(endIndex - 1);
+      if (lastCode == NEL) {
+        endIndex = _skipTrailingWhitespace(result, endIndex - 1);
+      }
+    } else {
+      result = this;
+      endIndex = _skipTrailingWhitespace(this, this.length);
+    }
+
+    if (endIndex == result.length) return result;
+    if (endIndex == 0) return "";
+    return JS('String', r'#.substring(#, #)', result, 0, endIndex);
+  }
+
+  String operator *(int times) {
+    if (0 >= times) return ''; // Unnecessary but hoists argument type check.
+    if (times == 1 || this.length == 0) return this;
+    if (times != JS('JSUInt32', '# >>> 0', times)) {
+      // times >= 2^32. We can't create a string that big.
+      throw const OutOfMemoryError();
+    }
+    var result = '';
+    var s = this;
+    while (true) {
+      if (times & 1 == 1) result = s + result;
+      times = JS('JSUInt31', '# >>> 1', times);
+      if (times == 0) break;
+      s += s;
+    }
+    return result;
+  }
+
+  String padLeft(int width, [String padding = ' ']) {
+    int delta = width - this.length;
+    if (delta <= 0) return this;
+    return padding * delta + this;
+  }
+
+  String padRight(int width, [String padding = ' ']) {
+    int delta = width - this.length;
+    if (delta <= 0) return this;
+    return this + padding * delta;
+  }
+
+  List<int> get codeUnits => new CodeUnits(this);
+
+  Runes get runes => new Runes(this);
+
+  int indexOf(Pattern pattern, [int start = 0]) {
+    checkNull(pattern);
+    if (start is! int) throw argumentErrorValue(start);
+    if (start < 0 || start > this.length) {
+      throw new RangeError.range(start, 0, this.length);
+    }
+    if (pattern is String) {
+      return stringIndexOfStringUnchecked(this, pattern, start);
+    }
+    if (pattern is JSSyntaxRegExp) {
+      JSSyntaxRegExp re = pattern;
+      Match match = firstMatchAfter(re, this, start);
+      return (match == null) ? -1 : match.start;
+    }
+    for (int i = start; i <= this.length; i++) {
+      if (pattern.matchAsPrefix(this, i) != null) return i;
+    }
+    return -1;
+  }
+
+  int lastIndexOf(Pattern pattern, [int start]) {
+    checkNull(pattern);
+    if (start == null) {
+      start = length;
+    } else if (start is! int) {
+      throw argumentErrorValue(start);
+    } else if (start < 0 || start > this.length) {
+      throw new RangeError.range(start, 0, this.length);
+    }
+    if (pattern is String) {
+      String other = pattern;
+      if (start + other.length > this.length) {
+        start = this.length - other.length;
+      }
+      return stringLastIndexOfUnchecked(this, other, start);
+    }
+    for (int i = start; i >= 0; i--) {
+      if (pattern.matchAsPrefix(this, i) != null) return i;
+    }
+    return -1;
+  }
+
+  bool contains(Pattern other, [int startIndex = 0]) {
+    checkNull(other);
+    if (startIndex < 0 || startIndex > this.length) {
+      throw new RangeError.range(startIndex, 0, this.length);
+    }
+    return stringContainsUnchecked(this, other, startIndex);
+  }
+
+  bool get isEmpty => length == 0;
+
+  bool get isNotEmpty => !isEmpty;
+
+  int compareTo(String other) {
+    if (other is! String) throw argumentErrorValue(other);
+    return this == other ? 0 : JS('bool', r'# < #', this, other) ? -1 : 1;
+  }
+
+  // Note: if you change this, also change the function [S].
+  String toString() => this;
+
+  /// This is the [Jenkins hash function][1] but using masking to keep
+  /// values in SMI range.
+  ///
+  /// [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
+  int get hashCode {
+    // TODO(ahe): This method shouldn't have to use JS. Update when our
+    // optimizations are smarter.
+    int hash = 0;
+    for (int i = 0; i < length; i++) {
+      hash = 0x1fffffff & (hash + JS('int', r'#.charCodeAt(#)', this, i));
+      hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
+      hash = JS('int', '# ^ (# >> 6)', hash, hash);
+    }
+    hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
+    hash = JS('int', '# ^ (# >> 11)', hash, hash);
+    return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
+  }
+
+  Type get runtimeType => String;
+
+  int get length => JS('int', r'#.length', this);
+
+  String operator [](int index) {
+    if (index is! int) throw diagnoseIndexError(this, index);
+    if (index >= length || index < 0) throw diagnoseIndexError(this, index);
+    return JS('String', '#[#]', this, index);
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart
new file mode 100644
index 0000000..42ad0c4
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart
@@ -0,0 +1,439 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Efficient JavaScript based implementation of a linked hash map used as a
+// backing map for constant maps and the [LinkedHashMap] patch
+
+part of _js_helper;
+
+const _USE_ES6_MAPS = const bool.fromEnvironment("dart2js.use.es6.maps");
+
+class JsLinkedHashMap<K, V> extends MapBase<K, V>
+    implements LinkedHashMap<K, V>, InternalMap {
+  int _length = 0;
+
+  // The hash map contents are divided into three parts: one part for
+  // string keys, one for numeric keys, and one for the rest. String
+  // and numeric keys map directly to their linked cells, but the rest
+  // of the entries are stored in bucket lists of the form:
+  //
+  //    [cell-0, cell-1, ...]
+  //
+  // where all keys in the same bucket share the same hash code.
+  var _strings;
+  var _nums;
+  var _rest;
+
+  // The keys and values are stored in cells that are linked together
+  // to form a double linked list.
+  LinkedHashMapCell _first;
+  LinkedHashMapCell _last;
+
+  // We track the number of modifications done to the key set of the
+  // hash map to be able to throw when the map is modified while being
+  // iterated over.
+  int _modifications = 0;
+
+  static bool get _supportsEs6Maps {
+    return JS('returns:bool;depends:none;effects:none;throws:never;gvn:true',
+        'typeof Map != "undefined"');
+  }
+
+  JsLinkedHashMap();
+
+  /// If ES6 Maps are available returns a linked hash-map backed by an ES6 Map.
+  @pragma('dart2js:tryInline')
+  factory JsLinkedHashMap.es6() {
+    return (_USE_ES6_MAPS && JsLinkedHashMap._supportsEs6Maps)
+        ? new Es6LinkedHashMap<K, V>()
+        : new JsLinkedHashMap<K, V>();
+  }
+
+  int get length => _length;
+  bool get isEmpty => _length == 0;
+  bool get isNotEmpty => !isEmpty;
+
+  Iterable<K> get keys {
+    return new LinkedHashMapKeyIterable<K>(this);
+  }
+
+  Iterable<V> get values {
+    return new MappedIterable<K, V>(keys, (each) => this[each]);
+  }
+
+  bool containsKey(Object key) {
+    if (_isStringKey(key)) {
+      var strings = _strings;
+      if (strings == null) return false;
+      return _containsTableEntry(strings, key);
+    } else if (_isNumericKey(key)) {
+      var nums = _nums;
+      if (nums == null) return false;
+      return _containsTableEntry(nums, key);
+    } else {
+      return internalContainsKey(key);
+    }
+  }
+
+  bool internalContainsKey(Object key) {
+    var rest = _rest;
+    if (rest == null) return false;
+    var bucket = _getBucket(rest, key);
+    return internalFindBucketIndex(bucket, key) >= 0;
+  }
+
+  bool containsValue(Object value) {
+    return keys.any((each) => this[each] == value);
+  }
+
+  void addAll(Map<K, V> other) {
+    other.forEach((K key, V value) {
+      this[key] = value;
+    });
+  }
+
+  V operator [](Object key) {
+    if (_isStringKey(key)) {
+      var strings = _strings;
+      if (strings == null) return null;
+      LinkedHashMapCell cell = _getTableCell(strings, key);
+      return JS('', '#', cell == null ? null : cell.hashMapCellValue);
+    } else if (_isNumericKey(key)) {
+      var nums = _nums;
+      if (nums == null) return null;
+      LinkedHashMapCell cell = _getTableCell(nums, key);
+      return JS('', '#', cell == null ? null : cell.hashMapCellValue);
+    } else {
+      return internalGet(key);
+    }
+  }
+
+  V internalGet(Object key) {
+    var rest = _rest;
+    if (rest == null) return null;
+    var bucket = _getBucket(rest, key);
+    int index = internalFindBucketIndex(bucket, key);
+    if (index < 0) return null;
+    LinkedHashMapCell cell = JS('var', '#[#]', bucket, index);
+    return JS('', '#', cell.hashMapCellValue);
+  }
+
+  void operator []=(K key, V value) {
+    if (_isStringKey(key)) {
+      var strings = _strings;
+      if (strings == null) _strings = strings = _newHashTable();
+      _addHashTableEntry(strings, key, value);
+    } else if (_isNumericKey(key)) {
+      var nums = _nums;
+      if (nums == null) _nums = nums = _newHashTable();
+      _addHashTableEntry(nums, key, value);
+    } else {
+      internalSet(key, value);
+    }
+  }
+
+  void internalSet(K key, V value) {
+    var rest = _rest;
+    if (rest == null) _rest = rest = _newHashTable();
+    var hash = internalComputeHashCode(key);
+    var bucket = _getTableBucket(rest, hash);
+    if (bucket == null) {
+      LinkedHashMapCell cell = _newLinkedCell(key, value);
+      _setTableEntry(rest, hash, JS('var', '[#]', cell));
+    } else {
+      int index = internalFindBucketIndex(bucket, key);
+      if (index >= 0) {
+        LinkedHashMapCell cell = JS('var', '#[#]', bucket, index);
+        cell.hashMapCellValue = value;
+      } else {
+        LinkedHashMapCell cell = _newLinkedCell(key, value);
+        JS('void', '#.push(#)', bucket, cell);
+      }
+    }
+  }
+
+  V putIfAbsent(K key, V ifAbsent()) {
+    if (containsKey(key)) return this[key];
+    V value = ifAbsent();
+    this[key] = value;
+    return value;
+  }
+
+  V remove(Object key) {
+    if (_isStringKey(key)) {
+      return _removeHashTableEntry(_strings, key);
+    } else if (_isNumericKey(key)) {
+      return _removeHashTableEntry(_nums, key);
+    } else {
+      return internalRemove(key);
+    }
+  }
+
+  V internalRemove(Object key) {
+    var rest = _rest;
+    if (rest == null) return null;
+    var hash = internalComputeHashCode(key);
+    var bucket = _getTableBucket(rest, hash);
+    int index = internalFindBucketIndex(bucket, key);
+    if (index < 0) return null;
+    // Use splice to remove the [cell] element at the index and
+    // unlink the cell before returning its value.
+    LinkedHashMapCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index);
+    _unlinkCell(cell);
+    // Remove empty bucket list to avoid memory leak.
+    if (JS('int', '#.length', bucket) == 0) {
+      _deleteTableEntry(rest, hash);
+    }
+    return JS('', '#', cell.hashMapCellValue);
+  }
+
+  void clear() {
+    if (_length > 0) {
+      _strings = _nums = _rest = _first = _last = null;
+      _length = 0;
+      _modified();
+    }
+  }
+
+  void forEach(void action(K key, V value)) {
+    LinkedHashMapCell cell = _first;
+    int modifications = _modifications;
+    while (cell != null) {
+      K key = JS('', '#', cell.hashMapCellKey);
+      V value = JS('', '#', cell.hashMapCellValue);
+      action(key, value);
+      if (modifications != _modifications) {
+        throw new ConcurrentModificationError(this);
+      }
+      cell = cell._next;
+    }
+  }
+
+  void _addHashTableEntry(var table, K key, V value) {
+    LinkedHashMapCell cell = _getTableCell(table, key);
+    if (cell == null) {
+      _setTableEntry(table, key, _newLinkedCell(key, value));
+    } else {
+      cell.hashMapCellValue = value;
+    }
+  }
+
+  V _removeHashTableEntry(var table, Object key) {
+    if (table == null) return null;
+    LinkedHashMapCell cell = _getTableCell(table, key);
+    if (cell == null) return null;
+    _unlinkCell(cell);
+    _deleteTableEntry(table, key);
+    return JS('', '#', cell.hashMapCellValue);
+  }
+
+  void _modified() {
+    // Value cycles after 2^30 modifications so that modification counts are
+    // always unboxed (Smi) values. Modification detection will be missed if you
+    // make exactly some multiple of 2^30 modifications between advances of an
+    // iterator.
+    _modifications = (_modifications + 1) & 0x3ffffff;
+  }
+
+  // Create a new cell and link it in as the last one in the list.
+  LinkedHashMapCell _newLinkedCell(K key, V value) {
+    LinkedHashMapCell cell = new LinkedHashMapCell(key, value);
+    if (_first == null) {
+      _first = _last = cell;
+    } else {
+      LinkedHashMapCell last = _last;
+      cell._previous = last;
+      _last = last._next = cell;
+    }
+    _length++;
+    _modified();
+    return cell;
+  }
+
+  // Unlink the given cell from the linked list of cells.
+  void _unlinkCell(LinkedHashMapCell cell) {
+    LinkedHashMapCell previous = cell._previous;
+    LinkedHashMapCell next = cell._next;
+    if (previous == null) {
+      assert(cell == _first);
+      _first = next;
+    } else {
+      previous._next = next;
+    }
+    if (next == null) {
+      assert(cell == _last);
+      _last = previous;
+    } else {
+      next._previous = previous;
+    }
+    _length--;
+    _modified();
+  }
+
+  static bool _isStringKey(var key) {
+    return key is String;
+  }
+
+  static bool _isNumericKey(var key) {
+    // Only treat unsigned 30-bit integers as numeric keys. This way,
+    // we avoid converting them to strings when we use them as keys in
+    // the JavaScript hash table object.
+    return key is num && JS('bool', '(# & 0x3ffffff) === #', key, key);
+  }
+
+  int internalComputeHashCode(var key) {
+    // We force the hash codes to be unsigned 30-bit integers to avoid
+    // issues with problematic keys like '__proto__'. Another option
+    // would be to throw an exception if the hash code isn't a number.
+    return JS('int', '# & 0x3ffffff', key.hashCode);
+  }
+
+  List<LinkedHashMapCell> _getBucket(var table, var key) {
+    var hash = internalComputeHashCode(key);
+    return _getTableBucket(table, hash);
+  }
+
+  int internalFindBucketIndex(var bucket, var key) {
+    if (bucket == null) return -1;
+    int length = JS('int', '#.length', bucket);
+    for (int i = 0; i < length; i++) {
+      LinkedHashMapCell cell = JS('var', '#[#]', bucket, i);
+      if (cell.hashMapCellKey == key) return i;
+    }
+    return -1;
+  }
+
+  String toString() => MapBase.mapToString(this);
+
+  LinkedHashMapCell _getTableCell(var table, var key) {
+    return JS('var', '#[#]', table, key);
+  }
+
+  List<LinkedHashMapCell> _getTableBucket(var table, var key) {
+    return JS('var', '#[#]', table, key);
+  }
+
+  void _setTableEntry(var table, var key, var value) {
+    assert(value != null);
+    JS('void', '#[#] = #', table, key, value);
+  }
+
+  void _deleteTableEntry(var table, var key) {
+    JS('void', 'delete #[#]', table, key);
+  }
+
+  bool _containsTableEntry(var table, var key) {
+    LinkedHashMapCell cell = _getTableCell(table, key);
+    return cell != null;
+  }
+
+  _newHashTable() {
+    // Create a new JavaScript object to be used as a hash table. Use
+    // Object.create to avoid the properties on Object.prototype
+    // showing up as entries.
+    var table = JS('var', 'Object.create(null)');
+    // Attempt to force the hash table into 'dictionary' mode by
+    // adding a property to it and deleting it again.
+    var temporaryKey = '<non-identifier-key>';
+    _setTableEntry(table, temporaryKey, table);
+    _deleteTableEntry(table, temporaryKey);
+    return table;
+  }
+}
+
+class Es6LinkedHashMap<K, V> extends JsLinkedHashMap<K, V> {
+  @override
+  LinkedHashMapCell _getTableCell(var table, var key) {
+    return JS('var', '#.get(#)', table, key);
+  }
+
+  @override
+  List<LinkedHashMapCell> _getTableBucket(var table, var key) {
+    return JS('var', '#.get(#)', table, key);
+  }
+
+  @override
+  void _setTableEntry(var table, var key, var value) {
+    JS('void', '#.set(#, #)', table, key, value);
+  }
+
+  @override
+  void _deleteTableEntry(var table, var key) {
+    JS('void', '#.delete(#)', table, key);
+  }
+
+  @override
+  bool _containsTableEntry(var table, var key) {
+    return JS('bool', '#.has(#)', table, key);
+  }
+
+  @override
+  _newHashTable() {
+    return JS('var', 'new Map()');
+  }
+}
+
+class LinkedHashMapCell {
+  final dynamic hashMapCellKey;
+  dynamic hashMapCellValue;
+
+  LinkedHashMapCell _next;
+  LinkedHashMapCell _previous;
+
+  LinkedHashMapCell(this.hashMapCellKey, this.hashMapCellValue);
+}
+
+class LinkedHashMapKeyIterable<E> extends EfficientLengthIterable<E> {
+  final dynamic _map;
+  LinkedHashMapKeyIterable(this._map);
+
+  int get length => _map._length;
+  bool get isEmpty => _map._length == 0;
+
+  Iterator<E> get iterator {
+    return new LinkedHashMapKeyIterator<E>(_map, _map._modifications);
+  }
+
+  bool contains(Object element) {
+    return _map.containsKey(element);
+  }
+
+  void forEach(void f(E element)) {
+    LinkedHashMapCell cell = _map._first;
+    int modifications = _map._modifications;
+    while (cell != null) {
+      f(JS('', '#', cell.hashMapCellKey));
+      if (modifications != _map._modifications) {
+        throw new ConcurrentModificationError(_map);
+      }
+      cell = cell._next;
+    }
+  }
+}
+
+class LinkedHashMapKeyIterator<E> implements Iterator<E> {
+  final dynamic _map;
+  final int _modifications;
+  LinkedHashMapCell _cell;
+  E _current;
+
+  LinkedHashMapKeyIterator(this._map, this._modifications) {
+    _cell = _map._first;
+  }
+
+  E get current => _current;
+
+  bool moveNext() {
+    if (_modifications != _map._modifications) {
+      throw new ConcurrentModificationError(_map);
+    } else if (_cell == null) {
+      _current = null;
+      return false;
+    } else {
+      _current = JS('', '#', _cell.hashMapCellKey);
+      _cell = _cell._next;
+      return true;
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/math_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/math_patch.dart
new file mode 100644
index 0000000..677953e
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/math_patch.dart
@@ -0,0 +1,329 @@
+// Copyright (c) 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.
+
+// Patch file for dart:math library.
+import 'dart:_foreign_helper' show JS;
+import 'dart:_js_helper' show patch, checkNum;
+import 'dart:typed_data' show ByteData;
+
+@patch
+T min<T extends num>(T a, T b) => JS(
+    'returns:num;depends:none;effects:none;gvn:true',
+    r'Math.min(#, #)',
+    checkNum(a),
+    checkNum(b));
+
+@patch
+T max<T extends num>(T a, T b) => JS(
+    'returns:num;depends:none;effects:none;gvn:true',
+    r'Math.max(#, #)',
+    checkNum(a),
+    checkNum(b));
+
+@patch
+double sqrt(num x) => JS('num', r'Math.sqrt(#)', checkNum(x));
+
+@patch
+double sin(num radians) => JS('num', r'Math.sin(#)', checkNum(radians));
+
+@patch
+double cos(num radians) => JS('num', r'Math.cos(#)', checkNum(radians));
+
+@patch
+double tan(num radians) => JS('num', r'Math.tan(#)', checkNum(radians));
+
+@patch
+double acos(num x) => JS('num', r'Math.acos(#)', checkNum(x));
+
+@patch
+double asin(num x) => JS('num', r'Math.asin(#)', checkNum(x));
+
+@patch
+double atan(num x) => JS('num', r'Math.atan(#)', checkNum(x));
+
+@patch
+double atan2(num a, num b) =>
+    JS('num', r'Math.atan2(#, #)', checkNum(a), checkNum(b));
+
+@patch
+double exp(num x) => JS('num', r'Math.exp(#)', checkNum(x));
+
+@patch
+double log(num x) => JS('num', r'Math.log(#)', checkNum(x));
+
+@patch
+num pow(num x, num exponent) {
+  checkNum(x);
+  checkNum(exponent);
+  return JS('num', r'Math.pow(#, #)', x, exponent);
+}
+
+const int _POW2_32 = 0x100000000;
+
+@patch
+class Random {
+  static Random _secureRandom;
+
+  @patch
+  factory Random([int seed]) =>
+      (seed == null) ? const _JSRandom() : new _Random(seed);
+
+  @patch
+  factory Random.secure() => _secureRandom ??= _JSSecureRandom();
+}
+
+class _JSRandom implements Random {
+  // The Dart2JS implementation of Random doesn't use a seed.
+  const _JSRandom();
+
+  int nextInt(int max) {
+    if (max <= 0 || max > _POW2_32) {
+      throw new RangeError('max must be in range 0 < max ≤ 2^32, was $max');
+    }
+    return JS('int', '(Math.random() * #) >>> 0', max);
+  }
+
+  /// Generates a positive random floating point value uniformly distributed on
+  /// the range from 0.0, inclusive, to 1.0, exclusive.
+  double nextDouble() => JS('double', 'Math.random()');
+
+  /// Generates a random boolean value.
+  bool nextBool() => JS('bool', 'Math.random() < 0.5');
+}
+
+class _Random implements Random {
+  // Constants used by the algorithm or masking.
+  static const double _POW2_53_D = 1.0 * (0x20000000000000);
+  static const double _POW2_27_D = 1.0 * (1 << 27);
+  static const int _MASK32 = 0xFFFFFFFF;
+
+  // State comprised of two unsigned 32 bit integers.
+  int _lo = 0;
+  int _hi = 0;
+
+  // Implements:
+  //   uint64_t hash = 0;
+  //   do {
+  //      hash = hash * 1037 ^ mix64((uint64_t)seed);
+  //      seed >>= 64;
+  //   } while (seed != 0 && seed != -1);  // Limits for pos/neg seed.
+  //   if (hash == 0) {
+  //     hash = 0x5A17;
+  //   }
+  //   _lo = hash & _MASK_32;
+  //   _hi = hash >> 32;
+  // and then does four _nextState calls to shuffle bits around.
+  _Random(int seed) {
+    int empty_seed = 0;
+    if (seed < 0) {
+      empty_seed = -1;
+    }
+    do {
+      int low = seed & _MASK32;
+      seed = (seed - low) ~/ _POW2_32;
+      int high = seed & _MASK32;
+      seed = (seed - high) ~/ _POW2_32;
+
+      // Thomas Wang's 64-bit mix function.
+      // http://www.concentric.net/~Ttwang/tech/inthash.htm
+      // via. http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm
+
+      // key = ~key + (key << 21);
+      int tmplow = low << 21;
+      int tmphigh = (high << 21) | (low >> 11);
+      tmplow = (~low & _MASK32) + tmplow;
+      low = tmplow & _MASK32;
+      high = (~high + tmphigh + ((tmplow - low) ~/ 0x100000000)) & _MASK32;
+      // key = key ^ (key >> 24).
+      tmphigh = high >> 24;
+      tmplow = (low >> 24) | (high << 8);
+      low ^= tmplow;
+      high ^= tmphigh;
+      // key = key * 265
+      tmplow = low * 265;
+      low = tmplow & _MASK32;
+      high = (high * 265 + (tmplow - low) ~/ 0x100000000) & _MASK32;
+      // key = key ^ (key >> 14);
+      tmphigh = high >> 14;
+      tmplow = (low >> 14) | (high << 18);
+      low ^= tmplow;
+      high ^= tmphigh;
+      // key = key * 21
+      tmplow = low * 21;
+      low = tmplow & _MASK32;
+      high = (high * 21 + (tmplow - low) ~/ 0x100000000) & _MASK32;
+      // key = key ^ (key >> 28).
+      tmphigh = high >> 28;
+      tmplow = (low >> 28) | (high << 4);
+      low ^= tmplow;
+      high ^= tmphigh;
+      // key = key + (key << 31);
+      tmplow = low << 31;
+      tmphigh = (high << 31) | (low >> 1);
+      tmplow += low;
+      low = tmplow & _MASK32;
+      high = (high + tmphigh + (tmplow - low) ~/ 0x100000000) & _MASK32;
+      // Mix end.
+
+      // seed = seed * 1037 ^ key;
+      tmplow = _lo * 1037;
+      _lo = tmplow & _MASK32;
+      _hi = (_hi * 1037 + (tmplow - _lo) ~/ 0x100000000) & _MASK32;
+      _lo ^= low;
+      _hi ^= high;
+    } while (seed != empty_seed);
+
+    if (_hi == 0 && _lo == 0) {
+      _lo = 0x5A17;
+    }
+    _nextState();
+    _nextState();
+    _nextState();
+    _nextState();
+  }
+
+  // The algorithm used here is Multiply with Carry (MWC) with a Base b = 2^32.
+  // http://en.wikipedia.org/wiki/Multiply-with-carry
+  // The constant A (0xFFFFDA61) is selected from "Numerical Recipes 3rd
+  // Edition" p.348 B1.
+
+  // Implements:
+  //   var state = (A * _lo + _hi) & _MASK_64;
+  //   _lo = state & _MASK_32;
+  //   _hi = state >> 32;
+  void _nextState() {
+    // Simulate (0xFFFFDA61 * lo + hi) without overflowing 53 bits.
+    int tmpHi = 0xFFFF0000 * _lo; // At most 48 bits of significant result.
+    int tmpHiLo = tmpHi & _MASK32; // Get the lower 32 bits.
+    int tmpHiHi = tmpHi - tmpHiLo; // And just the upper 32 bits.
+    int tmpLo = 0xDA61 * _lo;
+    int tmpLoLo = tmpLo & _MASK32;
+    int tmpLoHi = tmpLo - tmpLoLo;
+
+    int newLo = tmpLoLo + tmpHiLo + _hi;
+    _lo = newLo & _MASK32;
+    int newLoHi = newLo - _lo;
+    _hi = ((tmpLoHi + tmpHiHi + newLoHi) ~/ _POW2_32) & _MASK32;
+    assert(_lo < _POW2_32);
+    assert(_hi < _POW2_32);
+  }
+
+  int nextInt(int max) {
+    if (max <= 0 || max > _POW2_32) {
+      throw new RangeError('max must be in range 0 < max ≤ 2^32, was $max');
+    }
+    if ((max & (max - 1)) == 0) {
+      // Fast case for powers of two.
+      _nextState();
+      return _lo & (max - 1);
+    }
+
+    int rnd32;
+    int result;
+    do {
+      _nextState();
+      rnd32 = _lo;
+      result = rnd32.remainder(max); // % max;
+    } while ((rnd32 - result + max) >= _POW2_32);
+    return result;
+  }
+
+  double nextDouble() {
+    _nextState();
+    int bits26 = _lo & ((1 << 26) - 1);
+    _nextState();
+    int bits27 = _lo & ((1 << 27) - 1);
+    return (bits26 * _POW2_27_D + bits27) / _POW2_53_D;
+  }
+
+  bool nextBool() {
+    _nextState();
+    return (_lo & 1) == 0;
+  }
+}
+
+class _JSSecureRandom implements Random {
+  // Reused buffer with room enough for a double.
+  final _buffer = new ByteData(8);
+
+  _JSSecureRandom() {
+    var crypto = JS('', 'self.crypto');
+    if (crypto != null) {
+      var getRandomValues = JS('', '#.getRandomValues', crypto);
+      if (getRandomValues != null) {
+        return;
+      }
+    }
+    throw new UnsupportedError(
+        'No source of cryptographically secure random numbers available.');
+  }
+
+  /// Fill _buffer from [start] to `start + length` with random bytes.
+  void _getRandomBytes(int start, int length) {
+    JS('void', 'crypto.getRandomValues(#)',
+        _buffer.buffer.asUint8List(start, length));
+  }
+
+  bool nextBool() {
+    _getRandomBytes(0, 1);
+    return _buffer.getUint8(0).isOdd;
+  }
+
+  double nextDouble() {
+    _getRandomBytes(1, 7);
+    // Set top bits 12 of double to 0x3FF which is the exponent for numbers
+    // between 1.0 and 2.0.
+    _buffer.setUint8(0, 0x3F);
+    int highByte = _buffer.getUint8(1);
+    _buffer.setUint8(1, highByte | 0xF0);
+
+    // Buffer now contains double in the range [1.0-2.0)
+    // with 52 bits of entropy (not 53).
+    // To get 53 bits, we extract the 53rd bit from higthByte before
+    // overwriting it, and add that as a least significant bit.
+    // The getFloat64 method is big-endian as default.
+    double result = _buffer.getFloat64(0) - 1.0;
+    if (highByte & 0x10 != 0) {
+      result += 1.1102230246251565e-16; // pow(2,-53).
+    }
+    return result;
+  }
+
+  int nextInt(int max) {
+    if (max <= 0 || max > _POW2_32) {
+      throw new RangeError('max must be in range 0 < max ≤ 2^32, was $max');
+    }
+    int byteCount = 1;
+    if (max > 0xFF) {
+      byteCount++;
+      if (max > 0xFFFF) {
+        byteCount++;
+        if (max > 0xFFFFFF) {
+          byteCount++;
+        }
+      }
+    }
+    _buffer.setUint32(0, 0);
+    int start = 4 - byteCount;
+    int randomLimit = pow(256, byteCount);
+    while (true) {
+      _getRandomBytes(start, byteCount);
+      // The getUint32 method is big-endian as default.
+      int random = _buffer.getUint32(0);
+      if (max & (max - 1) == 0) {
+        // Max is power of 2.
+        return random & (max - 1);
+      }
+      int result = random.remainder(max);
+      // Ensure results have equal probability by rejecting values in the
+      // last range of k*max .. 256**byteCount.
+      // TODO: Consider picking a higher byte count if the last range is a
+      // significant portion of the entire range - a 50% chance of having
+      // to use two more bytes is no worse than always using one more.
+      if (random - result + max < randomLimit) {
+        return result;
+      }
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart
new file mode 100644
index 0000000..6f8018a
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 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.
+
+// Patch library for dart:mirrors.
+
+import 'dart:_js_helper' show patch;
+import 'dart:mirrors';
+
+const String _message = 'dart:mirrors is no longer supported for web apps';
+
+@patch
+MirrorSystem currentMirrorSystem() => throw new UnsupportedError(_message);
+
+@patch
+InstanceMirror reflect(Object reflectee) =>
+    throw new UnsupportedError(_message);
+
+@patch
+ClassMirror reflectClass(Type key) => throw new UnsupportedError(_message);
+
+@patch
+TypeMirror reflectType(Type key, [List<Type> typeArguments]) =>
+    throw new UnsupportedError(_message);
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/native_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/native_helper.dart
new file mode 100644
index 0000000..ccfa26f
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/native_helper.dart
@@ -0,0 +1,592 @@
+// Copyright (c) 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 _js_helper;
+
+// TODO(ngeoffray): stop using this method once our optimizers can
+// change str1.contains(str2) into str1.indexOf(str2) != -1.
+bool contains(String userAgent, String name) {
+  return JS('int', '#.indexOf(#)', userAgent, name) != -1;
+}
+
+int arrayLength(List array) {
+  return JS('int', '#.length', array);
+}
+
+arrayGet(List array, int index) {
+  return JS('var', '#[#]', array, index);
+}
+
+void arraySet(List array, int index, var value) {
+  JS('var', '#[#] = #', array, index, value);
+}
+
+propertyGet(var object, String property) {
+  return JS('var', '#[#]', object, property);
+}
+
+bool callHasOwnProperty(var function, var object, String property) {
+  return JS('bool', '#.call(#, #)', function, object, property);
+}
+
+void propertySet(var object, String property, var value) {
+  JS('var', '#[#] = #', object, property, value);
+}
+
+getPropertyFromPrototype(var object, String name) {
+  return JS('var', 'Object.getPrototypeOf(#)[#]', object, name);
+}
+
+/// Returns a String tag identifying the type of the native object, or `null`.
+/// The tag is not the name of the type, but usually the name of the JavaScript
+/// constructor function.  Initialized by [initHooks].
+Function getTagFunction;
+
+/// If a lookup via [getTagFunction] on an object [object] that has [tag] fails,
+/// this function is called to provide an alternate tag.  This allows us to fail
+/// gracefully if we can make a good guess, for example, when browsers add novel
+/// kinds of HTMLElement that we have never heard of.  Initialized by
+/// [initHooks].
+Function alternateTagFunction;
+
+/// Returns the prototype for the JavaScript constructor named by an input tag.
+/// Returns `null` if there is no such constructor, or if pre-patching of the
+/// constructor is to be avoided.  Initialized by [initHooks].
+Function prototypeForTagFunction;
+
+String toStringForNativeObject(var obj) {
+  // TODO(sra): Is this code dead?
+  // [getTagFunction] might be uninitialized, but in usual usage, toString has
+  // been called via an interceptor and initialized it.
+  String name = getTagFunction == null
+      ? '<Unknown>'
+      : JS('String', '#', getTagFunction(obj));
+  return 'Instance of $name';
+}
+
+int hashCodeForNativeObject(object) => Primitives.objectHashCode(object);
+
+/// Sets a JavaScript property on an object.
+void defineProperty(var obj, String property, var value) {
+  JS(
+      'void',
+      'Object.defineProperty(#, #, '
+          '{value: #, enumerable: false, writable: true, configurable: true})',
+      obj,
+      property,
+      value);
+}
+
+// Is [obj] an instance of a Dart-defined class?
+bool isDartObject(obj) {
+  // Some of the extra parens here are necessary.
+  return JS(
+      'bool',
+      '((#) instanceof (#))',
+      obj,
+      JS_BUILTIN(
+          'depends:none;effects:none;', JsBuiltin.dartObjectConstructor));
+}
+
+/// A JavaScript object mapping tags to the constructors of interceptors.
+/// This is a JavaScript object with no prototype.
+///
+/// Example: 'HTMLImageElement' maps to the ImageElement class constructor.
+get interceptorsByTag => JS_EMBEDDED_GLOBAL('=Object', INTERCEPTORS_BY_TAG);
+
+/// A JavaScript object mapping tags to `true` or `false`.
+///
+/// Example: 'HTMLImageElement' maps to `true` since, as there are no subclasses
+/// of ImageElement, it is a leaf class in the native class hierarchy.
+get leafTags => JS_EMBEDDED_GLOBAL('=Object', LEAF_TAGS);
+
+String findDispatchTagForInterceptorClass(interceptorClassConstructor) {
+  return JS(
+      '', r'#.#', interceptorClassConstructor, NATIVE_SUPERCLASS_TAG_NAME);
+}
+
+/// Cache of dispatch records for instances.  This is a JavaScript object used
+/// as a map.  Keys are instance tags, e.g. "!SomeThing".  The cache permits the
+/// sharing of one dispatch record between multiple instances.
+var dispatchRecordsForInstanceTags;
+
+/// Cache of interceptors indexed by uncacheable tags, e.g. "~SomeThing".
+/// This is a JavaScript object used as a map.
+var interceptorsForUncacheableTags;
+
+lookupInterceptor(String tag) {
+  return propertyGet(interceptorsByTag, tag);
+}
+
+// Dispatch tag marks are optional prefixes for a dispatch tag that direct how
+// the interceptor for the tag may be cached.
+
+/// No caching permitted.
+const UNCACHED_MARK = '~';
+
+/// Dispatch record must be cached per instance
+const INSTANCE_CACHED_MARK = '!';
+
+/// Dispatch record is cached on immediate prototype.
+const LEAF_MARK = '-';
+
+/// Dispatch record is cached on immediate prototype with a prototype
+/// verification to prevent the interceptor being associated with a subclass
+/// before a dispatch record is cached on the subclass.
+const INTERIOR_MARK = '+';
+
+/// A 'discriminator' function is to be used. TBD.
+const DISCRIMINATED_MARK = '*';
+
+/// Returns the interceptor for a native object, or returns `null` if not found.
+///
+/// A dispatch record is cached according to the specification of the dispatch
+/// tag for [obj].
+@pragma('dart2js:noInline')
+lookupAndCacheInterceptor(obj) {
+  assert(!isDartObject(obj));
+  String tag = getTagFunction(obj);
+
+  // Fast path for instance (and uncached) tags because the lookup is repeated
+  // for each instance (or getInterceptor call).
+  var record = propertyGet(dispatchRecordsForInstanceTags, tag);
+  if (record != null) return patchInstance(obj, record);
+  var interceptor = propertyGet(interceptorsForUncacheableTags, tag);
+  if (interceptor != null) return interceptor;
+
+  // This lookup works for derived dispatch tags because we add them all in
+  // [initNativeDispatch].
+  var interceptorClass = lookupInterceptor(tag);
+  if (interceptorClass == null) {
+    tag = alternateTagFunction(obj, tag);
+    if (tag != null) {
+      // Fast path for instance and uncached tags again.
+      record = propertyGet(dispatchRecordsForInstanceTags, tag);
+      if (record != null) return patchInstance(obj, record);
+      interceptor = propertyGet(interceptorsForUncacheableTags, tag);
+      if (interceptor != null) return interceptor;
+
+      interceptorClass = lookupInterceptor(tag);
+    }
+  }
+
+  if (interceptorClass == null) {
+    // This object is not known to Dart.  There could be several reasons for
+    // that, including (but not limited to):
+    //
+    // * A bug in native code (hopefully this is caught during development).
+    // * An unknown DOM object encountered.
+    // * JavaScript code running in an unexpected context.  For example, on
+    //   node.js.
+    return null;
+  }
+
+  interceptor = JS('', '#.prototype', interceptorClass);
+
+  var mark = JS('String|Null', '#[0]', tag);
+
+  if (mark == INSTANCE_CACHED_MARK) {
+    record = makeLeafDispatchRecord(interceptor);
+    propertySet(dispatchRecordsForInstanceTags, tag, record);
+    return patchInstance(obj, record);
+  }
+
+  if (mark == UNCACHED_MARK) {
+    propertySet(interceptorsForUncacheableTags, tag, interceptor);
+    return interceptor;
+  }
+
+  if (mark == LEAF_MARK) {
+    return patchProto(obj, makeLeafDispatchRecord(interceptor));
+  }
+
+  if (mark == INTERIOR_MARK) {
+    return patchInteriorProto(obj, interceptor);
+  }
+
+  if (mark == DISCRIMINATED_MARK) {
+    // TODO(sra): Use discriminator of tag.
+    throw new UnimplementedError(tag);
+  }
+
+  // [tag] was not explicitly an interior or leaf tag, so
+  var isLeaf = JS('bool', '(#[#]) === true', leafTags, tag);
+  if (isLeaf) {
+    return patchProto(obj, makeLeafDispatchRecord(interceptor));
+  } else {
+    return patchInteriorProto(obj, interceptor);
+  }
+}
+
+patchInstance(obj, record) {
+  setDispatchProperty(obj, record);
+  return dispatchRecordInterceptor(record);
+}
+
+patchProto(obj, record) {
+  setDispatchProperty(JS('', 'Object.getPrototypeOf(#)', obj), record);
+  return dispatchRecordInterceptor(record);
+}
+
+patchInteriorProto(obj, interceptor) {
+  var proto = JS('', 'Object.getPrototypeOf(#)', obj);
+  var record = makeDispatchRecord(interceptor, proto, null, null);
+  setDispatchProperty(proto, record);
+  return interceptor;
+}
+
+makeLeafDispatchRecord(interceptor) {
+  var fieldName = JS_GET_NAME(JsGetName.IS_INDEXABLE_FIELD_NAME);
+  bool indexability = JS('bool', r'!!#[#]', interceptor, fieldName);
+  return makeDispatchRecord(interceptor, false, null, indexability);
+}
+
+makeDefaultDispatchRecord(tag, interceptorClass, proto) {
+  var interceptor = JS('', '#.prototype', interceptorClass);
+  var isLeaf = JS('bool', '(#[#]) === true', leafTags, tag);
+  if (isLeaf) {
+    return makeLeafDispatchRecord(interceptor);
+  } else {
+    return makeDispatchRecord(interceptor, proto, null, null);
+  }
+}
+
+/// [proto] should have no shadowing prototypes that are not also assigned a
+/// dispatch rescord.
+setNativeSubclassDispatchRecord(proto, interceptor) {
+  setDispatchProperty(proto, makeLeafDispatchRecord(interceptor));
+}
+
+String constructorNameFallback(object) {
+  return JS('String', '#(#)', _constructorNameFallback, object);
+}
+
+var initNativeDispatchFlag; // null or true
+
+@pragma('dart2js:noInline')
+void initNativeDispatch() {
+  if (true == initNativeDispatchFlag) return;
+  initNativeDispatchFlag = true;
+  initNativeDispatchContinue();
+}
+
+@pragma('dart2js:noInline')
+void initNativeDispatchContinue() {
+  dispatchRecordsForInstanceTags = JS('', 'Object.create(null)');
+  interceptorsForUncacheableTags = JS('', 'Object.create(null)');
+
+  initHooks();
+
+  // Try to pro-actively patch prototypes of DOM objects.  For each of our known
+  // tags `TAG`, if `window.TAG` is a (constructor) function, set the dispatch
+  // property if the function's prototype to a dispatch record.
+  var map = interceptorsByTag;
+  var tags = JS('JSMutableArray', 'Object.getOwnPropertyNames(#)', map);
+
+  if (JS('bool', 'typeof window != "undefined"')) {
+    var context = JS('=Object', 'window');
+    var fun = JS('=Object', 'function () {}');
+    for (int i = 0; i < tags.length; i++) {
+      var tag = tags[i];
+      var proto = prototypeForTagFunction(tag);
+      if (proto != null) {
+        var interceptorClass = JS('', '#[#]', map, tag);
+        var record = makeDefaultDispatchRecord(tag, interceptorClass, proto);
+        if (record != null) {
+          setDispatchProperty(proto, record);
+          // Ensure the modified prototype is still fast by assigning it to
+          // the prototype property of a function object.
+          JS('', '#.prototype = #', fun, proto);
+        }
+      }
+    }
+  }
+
+  // [interceptorsByTag] maps 'plain' dispatch tags.  Add all the derived
+  // dispatch tags to simplify lookup of derived tags.
+  for (int i = 0; i < tags.length; i++) {
+    var tag = JS('String', '#[#]', tags, i);
+    if (JS('bool', '/^[A-Za-z_]/.test(#)', tag)) {
+      var interceptorClass = propertyGet(map, tag);
+      propertySet(map, INSTANCE_CACHED_MARK + tag, interceptorClass);
+      propertySet(map, UNCACHED_MARK + tag, interceptorClass);
+      propertySet(map, LEAF_MARK + tag, interceptorClass);
+      propertySet(map, INTERIOR_MARK + tag, interceptorClass);
+      propertySet(map, DISCRIMINATED_MARK + tag, interceptorClass);
+    }
+  }
+}
+
+/// Initializes [getTagFunction] and [alternateTagFunction].
+///
+/// These functions are 'hook functions', collectively 'hooks'.  They
+/// initialized by applying a series of hooks transformers.  Built-in hooks
+/// transformers deal with various known browser behaviours.
+///
+/// Each hook tranformer takes a 'hooks' input which is a JavaScript object
+/// containing the hook functions, and returns the same or a new object with
+/// replacements.  The replacements can wrap the originals to provide alternate
+/// or modified behaviour.
+///
+///     { getTag: function(obj) {...},
+///       getUnknownTag: function(obj, tag) {...},
+///       prototypeForTag: function(tag) {...},
+///       discriminator: function(tag) {...},
+///      }
+///
+/// * getTag(obj) returns the dispatch tag, or `null`.
+/// * getUnknownTag(obj, tag) returns a tag when [getTag] fails.
+/// * prototypeForTag(tag) returns the prototype of the constructor for tag,
+///   or `null` if not available or prepatching is undesirable.
+/// * discriminator(tag) returns a function TBD.
+///
+/// The web site can adapt a dart2js application by loading code ahead of the
+/// dart2js application that defines hook transformers to be after the built in
+/// ones.  Code defining a transformer HT should use the following pattern to
+/// ensure multiple transformers can be composed:
+///
+///     (dartNativeDispatchHooksTransformer =
+///      window.dartNativeDispatchHooksTransformer || []).push(HT);
+///
+///
+/// TODO: Implement and describe dispatch tags and their caching methods.
+void initHooks() {
+  // The initial simple hooks:
+  var hooks = JS('', '#()', _baseHooks);
+
+  // Customize for browsers where `object.constructor.name` fails:
+  var _fallbackConstructorHooksTransformer = JS('', '#(#)',
+      _fallbackConstructorHooksTransformerGenerator, _constructorNameFallback);
+  hooks = applyHooksTransformer(_fallbackConstructorHooksTransformer, hooks);
+
+  // Customize for browsers:
+  hooks = applyHooksTransformer(_firefoxHooksTransformer, hooks);
+  hooks = applyHooksTransformer(_ieHooksTransformer, hooks);
+  hooks = applyHooksTransformer(_operaHooksTransformer, hooks);
+  hooks = applyHooksTransformer(_safariHooksTransformer, hooks);
+
+  hooks = applyHooksTransformer(_fixDocumentHooksTransformer, hooks);
+
+  // TODO(sra): Update ShadowDOM polyfil to use
+  // [dartNativeDispatchHooksTransformer] and remove this hook.
+  hooks = applyHooksTransformer(
+      _dartExperimentalFixupGetTagHooksTransformer, hooks);
+
+  // Apply global hooks.
+  //
+  // If defined, dartNativeDispatchHookdTransformer should be a single function
+  // of a JavaScript Array of functions.
+
+  if (JS('bool', 'typeof dartNativeDispatchHooksTransformer != "undefined"')) {
+    var transformers = JS('', 'dartNativeDispatchHooksTransformer');
+    if (JS('bool', 'typeof # == "function"', transformers)) {
+      transformers = [transformers];
+    }
+    if (JS('bool', '#.constructor == Array', transformers)) {
+      for (int i = 0; i < JS('int', '#.length', transformers); i++) {
+        var transformer = JS('', '#[#]', transformers, i);
+        if (JS('bool', 'typeof # == "function"', transformer)) {
+          hooks = applyHooksTransformer(transformer, hooks);
+        }
+      }
+    }
+  }
+
+  var getTag = JS('', '#.getTag', hooks);
+  var getUnknownTag = JS('', '#.getUnknownTag', hooks);
+  var prototypeForTag = JS('', '#.prototypeForTag', hooks);
+
+  getTagFunction = (o) => JS('String|Null', '#(#)', getTag, o);
+  alternateTagFunction =
+      (o, String tag) => JS('String|Null', '#(#, #)', getUnknownTag, o, tag);
+  prototypeForTagFunction =
+      (String tag) => JS('', '#(#)', prototypeForTag, tag);
+}
+
+applyHooksTransformer(transformer, hooks) {
+  var newHooks = JS('=Object|Null', '#(#)', transformer, hooks);
+  return JS('', '# || #', newHooks, hooks);
+}
+
+// JavaScript code fragments.
+//
+// This is a temporary place for the JavaScript code.
+//
+// TODO(sra): These code fragments are not minified.  They could be generated by
+// the code emitter, or JS_CONST could be improved to parse entire functions and
+// take care of the minification.
+
+const _baseHooks = const JS_CONST(r'''
+function() {
+  var toStringFunction = Object.prototype.toString;
+  function getTag(o) {
+    var s = toStringFunction.call(o);
+    return s.substring(8, s.length - 1);
+  }
+  function getUnknownTag(object, tag) {
+    // This code really belongs in [getUnknownTagGenericBrowser] but having it
+    // here allows [getUnknownTag] to be tested on d8.
+    if (/^HTML[A-Z].*Element$/.test(tag)) {
+      // Check that it is not a simple JavaScript object.
+      var name = toStringFunction.call(object);
+      if (name == "[object Object]") return null;
+      return "HTMLElement";
+    }
+  }
+  function getUnknownTagGenericBrowser(object, tag) {
+    if (self.HTMLElement && object instanceof HTMLElement) return "HTMLElement";
+    return getUnknownTag(object, tag);
+  }
+  function prototypeForTag(tag) {
+    if (typeof window == "undefined") return null;
+    if (typeof window[tag] == "undefined") return null;
+    var constructor = window[tag];
+    if (typeof constructor != "function") return null;
+    return constructor.prototype;
+  }
+  function discriminator(tag) { return null; }
+
+  var isBrowser = typeof navigator == "object";
+
+  return {
+    getTag: getTag,
+    getUnknownTag: isBrowser ? getUnknownTagGenericBrowser : getUnknownTag,
+    prototypeForTag: prototypeForTag,
+    discriminator: discriminator };
+}''');
+
+/// Returns the name of the constructor function for browsers where
+/// `object.constructor.name` is not reliable.
+///
+/// This function is split out of
+/// [_fallbackConstructorHooksTransformerGenerator] as it is called from both
+/// the dispatch hooks and via [constructorNameFallback] from objectToString.
+const _constructorNameFallback = const JS_CONST(r'''
+function getTagFallback(o) {
+  var s = Object.prototype.toString.call(o);
+  return s.substring(8, s.length - 1);
+}''');
+
+const _fallbackConstructorHooksTransformerGenerator = const JS_CONST(r'''
+function(getTagFallback) {
+  return function(hooks) {
+    // If we are not in a browser, assume we are in d8.
+    // TODO(sra): Recognize jsshell.
+    if (typeof navigator != "object") return hooks;
+
+    var ua = navigator.userAgent;
+    // TODO(antonm): remove a reference to DumpRenderTree.
+    if (ua.indexOf("DumpRenderTree") >= 0) return hooks;
+    if (ua.indexOf("Chrome") >= 0) {
+      // Confirm constructor name is usable for dispatch.
+      function confirm(p) {
+        return typeof window == "object" && window[p] && window[p].name == p;
+      }
+      if (confirm("Window") && confirm("HTMLElement")) return hooks;
+    }
+
+    hooks.getTag = getTagFallback;
+  };
+}''');
+
+const _ieHooksTransformer = const JS_CONST(r'''
+function(hooks) {
+  var userAgent = typeof navigator == "object" ? navigator.userAgent : "";
+  if (userAgent.indexOf("Trident/") == -1) return hooks;
+
+  var getTag = hooks.getTag;
+
+  var quickMap = {
+    "BeforeUnloadEvent": "Event",
+    "DataTransfer": "Clipboard",
+    "HTMLDDElement": "HTMLElement",
+    "HTMLDTElement": "HTMLElement",
+    "HTMLPhraseElement": "HTMLElement",
+    "Position": "Geoposition"
+  };
+
+  function getTagIE(o) {
+    var tag = getTag(o);
+    var newTag = quickMap[tag];
+    if (newTag) return newTag;
+    // Patches for types which report themselves as Objects.
+    if (tag == "Object") {
+      if (window.DataView && (o instanceof window.DataView)) return "DataView";
+    }
+    return tag;
+  }
+
+  function prototypeForTagIE(tag) {
+    var constructor = window[tag];
+    if (constructor == null) return null;
+    return constructor.prototype;
+  }
+
+  hooks.getTag = getTagIE;
+  hooks.prototypeForTag = prototypeForTagIE;
+}''');
+
+const _fixDocumentHooksTransformer = const JS_CONST(r'''
+function(hooks) {
+  var getTag = hooks.getTag;
+  var prototypeForTag = hooks.prototypeForTag;
+  function getTagFixed(o) {
+    var tag = getTag(o);
+    if (tag == "Document") {
+      // Some browsers and the polymer polyfill call both HTML and XML documents
+      // "Document", so we check for the xmlVersion property, which is the empty
+      // string on HTML documents. Since both dart:html classes Document and
+      // HtmlDocument share the same type, we must patch the instances and not
+      // the prototype.
+      if (!!o.xmlVersion) return "!Document";
+      return "!HTMLDocument";
+    }
+    return tag;
+  }
+
+  function prototypeForTagFixed(tag) {
+    if (tag == "Document") return null;  // Do not pre-patch Document.
+    return prototypeForTag(tag);
+  }
+
+  hooks.getTag = getTagFixed;
+  hooks.prototypeForTag = prototypeForTagFixed;
+}''');
+
+const _firefoxHooksTransformer = const JS_CONST(r'''
+function(hooks) {
+  var userAgent = typeof navigator == "object" ? navigator.userAgent : "";
+  if (userAgent.indexOf("Firefox") == -1) return hooks;
+
+  var getTag = hooks.getTag;
+
+  var quickMap = {
+    "BeforeUnloadEvent": "Event",
+    "DataTransfer": "Clipboard",
+    "GeoGeolocation": "Geolocation",
+    "Location": "!Location",               // Fixes issue 18151
+    "WorkerMessageEvent": "MessageEvent",
+    "XMLDocument": "!Document"};
+
+  function getTagFirefox(o) {
+    var tag = getTag(o);
+    return quickMap[tag] || tag;
+  }
+
+  hooks.getTag = getTagFirefox;
+}''');
+
+const _operaHooksTransformer = const JS_CONST(r'''
+function(hooks) { return hooks; }
+''');
+
+const _safariHooksTransformer = const JS_CONST(r'''
+function(hooks) { return hooks; }
+''');
+
+const _dartExperimentalFixupGetTagHooksTransformer = const JS_CONST(r'''
+function(hooks) {
+  if (typeof dartExperimentalFixupGetTag != "function") return hooks;
+  hooks.getTag = dartExperimentalFixupGetTag(hooks.getTag);
+}''');
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart
new file mode 100644
index 0000000..0a91641
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart
@@ -0,0 +1,1821 @@
+// 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.
+
+/// Specialized integers and floating point numbers,
+/// with SIMD support and efficient lists.
+library dart.typed_data.implementation;
+
+import 'dart:collection' show ListMixin;
+import 'dart:_internal' show FixedLengthListMixin hide Symbol;
+import 'dart:_interceptors' show JSIndexable, JSUInt32, JSUInt31;
+import 'dart:_js_helper'
+    show
+        Creates,
+        JavaScriptIndexingBehavior,
+        JSName,
+        Native,
+        Returns,
+        diagnoseIndexError,
+        diagnoseRangeError;
+import 'dart:_foreign_helper' show JS;
+import 'dart:math' as Math;
+
+import 'dart:typed_data';
+
+@Native('ArrayBuffer')
+class NativeByteBuffer implements ByteBuffer {
+  @JSName('byteLength')
+  final int lengthInBytes;
+
+  Type get runtimeType => ByteBuffer;
+
+  Uint8List asUint8List([int offsetInBytes = 0, int length]) {
+    return new NativeUint8List.view(this, offsetInBytes, length);
+  }
+
+  Int8List asInt8List([int offsetInBytes = 0, int length]) {
+    return new NativeInt8List.view(this, offsetInBytes, length);
+  }
+
+  Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int length]) {
+    return new NativeUint8ClampedList.view(this, offsetInBytes, length);
+  }
+
+  Uint16List asUint16List([int offsetInBytes = 0, int length]) {
+    return new NativeUint16List.view(this, offsetInBytes, length);
+  }
+
+  Int16List asInt16List([int offsetInBytes = 0, int length]) {
+    return new NativeInt16List.view(this, offsetInBytes, length);
+  }
+
+  Uint32List asUint32List([int offsetInBytes = 0, int length]) {
+    return new NativeUint32List.view(this, offsetInBytes, length);
+  }
+
+  Int32List asInt32List([int offsetInBytes = 0, int length]) {
+    return new NativeInt32List.view(this, offsetInBytes, length);
+  }
+
+  Uint64List asUint64List([int offsetInBytes = 0, int length]) {
+    throw new UnsupportedError('Uint64List not supported by dart2js.');
+  }
+
+  Int64List asInt64List([int offsetInBytes = 0, int length]) {
+    throw new UnsupportedError('Int64List not supported by dart2js.');
+  }
+
+  Int32x4List asInt32x4List([int offsetInBytes = 0, int length]) {
+    NativeInt32List storage =
+        this.asInt32List(offsetInBytes, length != null ? length * 4 : null);
+    return new NativeInt32x4List._externalStorage(storage);
+  }
+
+  Float32List asFloat32List([int offsetInBytes = 0, int length]) {
+    return new NativeFloat32List.view(this, offsetInBytes, length);
+  }
+
+  Float64List asFloat64List([int offsetInBytes = 0, int length]) {
+    return new NativeFloat64List.view(this, offsetInBytes, length);
+  }
+
+  Float32x4List asFloat32x4List([int offsetInBytes = 0, int length]) {
+    NativeFloat32List storage =
+        this.asFloat32List(offsetInBytes, length != null ? length * 4 : null);
+    return new NativeFloat32x4List._externalStorage(storage);
+  }
+
+  Float64x2List asFloat64x2List([int offsetInBytes = 0, int length]) {
+    NativeFloat64List storage =
+        this.asFloat64List(offsetInBytes, length != null ? length * 2 : null);
+    return new NativeFloat64x2List._externalStorage(storage);
+  }
+
+  ByteData asByteData([int offsetInBytes = 0, int length]) {
+    return new NativeByteData.view(this, offsetInBytes, length);
+  }
+}
+
+/// A fixed-length list of Float32x4 numbers that is viewable as a
+/// [TypedData]. For long lists, this implementation will be considerably more
+/// space- and time-efficient than the default [List] implementation.
+class NativeFloat32x4List extends Object
+    with ListMixin<Float32x4>, FixedLengthListMixin<Float32x4>
+    implements Float32x4List {
+  final NativeFloat32List _storage;
+
+  /// Creates a [Float32x4List] of the specified length (in elements),
+  /// all of whose elements are initially zero.
+  NativeFloat32x4List(int length)
+      : _storage = new NativeFloat32List(length * 4);
+
+  NativeFloat32x4List._externalStorage(this._storage);
+
+  NativeFloat32x4List._slowFromList(List<Float32x4> list)
+      : _storage = new NativeFloat32List(list.length * 4) {
+    for (int i = 0; i < list.length; i++) {
+      var e = list[i];
+      _storage[(i * 4) + 0] = e.x;
+      _storage[(i * 4) + 1] = e.y;
+      _storage[(i * 4) + 2] = e.z;
+      _storage[(i * 4) + 3] = e.w;
+    }
+  }
+
+  Type get runtimeType => Float32x4List;
+
+  /// Creates a [Float32x4List] with the same size as the [elements] list
+  /// and copies over the elements.
+  factory NativeFloat32x4List.fromList(List<Float32x4> list) {
+    if (list is NativeFloat32x4List) {
+      return new NativeFloat32x4List._externalStorage(
+          new NativeFloat32List.fromList(list._storage));
+    } else {
+      return new NativeFloat32x4List._slowFromList(list);
+    }
+  }
+
+  ByteBuffer get buffer => _storage.buffer;
+
+  int get lengthInBytes => _storage.lengthInBytes;
+
+  int get offsetInBytes => _storage.offsetInBytes;
+
+  int get elementSizeInBytes => Float32x4List.bytesPerElement;
+
+  int get length => _storage.length ~/ 4;
+
+  Float32x4 operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    double _x = _storage[(index * 4) + 0];
+    double _y = _storage[(index * 4) + 1];
+    double _z = _storage[(index * 4) + 2];
+    double _w = _storage[(index * 4) + 3];
+    return new NativeFloat32x4._truncated(_x, _y, _z, _w);
+  }
+
+  void operator []=(int index, Float32x4 value) {
+    _checkValidIndex(index, this, this.length);
+    _storage[(index * 4) + 0] = value.x;
+    _storage[(index * 4) + 1] = value.y;
+    _storage[(index * 4) + 2] = value.z;
+    _storage[(index * 4) + 3] = value.w;
+  }
+
+  Float32x4List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    return new NativeFloat32x4List._externalStorage(
+        _storage.sublist(start * 4, end * 4));
+  }
+}
+
+/// A fixed-length list of Int32x4 numbers that is viewable as a
+/// [TypedData]. For long lists, this implementation will be considerably more
+/// space- and time-efficient than the default [List] implementation.
+class NativeInt32x4List extends Object
+    with ListMixin<Int32x4>, FixedLengthListMixin<Int32x4>
+    implements Int32x4List {
+  final Int32List _storage;
+
+  /// Creates a [Int32x4List] of the specified length (in elements),
+  /// all of whose elements are initially zero.
+  NativeInt32x4List(int length) : _storage = new NativeInt32List(length * 4);
+
+  NativeInt32x4List._externalStorage(Int32List storage) : _storage = storage;
+
+  NativeInt32x4List._slowFromList(List<Int32x4> list)
+      : _storage = new NativeInt32List(list.length * 4) {
+    for (int i = 0; i < list.length; i++) {
+      var e = list[i];
+      _storage[(i * 4) + 0] = e.x;
+      _storage[(i * 4) + 1] = e.y;
+      _storage[(i * 4) + 2] = e.z;
+      _storage[(i * 4) + 3] = e.w;
+    }
+  }
+
+  Type get runtimeType => Int32x4List;
+
+  /// Creates a [Int32x4List] with the same size as the [elements] list
+  /// and copies over the elements.
+  factory NativeInt32x4List.fromList(List<Int32x4> list) {
+    if (list is NativeInt32x4List) {
+      return new NativeInt32x4List._externalStorage(
+          new NativeInt32List.fromList(list._storage));
+    } else {
+      return new NativeInt32x4List._slowFromList(list);
+    }
+  }
+
+  ByteBuffer get buffer => _storage.buffer;
+
+  int get lengthInBytes => _storage.lengthInBytes;
+
+  int get offsetInBytes => _storage.offsetInBytes;
+
+  int get elementSizeInBytes => Int32x4List.bytesPerElement;
+
+  int get length => _storage.length ~/ 4;
+
+  Int32x4 operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    int _x = _storage[(index * 4) + 0];
+    int _y = _storage[(index * 4) + 1];
+    int _z = _storage[(index * 4) + 2];
+    int _w = _storage[(index * 4) + 3];
+    return new NativeInt32x4._truncated(_x, _y, _z, _w);
+  }
+
+  void operator []=(int index, Int32x4 value) {
+    _checkValidIndex(index, this, this.length);
+    _storage[(index * 4) + 0] = value.x;
+    _storage[(index * 4) + 1] = value.y;
+    _storage[(index * 4) + 2] = value.z;
+    _storage[(index * 4) + 3] = value.w;
+  }
+
+  Int32x4List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    return new NativeInt32x4List._externalStorage(
+        _storage.sublist(start * 4, end * 4));
+  }
+}
+
+/// A fixed-length list of Float64x2 numbers that is viewable as a
+/// [TypedData]. For long lists, this implementation will be considerably more
+/// space- and time-efficient than the default [List] implementation.
+class NativeFloat64x2List extends Object
+    with ListMixin<Float64x2>, FixedLengthListMixin<Float64x2>
+    implements Float64x2List {
+  final NativeFloat64List _storage;
+
+  /// Creates a [Float64x2List] of the specified length (in elements),
+  /// all of whose elements are initially zero.
+  NativeFloat64x2List(int length)
+      : _storage = new NativeFloat64List(length * 2);
+
+  NativeFloat64x2List._externalStorage(this._storage);
+
+  NativeFloat64x2List._slowFromList(List<Float64x2> list)
+      : _storage = new NativeFloat64List(list.length * 2) {
+    for (int i = 0; i < list.length; i++) {
+      var e = list[i];
+      _storage[(i * 2) + 0] = e.x;
+      _storage[(i * 2) + 1] = e.y;
+    }
+  }
+
+  /// Creates a [Float64x2List] with the same size as the [elements] list
+  /// and copies over the elements.
+  factory NativeFloat64x2List.fromList(List<Float64x2> list) {
+    if (list is NativeFloat64x2List) {
+      return new NativeFloat64x2List._externalStorage(
+          new NativeFloat64List.fromList(list._storage));
+    } else {
+      return new NativeFloat64x2List._slowFromList(list);
+    }
+  }
+
+  Type get runtimeType => Float64x2List;
+
+  ByteBuffer get buffer => _storage.buffer;
+
+  int get lengthInBytes => _storage.lengthInBytes;
+
+  int get offsetInBytes => _storage.offsetInBytes;
+
+  int get elementSizeInBytes => Float64x2List.bytesPerElement;
+
+  int get length => _storage.length ~/ 2;
+
+  Float64x2 operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    double _x = _storage[(index * 2) + 0];
+    double _y = _storage[(index * 2) + 1];
+    return new Float64x2(_x, _y);
+  }
+
+  void operator []=(int index, Float64x2 value) {
+    _checkValidIndex(index, this, this.length);
+    _storage[(index * 2) + 0] = value.x;
+    _storage[(index * 2) + 1] = value.y;
+  }
+
+  Float64x2List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    return new NativeFloat64x2List._externalStorage(
+        _storage.sublist(start * 2, end * 2));
+  }
+}
+
+@Native('ArrayBufferView')
+class NativeTypedData implements TypedData {
+  /// Returns the byte buffer associated with this object.
+  @Creates('NativeByteBuffer')
+  // May be Null for IE's CanvasPixelArray.
+  @Returns('NativeByteBuffer|Null')
+  final ByteBuffer buffer;
+
+  /// Returns the length of this view, in bytes.
+  @JSName('byteLength')
+  final int lengthInBytes;
+
+  /// Returns the offset in bytes into the underlying byte buffer of this view.
+  @JSName('byteOffset')
+  final int offsetInBytes;
+
+  /// Returns the number of bytes in the representation of each element in this
+  /// list.
+  @JSName('BYTES_PER_ELEMENT')
+  final int elementSizeInBytes;
+
+  void _invalidPosition(int position, int length, String name) {
+    if (position is! int) {
+      throw new ArgumentError.value(position, name, 'Invalid list position');
+    } else {
+      throw new RangeError.range(position, 0, length, name);
+    }
+  }
+
+  void _checkPosition(int position, int length, String name) {
+    if (JS('bool', '(# >>> 0) !== #', position, position) ||
+        JS('int', '#', position) > length) {
+      // 'int' guaranteed by above test.
+      _invalidPosition(position, length, name);
+    }
+  }
+}
+
+// Validates the unnamed constructor length argument.  Checking is necessary
+// because passing unvalidated values to the native constructors can cause
+// conversions or create views.
+int _checkLength(length) {
+  return length is int
+      ? length
+      : throw new ArgumentError('Invalid length $length');
+}
+
+// Validates `.view` constructor arguments.  Checking is necessary because
+// passing unvalidated values to the native constructors can cause conversions
+// (e.g. String arguments) or create typed data objects that are not actually
+// views of the input.
+void _checkViewArguments(buffer, offsetInBytes, length) {
+  if (buffer is! NativeByteBuffer) {
+    throw new ArgumentError('Invalid view buffer');
+  }
+  if (offsetInBytes is! int) {
+    throw new ArgumentError('Invalid view offsetInBytes $offsetInBytes');
+  }
+  if (length != null && length is! int) {
+    throw new ArgumentError('Invalid view length $length');
+  }
+}
+
+// Ensures that [list] is a JavaScript Array or a typed array.  If necessary,
+// returns a copy of the list.
+List _ensureNativeList(List list) {
+  if (list is JSIndexable) return list;
+  List result = new List(list.length);
+  for (int i = 0; i < list.length; i++) {
+    result[i] = list[i];
+  }
+  return result;
+}
+
+@Native('DataView')
+class NativeByteData extends NativeTypedData implements ByteData {
+  /// Creates a [ByteData] of the specified length (in elements), all of
+  /// whose elements are initially zero.
+  factory NativeByteData(int length) => _create1(_checkLength(length));
+
+  /// Creates an [ByteData] _view_ of the specified region in the specified
+  /// byte buffer. Changes in the [ByteData] will be visible in the byte
+  /// buffer and vice versa. If the [offsetInBytes] index of the region is not
+  /// specified, it defaults to zero (the first byte in the byte buffer).
+  /// If the length is not specified, it defaults to null, which indicates
+  /// that the view extends to the end of the byte buffer.
+  ///
+  /// Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+  /// if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+  /// the length of [buffer].
+  factory NativeByteData.view(
+      ByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => ByteData;
+
+  int get elementSizeInBytes => 1;
+
+  /// Returns the floating point number represented by the four bytes at
+  /// the specified [byteOffset] in this object, in IEEE 754
+  /// single-precision binary floating-point format (binary32).
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// `byteOffset + 4` is greater than the length of this object.
+  double getFloat32(int byteOffset, [Endian endian = Endian.big]) =>
+      _getFloat32(byteOffset, Endian.little == endian);
+
+  @JSName('getFloat32')
+  @Returns('num')
+  num _getFloat32(int byteOffset, [bool littleEndian]) native;
+
+  /// Returns the floating point number represented by the eight bytes at
+  /// the specified [byteOffset] in this object, in IEEE 754
+  /// double-precision binary floating-point format (binary64).
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// `byteOffset + 8` is greater than the length of this object.
+  double getFloat64(int byteOffset, [Endian endian = Endian.big]) =>
+      _getFloat64(byteOffset, Endian.little == endian);
+
+  @JSName('getFloat64')
+  @Returns('num')
+  num _getFloat64(int byteOffset, [bool littleEndian]) native;
+
+  /// Returns the (possibly negative) integer represented by the two bytes at
+  /// the specified [byteOffset] in this object, in two's complement binary
+  /// form.
+  /// The return value will be between 2<sup>15</sup> and 2<sup>15</sup> - 1,
+  /// inclusive.
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// `byteOffset + 2` is greater than the length of this object.
+  int getInt16(int byteOffset, [Endian endian = Endian.big]) =>
+      _getInt16(byteOffset, Endian.little == endian);
+
+  @JSName('getInt16')
+  @Returns('int')
+  int _getInt16(int byteOffset, [bool littleEndian]) native;
+
+  /// Returns the (possibly negative) integer represented by the four bytes at
+  /// the specified [byteOffset] in this object, in two's complement binary
+  /// form.
+  /// The return value will be between 2<sup>31</sup> and 2<sup>31</sup> - 1,
+  /// inclusive.
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// `byteOffset + 4` is greater than the length of this object.
+  int getInt32(int byteOffset, [Endian endian = Endian.big]) =>
+      _getInt32(byteOffset, Endian.little == endian);
+
+  @JSName('getInt32')
+  @Returns('int')
+  int _getInt32(int byteOffset, [bool littleEndian]) native;
+
+  /// Returns the (possibly negative) integer represented by the eight bytes at
+  /// the specified [byteOffset] in this object, in two's complement binary
+  /// form.
+  /// The return value will be between 2<sup>63</sup> and 2<sup>63</sup> - 1,
+  /// inclusive.
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// `byteOffset + 8` is greater than the length of this object.
+  int getInt64(int byteOffset, [Endian endian = Endian.big]) {
+    throw new UnsupportedError('Int64 accessor not supported by dart2js.');
+  }
+
+  /// Returns the (possibly negative) integer represented by the byte at the
+  /// specified [byteOffset] in this object, in two's complement binary
+  /// representation. The return value will be between -128 and 127, inclusive.
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// greater than or equal to the length of this object.
+  int getInt8(int byteOffset) native;
+
+  /// Returns the positive integer represented by the two bytes starting
+  /// at the specified [byteOffset] in this object, in unsigned binary
+  /// form.
+  /// The return value will be between 0 and  2<sup>16</sup> - 1, inclusive.
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// `byteOffset + 2` is greater than the length of this object.
+  int getUint16(int byteOffset, [Endian endian = Endian.big]) =>
+      _getUint16(byteOffset, Endian.little == endian);
+
+  @JSName('getUint16')
+  @Returns('JSUInt31')
+  int _getUint16(int byteOffset, [bool littleEndian]) native;
+
+  /// Returns the positive integer represented by the four bytes starting
+  /// at the specified [byteOffset] in this object, in unsigned binary
+  /// form.
+  /// The return value will be between 0 and  2<sup>32</sup> - 1, inclusive.
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// `byteOffset + 4` is greater than the length of this object.
+  int getUint32(int byteOffset, [Endian endian = Endian.big]) =>
+      _getUint32(byteOffset, Endian.little == endian);
+
+  @JSName('getUint32')
+  @Returns('JSUInt32')
+  int _getUint32(int byteOffset, [bool littleEndian]) native;
+
+  /// Returns the positive integer represented by the eight bytes starting
+  /// at the specified [byteOffset] in this object, in unsigned binary
+  /// form.
+  /// The return value will be between 0 and  2<sup>64</sup> - 1, inclusive.
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// `byteOffset + 8` is greater than the length of this object.
+  int getUint64(int byteOffset, [Endian endian = Endian.big]) {
+    throw new UnsupportedError('Uint64 accessor not supported by dart2js.');
+  }
+
+  /// Returns the positive integer represented by the byte at the specified
+  /// [byteOffset] in this object, in unsigned binary form. The
+  /// return value will be between 0 and 255, inclusive.
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// greater than or equal to the length of this object.
+  int getUint8(int byteOffset) native;
+
+  /// Sets the four bytes starting at the specified [byteOffset] in this
+  /// object to the IEEE 754 single-precision binary floating-point
+  /// (binary32) representation of the specified [value].
+  ///
+  /// **Note that this method can lose precision.** The input [value] is
+  /// a 64-bit floating point value, which will be converted to 32-bit
+  /// floating point value by IEEE 754 rounding rules before it is stored.
+  /// If [value] cannot be represented exactly as a binary32, it will be
+  /// converted to the nearest binary32 value.  If two binary32 values are
+  /// equally close, the one whose least significant bit is zero will be used.
+  /// Note that finite (but large) values can be converted to infinity, and
+  /// small non-zero values can be converted to zero.
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// `byteOffset + 4` is greater than the length of this object.
+  void setFloat32(int byteOffset, num value, [Endian endian = Endian.big]) =>
+      _setFloat32(byteOffset, value, Endian.little == endian);
+
+  @JSName('setFloat32')
+  void _setFloat32(int byteOffset, num value, [bool littleEndian]) native;
+
+  /// Sets the eight bytes starting at the specified [byteOffset] in this
+  /// object to the IEEE 754 double-precision binary floating-point
+  /// (binary64) representation of the specified [value].
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// `byteOffset + 8` is greater than the length of this object.
+  void setFloat64(int byteOffset, num value, [Endian endian = Endian.big]) =>
+      _setFloat64(byteOffset, value, Endian.little == endian);
+
+  @JSName('setFloat64')
+  void _setFloat64(int byteOffset, num value, [bool littleEndian]) native;
+
+  /// Sets the two bytes starting at the specified [byteOffset] in this
+  /// object to the two's complement binary representation of the specified
+  /// [value], which must fit in two bytes. In other words, [value] must lie
+  /// between 2<sup>15</sup> and 2<sup>15</sup> - 1, inclusive.
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// `byteOffset + 2` is greater than the length of this object.
+  void setInt16(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _setInt16(byteOffset, value, Endian.little == endian);
+
+  @JSName('setInt16')
+  void _setInt16(int byteOffset, int value, [bool littleEndian]) native;
+
+  /// Sets the four bytes starting at the specified [byteOffset] in this
+  /// object to the two's complement binary representation of the specified
+  /// [value], which must fit in four bytes. In other words, [value] must lie
+  /// between 2<sup>31</sup> and 2<sup>31</sup> - 1, inclusive.
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// `byteOffset + 4` is greater than the length of this object.
+  void setInt32(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _setInt32(byteOffset, value, Endian.little == endian);
+
+  @JSName('setInt32')
+  void _setInt32(int byteOffset, int value, [bool littleEndian]) native;
+
+  /// Sets the eight bytes starting at the specified [byteOffset] in this
+  /// object to the two's complement binary representation of the specified
+  /// [value], which must fit in eight bytes. In other words, [value] must lie
+  /// between 2<sup>63</sup> and 2<sup>63</sup> - 1, inclusive.
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// `byteOffset + 8` is greater than the length of this object.
+  void setInt64(int byteOffset, int value, [Endian endian = Endian.big]) {
+    throw new UnsupportedError('Int64 accessor not supported by dart2js.');
+  }
+
+  /// Sets the byte at the specified [byteOffset] in this object to the
+  /// two's complement binary representation of the specified [value], which
+  /// must fit in a single byte. In other words, [value] must be between
+  /// -128 and 127, inclusive.
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// greater than or equal to the length of this object.
+  void setInt8(int byteOffset, int value) native;
+
+  /// Sets the two bytes starting at the specified [byteOffset] in this object
+  /// to the unsigned binary representation of the specified [value],
+  /// which must fit in two bytes. in other words, [value] must be between
+  /// 0 and 2<sup>16</sup> - 1, inclusive.
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// `byteOffset + 2` is greater than the length of this object.
+  void setUint16(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _setUint16(byteOffset, value, Endian.little == endian);
+
+  @JSName('setUint16')
+  void _setUint16(int byteOffset, int value, [bool littleEndian]) native;
+
+  /// Sets the four bytes starting at the specified [byteOffset] in this object
+  /// to the unsigned binary representation of the specified [value],
+  /// which must fit in four bytes. in other words, [value] must be between
+  /// 0 and 2<sup>32</sup> - 1, inclusive.
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// `byteOffset + 4` is greater than the length of this object.
+  void setUint32(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _setUint32(byteOffset, value, Endian.little == endian);
+
+  @JSName('setUint32')
+  void _setUint32(int byteOffset, int value, [bool littleEndian]) native;
+
+  /// Sets the eight bytes starting at the specified [byteOffset] in this object
+  /// to the unsigned binary representation of the specified [value],
+  /// which must fit in eight bytes. in other words, [value] must be between
+  /// 0 and 2<sup>64</sup> - 1, inclusive.
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative, or
+  /// `byteOffset + 8` is greater than the length of this object.
+  void setUint64(int byteOffset, int value, [Endian endian = Endian.big]) {
+    throw new UnsupportedError('Uint64 accessor not supported by dart2js.');
+  }
+
+  /// Sets the byte at the specified [byteOffset] in this object to the
+  /// unsigned binary representation of the specified [value], which must fit
+  /// in a single byte. in other words, [value] must be between 0 and 255,
+  /// inclusive.
+  ///
+  /// Throws [RangeError] if [byteOffset] is negative,
+  /// or greater than or equal to the length of this object.
+  void setUint8(int byteOffset, int value) native;
+
+  static NativeByteData _create1(arg) =>
+      JS('NativeByteData', 'new DataView(new ArrayBuffer(#))', arg);
+
+  static NativeByteData _create2(arg1, arg2) =>
+      JS('NativeByteData', 'new DataView(#, #)', arg1, arg2);
+
+  static NativeByteData _create3(arg1, arg2, arg3) =>
+      JS('NativeByteData', 'new DataView(#, #, #)', arg1, arg2, arg3);
+}
+
+abstract class NativeTypedArray extends NativeTypedData
+    implements JavaScriptIndexingBehavior {
+  int get length => JS('JSUInt32', '#.length', this);
+
+  void _setRangeFast(
+      int start, int end, NativeTypedArray source, int skipCount) {
+    int targetLength = this.length;
+    _checkPosition(start, targetLength, 'start');
+    _checkPosition(end, targetLength, 'end');
+    if (start > end) throw new RangeError.range(start, 0, end);
+    int count = end - start;
+
+    if (skipCount < 0) throw new ArgumentError(skipCount);
+
+    int sourceLength = source.length;
+    if (sourceLength - skipCount < count) {
+      throw new StateError('Not enough elements');
+    }
+
+    if (skipCount != 0 || sourceLength != count) {
+      // Create a view of the exact subrange that is copied from the source.
+      source = JS('', '#.subarray(#, #)', source, skipCount, skipCount + count);
+    }
+    JS('void', '#.set(#, #)', this, source, start);
+  }
+}
+
+abstract class NativeTypedArrayOfDouble extends NativeTypedArray
+    with ListMixin<double>, FixedLengthListMixin<double> {
+  double operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    return JS('num', '#[#]', this, index);
+  }
+
+  void operator []=(int index, double value) {
+    _checkValidIndex(index, this, this.length);
+    JS('void', '#[#] = #', this, index, value);
+  }
+
+  void setRange(int start, int end, Iterable<double> iterable,
+      [int skipCount = 0]) {
+    if (iterable is NativeTypedArrayOfDouble) {
+      _setRangeFast(start, end, iterable, skipCount);
+      return;
+    }
+    super.setRange(start, end, iterable, skipCount);
+  }
+}
+
+abstract class NativeTypedArrayOfInt extends NativeTypedArray
+    with ListMixin<int>, FixedLengthListMixin<int>
+    implements List<int> {
+  // operator[]() is not here since different versions have different return
+  // types
+
+  void operator []=(int index, int value) {
+    _checkValidIndex(index, this, this.length);
+    JS('void', '#[#] = #', this, index, value);
+  }
+
+  void setRange(int start, int end, Iterable<int> iterable,
+      [int skipCount = 0]) {
+    if (iterable is NativeTypedArrayOfInt) {
+      _setRangeFast(start, end, iterable, skipCount);
+      return;
+    }
+    super.setRange(start, end, iterable, skipCount);
+  }
+}
+
+@Native('Float32Array')
+class NativeFloat32List extends NativeTypedArrayOfDouble
+    implements Float32List {
+  factory NativeFloat32List(int length) => _create1(_checkLength(length));
+
+  factory NativeFloat32List.fromList(List<double> elements) =>
+      _create1(_ensureNativeList(elements));
+
+  factory NativeFloat32List.view(
+      ByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => Float32List;
+
+  Float32List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    var source = JS('NativeFloat32List', '#.subarray(#, #)', this, start, end);
+    return _create1(source);
+  }
+
+  static NativeFloat32List _create1(arg) =>
+      JS('NativeFloat32List', 'new Float32Array(#)', arg);
+
+  static NativeFloat32List _create2(arg1, arg2) =>
+      JS('NativeFloat32List', 'new Float32Array(#, #)', arg1, arg2);
+
+  static NativeFloat32List _create3(arg1, arg2, arg3) =>
+      JS('NativeFloat32List', 'new Float32Array(#, #, #)', arg1, arg2, arg3);
+}
+
+@Native('Float64Array')
+class NativeFloat64List extends NativeTypedArrayOfDouble
+    implements Float64List {
+  factory NativeFloat64List(int length) => _create1(_checkLength(length));
+
+  factory NativeFloat64List.fromList(List<double> elements) =>
+      _create1(_ensureNativeList(elements));
+
+  factory NativeFloat64List.view(
+      ByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => Float64List;
+
+  Float64List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    var source = JS('NativeFloat64List', '#.subarray(#, #)', this, start, end);
+    return _create1(source);
+  }
+
+  static NativeFloat64List _create1(arg) =>
+      JS('NativeFloat64List', 'new Float64Array(#)', arg);
+
+  static NativeFloat64List _create2(arg1, arg2) =>
+      JS('NativeFloat64List', 'new Float64Array(#, #)', arg1, arg2);
+
+  static NativeFloat64List _create3(arg1, arg2, arg3) =>
+      JS('NativeFloat64List', 'new Float64Array(#, #, #)', arg1, arg2, arg3);
+}
+
+@Native('Int16Array')
+class NativeInt16List extends NativeTypedArrayOfInt implements Int16List {
+  factory NativeInt16List(int length) => _create1(_checkLength(length));
+
+  factory NativeInt16List.fromList(List<int> elements) =>
+      _create1(_ensureNativeList(elements));
+
+  factory NativeInt16List.view(
+      NativeByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => Int16List;
+
+  int operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    return JS('int', '#[#]', this, index);
+  }
+
+  Int16List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    var source = JS('NativeInt16List', '#.subarray(#, #)', this, start, end);
+    return _create1(source);
+  }
+
+  static NativeInt16List _create1(arg) =>
+      JS('NativeInt16List', 'new Int16Array(#)', arg);
+
+  static NativeInt16List _create2(arg1, arg2) =>
+      JS('NativeInt16List', 'new Int16Array(#, #)', arg1, arg2);
+
+  static NativeInt16List _create3(arg1, arg2, arg3) =>
+      JS('NativeInt16List', 'new Int16Array(#, #, #)', arg1, arg2, arg3);
+}
+
+@Native('Int32Array')
+class NativeInt32List extends NativeTypedArrayOfInt implements Int32List {
+  factory NativeInt32List(int length) => _create1(_checkLength(length));
+
+  factory NativeInt32List.fromList(List<int> elements) =>
+      _create1(_ensureNativeList(elements));
+
+  factory NativeInt32List.view(
+      ByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => Int32List;
+
+  int operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    return JS('int', '#[#]', this, index);
+  }
+
+  Int32List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    var source = JS('NativeInt32List', '#.subarray(#, #)', this, start, end);
+    return _create1(source);
+  }
+
+  static NativeInt32List _create1(arg) =>
+      JS('NativeInt32List', 'new Int32Array(#)', arg);
+
+  static NativeInt32List _create2(arg1, arg2) =>
+      JS('NativeInt32List', 'new Int32Array(#, #)', arg1, arg2);
+
+  static NativeInt32List _create3(arg1, arg2, arg3) =>
+      JS('NativeInt32List', 'new Int32Array(#, #, #)', arg1, arg2, arg3);
+}
+
+@Native('Int8Array')
+class NativeInt8List extends NativeTypedArrayOfInt implements Int8List {
+  factory NativeInt8List(int length) => _create1(_checkLength(length));
+
+  factory NativeInt8List.fromList(List<int> elements) =>
+      _create1(_ensureNativeList(elements));
+
+  factory NativeInt8List.view(
+      ByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => Int8List;
+
+  int operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    return JS('int', '#[#]', this, index);
+  }
+
+  Int8List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    var source = JS('NativeInt8List', '#.subarray(#, #)', this, start, end);
+    return _create1(source);
+  }
+
+  static NativeInt8List _create1(arg) =>
+      JS('NativeInt8List', 'new Int8Array(#)', arg);
+
+  static NativeInt8List _create2(arg1, arg2) =>
+      JS('NativeInt8List', 'new Int8Array(#, #)', arg1, arg2);
+
+  static Int8List _create3(arg1, arg2, arg3) =>
+      JS('NativeInt8List', 'new Int8Array(#, #, #)', arg1, arg2, arg3);
+}
+
+@Native('Uint16Array')
+class NativeUint16List extends NativeTypedArrayOfInt implements Uint16List {
+  factory NativeUint16List(int length) => _create1(_checkLength(length));
+
+  factory NativeUint16List.fromList(List<int> list) =>
+      _create1(_ensureNativeList(list));
+
+  factory NativeUint16List.view(
+      ByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => Uint16List;
+
+  int operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    return JS('JSUInt31', '#[#]', this, index);
+  }
+
+  Uint16List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    var source = JS('NativeUint16List', '#.subarray(#, #)', this, start, end);
+    return _create1(source);
+  }
+
+  static NativeUint16List _create1(arg) =>
+      JS('NativeUint16List', 'new Uint16Array(#)', arg);
+
+  static NativeUint16List _create2(arg1, arg2) =>
+      JS('NativeUint16List', 'new Uint16Array(#, #)', arg1, arg2);
+
+  static NativeUint16List _create3(arg1, arg2, arg3) =>
+      JS('NativeUint16List', 'new Uint16Array(#, #, #)', arg1, arg2, arg3);
+}
+
+@Native('Uint32Array')
+class NativeUint32List extends NativeTypedArrayOfInt implements Uint32List {
+  factory NativeUint32List(int length) => _create1(_checkLength(length));
+
+  factory NativeUint32List.fromList(List<int> elements) =>
+      _create1(_ensureNativeList(elements));
+
+  factory NativeUint32List.view(
+      ByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => Uint32List;
+
+  int operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    return JS('JSUInt32', '#[#]', this, index);
+  }
+
+  Uint32List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    var source = JS('NativeUint32List', '#.subarray(#, #)', this, start, end);
+    return _create1(source);
+  }
+
+  static NativeUint32List _create1(arg) =>
+      JS('NativeUint32List', 'new Uint32Array(#)', arg);
+
+  static NativeUint32List _create2(arg1, arg2) =>
+      JS('NativeUint32List', 'new Uint32Array(#, #)', arg1, arg2);
+
+  static NativeUint32List _create3(arg1, arg2, arg3) =>
+      JS('NativeUint32List', 'new Uint32Array(#, #, #)', arg1, arg2, arg3);
+}
+
+@Native('Uint8ClampedArray,CanvasPixelArray')
+class NativeUint8ClampedList extends NativeTypedArrayOfInt
+    implements Uint8ClampedList {
+  factory NativeUint8ClampedList(int length) => _create1(_checkLength(length));
+
+  factory NativeUint8ClampedList.fromList(List<int> elements) =>
+      _create1(_ensureNativeList(elements));
+
+  factory NativeUint8ClampedList.view(
+      ByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => Uint8ClampedList;
+
+  int get length => JS('JSUInt32', '#.length', this);
+
+  int operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    return JS('JSUInt31', '#[#]', this, index);
+  }
+
+  Uint8ClampedList sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    var source =
+        JS('NativeUint8ClampedList', '#.subarray(#, #)', this, start, end);
+    return _create1(source);
+  }
+
+  static NativeUint8ClampedList _create1(arg) =>
+      JS('NativeUint8ClampedList', 'new Uint8ClampedArray(#)', arg);
+
+  static NativeUint8ClampedList _create2(arg1, arg2) =>
+      JS('NativeUint8ClampedList', 'new Uint8ClampedArray(#, #)', arg1, arg2);
+
+  static NativeUint8ClampedList _create3(arg1, arg2, arg3) => JS(
+      'NativeUint8ClampedList',
+      'new Uint8ClampedArray(#, #, #)',
+      arg1,
+      arg2,
+      arg3);
+}
+
+// On some browsers Uint8ClampedArray is a subtype of Uint8Array.  Marking
+// Uint8List as !nonleaf ensures that the native dispatch correctly handles
+// the potential for Uint8ClampedArray to 'accidentally' pick up the
+// dispatch record for Uint8List.
+@Native('Uint8Array,!nonleaf')
+class NativeUint8List extends NativeTypedArrayOfInt implements Uint8List {
+  factory NativeUint8List(int length) => _create1(_checkLength(length));
+
+  factory NativeUint8List.fromList(List<int> elements) =>
+      _create1(_ensureNativeList(elements));
+
+  factory NativeUint8List.view(
+      ByteBuffer buffer, int offsetInBytes, int length) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
+
+  Type get runtimeType => Uint8List;
+
+  int get length => JS('JSUInt32', '#.length', this);
+
+  int operator [](int index) {
+    _checkValidIndex(index, this, this.length);
+    return JS('JSUInt31', '#[#]', this, index);
+  }
+
+  Uint8List sublist(int start, [int end]) {
+    end = _checkValidRange(start, end, this.length);
+    var source = JS('NativeUint8List', '#.subarray(#, #)', this, start, end);
+    return _create1(source);
+  }
+
+  static NativeUint8List _create1(arg) =>
+      JS('NativeUint8List', 'new Uint8Array(#)', arg);
+
+  static NativeUint8List _create2(arg1, arg2) =>
+      JS('NativeUint8List', 'new Uint8Array(#, #)', arg1, arg2);
+
+  static NativeUint8List _create3(arg1, arg2, arg3) =>
+      JS('NativeUint8List', 'new Uint8Array(#, #, #)', arg1, arg2, arg3);
+}
+
+/// Implementation of Dart Float32x4 immutable value type and operations.
+/// Float32x4 stores 4 32-bit floating point values in "lanes".
+/// The lanes are "x", "y", "z", and "w" respectively.
+class NativeFloat32x4 implements Float32x4 {
+  final double x;
+  final double y;
+  final double z;
+  final double w;
+
+  static final NativeFloat32List _list = new NativeFloat32List(4);
+  static final Uint32List _uint32view = _list.buffer.asUint32List();
+
+  static _truncate(x) {
+    _list[0] = x;
+    return _list[0];
+  }
+
+  NativeFloat32x4(double x, double y, double z, double w)
+      : this.x = _truncate(x),
+        this.y = _truncate(y),
+        this.z = _truncate(z),
+        this.w = _truncate(w) {
+    // We would prefer to check for `double` but in dart2js we can't see the
+    // difference anyway.
+    if (x is! num) throw new ArgumentError(x);
+    if (y is! num) throw new ArgumentError(y);
+    if (z is! num) throw new ArgumentError(z);
+    if (w is! num) throw new ArgumentError(w);
+  }
+
+  NativeFloat32x4.splat(double v) : this(v, v, v, v);
+  NativeFloat32x4.zero() : this._truncated(0.0, 0.0, 0.0, 0.0);
+
+  /// Returns a bit-wise copy of [i] as a Float32x4.
+  factory NativeFloat32x4.fromInt32x4Bits(Int32x4 i) {
+    _uint32view[0] = i.x;
+    _uint32view[1] = i.y;
+    _uint32view[2] = i.z;
+    _uint32view[3] = i.w;
+    return new NativeFloat32x4._truncated(
+        _list[0], _list[1], _list[2], _list[3]);
+  }
+
+  NativeFloat32x4.fromFloat64x2(Float64x2 v)
+      : this._truncated(_truncate(v.x), _truncate(v.y), 0.0, 0.0);
+
+  /// Creates a new NativeFloat32x4.
+  ///
+  /// Does not verify if the given arguments are non-null.
+  NativeFloat32x4._doubles(double x, double y, double z, double w)
+      : this.x = _truncate(x),
+        this.y = _truncate(y),
+        this.z = _truncate(z),
+        this.w = _truncate(w);
+
+  /// Creates a new NativeFloat32x4.
+  ///
+  /// The constructor does not truncate the arguments. They must already be in
+  /// the correct range. It does not verify the type of the given arguments,
+  /// either.
+  NativeFloat32x4._truncated(this.x, this.y, this.z, this.w);
+
+  String toString() {
+    return '[$x, $y, $z, $w]';
+  }
+
+  /// Addition operator.
+  Float32x4 operator +(Float32x4 other) {
+    double _x = x + other.x;
+    double _y = y + other.y;
+    double _z = z + other.z;
+    double _w = w + other.w;
+    return new NativeFloat32x4._doubles(_x, _y, _z, _w);
+  }
+
+  /// Negate operator.
+  Float32x4 operator -() {
+    return new NativeFloat32x4._truncated(-x, -y, -z, -w);
+  }
+
+  /// Subtraction operator.
+  Float32x4 operator -(Float32x4 other) {
+    double _x = x - other.x;
+    double _y = y - other.y;
+    double _z = z - other.z;
+    double _w = w - other.w;
+    return new NativeFloat32x4._doubles(_x, _y, _z, _w);
+  }
+
+  /// Multiplication operator.
+  Float32x4 operator *(Float32x4 other) {
+    double _x = x * other.x;
+    double _y = y * other.y;
+    double _z = z * other.z;
+    double _w = w * other.w;
+    return new NativeFloat32x4._doubles(_x, _y, _z, _w);
+  }
+
+  /// Division operator.
+  Float32x4 operator /(Float32x4 other) {
+    double _x = x / other.x;
+    double _y = y / other.y;
+    double _z = z / other.z;
+    double _w = w / other.w;
+    return new NativeFloat32x4._doubles(_x, _y, _z, _w);
+  }
+
+  /// Relational less than.
+  Int32x4 lessThan(Float32x4 other) {
+    bool _cx = x < other.x;
+    bool _cy = y < other.y;
+    bool _cz = z < other.z;
+    bool _cw = w < other.w;
+    return new NativeInt32x4._truncated(
+        _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
+  }
+
+  /// Relational less than or equal.
+  Int32x4 lessThanOrEqual(Float32x4 other) {
+    bool _cx = x <= other.x;
+    bool _cy = y <= other.y;
+    bool _cz = z <= other.z;
+    bool _cw = w <= other.w;
+    return new NativeInt32x4._truncated(
+        _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
+  }
+
+  /// Relational greater than.
+  Int32x4 greaterThan(Float32x4 other) {
+    bool _cx = x > other.x;
+    bool _cy = y > other.y;
+    bool _cz = z > other.z;
+    bool _cw = w > other.w;
+    return new NativeInt32x4._truncated(
+        _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
+  }
+
+  /// Relational greater than or equal.
+  Int32x4 greaterThanOrEqual(Float32x4 other) {
+    bool _cx = x >= other.x;
+    bool _cy = y >= other.y;
+    bool _cz = z >= other.z;
+    bool _cw = w >= other.w;
+    return new NativeInt32x4._truncated(
+        _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
+  }
+
+  /// Relational equal.
+  Int32x4 equal(Float32x4 other) {
+    bool _cx = x == other.x;
+    bool _cy = y == other.y;
+    bool _cz = z == other.z;
+    bool _cw = w == other.w;
+    return new NativeInt32x4._truncated(
+        _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
+  }
+
+  /// Relational not-equal.
+  Int32x4 notEqual(Float32x4 other) {
+    bool _cx = x != other.x;
+    bool _cy = y != other.y;
+    bool _cz = z != other.z;
+    bool _cw = w != other.w;
+    return new NativeInt32x4._truncated(
+        _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
+  }
+
+  /// Returns a copy of [this] each lane being scaled by [s].
+  Float32x4 scale(double s) {
+    double _x = s * x;
+    double _y = s * y;
+    double _z = s * z;
+    double _w = s * w;
+    return new NativeFloat32x4._doubles(_x, _y, _z, _w);
+  }
+
+  /// Returns the absolute value of this [Float32x4].
+  Float32x4 abs() {
+    double _x = x.abs();
+    double _y = y.abs();
+    double _z = z.abs();
+    double _w = w.abs();
+    return new NativeFloat32x4._truncated(_x, _y, _z, _w);
+  }
+
+  /// Clamps [this] to be in the range [lowerLimit]-[upperLimit].
+  Float32x4 clamp(Float32x4 lowerLimit, Float32x4 upperLimit) {
+    double _lx = lowerLimit.x;
+    double _ly = lowerLimit.y;
+    double _lz = lowerLimit.z;
+    double _lw = lowerLimit.w;
+    double _ux = upperLimit.x;
+    double _uy = upperLimit.y;
+    double _uz = upperLimit.z;
+    double _uw = upperLimit.w;
+    double _x = x;
+    double _y = y;
+    double _z = z;
+    double _w = w;
+    // MAX(MIN(self, upper), lower).
+    _x = _x > _ux ? _ux : _x;
+    _y = _y > _uy ? _uy : _y;
+    _z = _z > _uz ? _uz : _z;
+    _w = _w > _uw ? _uw : _w;
+    _x = _x < _lx ? _lx : _x;
+    _y = _y < _ly ? _ly : _y;
+    _z = _z < _lz ? _lz : _z;
+    _w = _w < _lw ? _lw : _w;
+    return new NativeFloat32x4._truncated(_x, _y, _z, _w);
+  }
+
+  /// Extract the sign bit from each lane return them in the first 4 bits.
+  int get signMask {
+    var view = _uint32view;
+    var mx, my, mz, mw;
+    _list[0] = x;
+    _list[1] = y;
+    _list[2] = z;
+    _list[3] = w;
+    // This is correct because dart2js uses the unsigned right shift.
+    mx = (view[0] & 0x80000000) >> 31;
+    my = (view[1] & 0x80000000) >> 30;
+    mz = (view[2] & 0x80000000) >> 29;
+    mw = (view[3] & 0x80000000) >> 28;
+    return mx | my | mz | mw;
+  }
+
+  /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
+  Float32x4 shuffle(int mask) {
+    if ((mask < 0) || (mask > 255)) {
+      throw new RangeError.range(mask, 0, 255, 'mask');
+    }
+    _list[0] = x;
+    _list[1] = y;
+    _list[2] = z;
+    _list[3] = w;
+
+    double _x = _list[mask & 0x3];
+    double _y = _list[(mask >> 2) & 0x3];
+    double _z = _list[(mask >> 4) & 0x3];
+    double _w = _list[(mask >> 6) & 0x3];
+    return new NativeFloat32x4._truncated(_x, _y, _z, _w);
+  }
+
+  /// Shuffle the lane values in [this] and [other]. The returned
+  /// Float32x4 will have XY lanes from [this] and ZW lanes from [other].
+  /// Uses the same [mask] as [shuffle].
+  Float32x4 shuffleMix(Float32x4 other, int mask) {
+    if ((mask < 0) || (mask > 255)) {
+      throw new RangeError.range(mask, 0, 255, 'mask');
+    }
+    _list[0] = x;
+    _list[1] = y;
+    _list[2] = z;
+    _list[3] = w;
+    double _x = _list[mask & 0x3];
+    double _y = _list[(mask >> 2) & 0x3];
+
+    _list[0] = other.x;
+    _list[1] = other.y;
+    _list[2] = other.z;
+    _list[3] = other.w;
+    double _z = _list[(mask >> 4) & 0x3];
+    double _w = _list[(mask >> 6) & 0x3];
+    return new NativeFloat32x4._truncated(_x, _y, _z, _w);
+  }
+
+  /// Copy [this] and replace the [x] lane.
+  Float32x4 withX(double newX) {
+    return new NativeFloat32x4._truncated(_truncate(newX), y, z, w);
+  }
+
+  /// Copy [this] and replace the [y] lane.
+  Float32x4 withY(double newY) {
+    return new NativeFloat32x4._truncated(x, _truncate(newY), z, w);
+  }
+
+  /// Copy [this] and replace the [z] lane.
+  Float32x4 withZ(double newZ) {
+    return new NativeFloat32x4._truncated(x, y, _truncate(newZ), w);
+  }
+
+  /// Copy [this] and replace the [w] lane.
+  Float32x4 withW(double newW) {
+    return new NativeFloat32x4._truncated(x, y, z, _truncate(newW));
+  }
+
+  /// Returns the lane-wise minimum value in [this] or [other].
+  Float32x4 min(Float32x4 other) {
+    double _x = x < other.x ? x : other.x;
+    double _y = y < other.y ? y : other.y;
+    double _z = z < other.z ? z : other.z;
+    double _w = w < other.w ? w : other.w;
+    return new NativeFloat32x4._truncated(_x, _y, _z, _w);
+  }
+
+  /// Returns the lane-wise maximum value in [this] or [other].
+  Float32x4 max(Float32x4 other) {
+    double _x = x > other.x ? x : other.x;
+    double _y = y > other.y ? y : other.y;
+    double _z = z > other.z ? z : other.z;
+    double _w = w > other.w ? w : other.w;
+    return new NativeFloat32x4._truncated(_x, _y, _z, _w);
+  }
+
+  /// Returns the square root of [this].
+  Float32x4 sqrt() {
+    double _x = Math.sqrt(x);
+    double _y = Math.sqrt(y);
+    double _z = Math.sqrt(z);
+    double _w = Math.sqrt(w);
+    return new NativeFloat32x4._doubles(_x, _y, _z, _w);
+  }
+
+  /// Returns the reciprocal of [this].
+  Float32x4 reciprocal() {
+    double _x = 1.0 / x;
+    double _y = 1.0 / y;
+    double _z = 1.0 / z;
+    double _w = 1.0 / w;
+    return new NativeFloat32x4._doubles(_x, _y, _z, _w);
+  }
+
+  /// Returns the square root of the reciprocal of [this].
+  Float32x4 reciprocalSqrt() {
+    double _x = Math.sqrt(1.0 / x);
+    double _y = Math.sqrt(1.0 / y);
+    double _z = Math.sqrt(1.0 / z);
+    double _w = Math.sqrt(1.0 / w);
+    return new NativeFloat32x4._doubles(_x, _y, _z, _w);
+  }
+}
+
+/// Interface of Dart Int32x4 and operations.
+/// Int32x4 stores 4 32-bit bit-masks in "lanes".
+/// The lanes are "x", "y", "z", and "w" respectively.
+class NativeInt32x4 implements Int32x4 {
+  final int x;
+  final int y;
+  final int z;
+  final int w;
+
+  static final _list = new NativeInt32List(4);
+
+  static _truncate(x) {
+    _list[0] = x;
+    return _list[0];
+  }
+
+  NativeInt32x4(int x, int y, int z, int w)
+      : this.x = _truncate(x),
+        this.y = _truncate(y),
+        this.z = _truncate(z),
+        this.w = _truncate(w) {
+    if (x != this.x && x is! int) throw new ArgumentError(x);
+    if (y != this.y && y is! int) throw new ArgumentError(y);
+    if (z != this.z && z is! int) throw new ArgumentError(z);
+    if (w != this.w && w is! int) throw new ArgumentError(w);
+  }
+
+  NativeInt32x4.bool(bool x, bool y, bool z, bool w)
+      : this.x = x ? -1 : 0,
+        this.y = y ? -1 : 0,
+        this.z = z ? -1 : 0,
+        this.w = w ? -1 : 0;
+
+  /// Returns a bit-wise copy of [f] as a Int32x4.
+  factory NativeInt32x4.fromFloat32x4Bits(Float32x4 f) {
+    NativeFloat32List floatList = NativeFloat32x4._list;
+    floatList[0] = f.x;
+    floatList[1] = f.y;
+    floatList[2] = f.z;
+    floatList[3] = f.w;
+    NativeInt32List view = floatList.buffer.asInt32List();
+    return new NativeInt32x4._truncated(view[0], view[1], view[2], view[3]);
+  }
+
+  NativeInt32x4._truncated(this.x, this.y, this.z, this.w);
+
+  String toString() => '[$x, $y, $z, $w]';
+
+  /// The bit-wise or operator.
+  Int32x4 operator |(Int32x4 other) {
+    // Dart2js uses unsigned results for bit-operations.
+    // We use "JS" to fall back to the signed versions.
+    return new NativeInt32x4._truncated(
+        JS('int', '# | #', x, other.x),
+        JS('int', '# | #', y, other.y),
+        JS('int', '# | #', z, other.z),
+        JS('int', '# | #', w, other.w));
+  }
+
+  /// The bit-wise and operator.
+  Int32x4 operator &(Int32x4 other) {
+    // Dart2js uses unsigned results for bit-operations.
+    // We use "JS" to fall back to the signed versions.
+    return new NativeInt32x4._truncated(
+        JS('int', '# & #', x, other.x),
+        JS('int', '# & #', y, other.y),
+        JS('int', '# & #', z, other.z),
+        JS('int', '# & #', w, other.w));
+  }
+
+  /// The bit-wise xor operator.
+  Int32x4 operator ^(Int32x4 other) {
+    // Dart2js uses unsigned results for bit-operations.
+    // We use "JS" to fall back to the signed versions.
+    return new NativeInt32x4._truncated(
+        JS('int', '# ^ #', x, other.x),
+        JS('int', '# ^ #', y, other.y),
+        JS('int', '# ^ #', z, other.z),
+        JS('int', '# ^ #', w, other.w));
+  }
+
+  Int32x4 operator +(Int32x4 other) {
+    // Avoid going through the typed array by "| 0" the result.
+    return new NativeInt32x4._truncated(
+        JS('int', '(# + #) | 0', x, other.x),
+        JS('int', '(# + #) | 0', y, other.y),
+        JS('int', '(# + #) | 0', z, other.z),
+        JS('int', '(# + #) | 0', w, other.w));
+  }
+
+  Int32x4 operator -(Int32x4 other) {
+    // Avoid going through the typed array by "| 0" the result.
+    return new NativeInt32x4._truncated(
+        JS('int', '(# - #) | 0', x, other.x),
+        JS('int', '(# - #) | 0', y, other.y),
+        JS('int', '(# - #) | 0', z, other.z),
+        JS('int', '(# - #) | 0', w, other.w));
+  }
+
+  Int32x4 operator -() {
+    // Avoid going through the typed array by "| 0" the result.
+    return new NativeInt32x4._truncated(
+        JS('int', '(-#) | 0', x),
+        JS('int', '(-#) | 0', y),
+        JS('int', '(-#) | 0', z),
+        JS('int', '(-#) | 0', w));
+  }
+
+  /// Extract the top bit from each lane return them in the first 4 bits.
+  int get signMask {
+    int mx = (x & 0x80000000) >> 31;
+    int my = (y & 0x80000000) >> 31;
+    int mz = (z & 0x80000000) >> 31;
+    int mw = (w & 0x80000000) >> 31;
+    return mx | my << 1 | mz << 2 | mw << 3;
+  }
+
+  /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
+  Int32x4 shuffle(int mask) {
+    if ((mask < 0) || (mask > 255)) {
+      throw new RangeError.range(mask, 0, 255, 'mask');
+    }
+    _list[0] = x;
+    _list[1] = y;
+    _list[2] = z;
+    _list[3] = w;
+    int _x = _list[mask & 0x3];
+    int _y = _list[(mask >> 2) & 0x3];
+    int _z = _list[(mask >> 4) & 0x3];
+    int _w = _list[(mask >> 6) & 0x3];
+    return new NativeInt32x4._truncated(_x, _y, _z, _w);
+  }
+
+  /// Shuffle the lane values in [this] and [other]. The returned
+  /// Int32x4 will have XY lanes from [this] and ZW lanes from [other].
+  /// Uses the same [mask] as [shuffle].
+  Int32x4 shuffleMix(Int32x4 other, int mask) {
+    if ((mask < 0) || (mask > 255)) {
+      throw new RangeError.range(mask, 0, 255, 'mask');
+    }
+    _list[0] = x;
+    _list[1] = y;
+    _list[2] = z;
+    _list[3] = w;
+    int _x = _list[mask & 0x3];
+    int _y = _list[(mask >> 2) & 0x3];
+
+    _list[0] = other.x;
+    _list[1] = other.y;
+    _list[2] = other.z;
+    _list[3] = other.w;
+    int _z = _list[(mask >> 4) & 0x3];
+    int _w = _list[(mask >> 6) & 0x3];
+    return new NativeInt32x4._truncated(_x, _y, _z, _w);
+  }
+
+  /// Returns a new [Int32x4] copied from [this] with a new x value.
+  Int32x4 withX(int x) {
+    int _x = _truncate(x);
+    return new NativeInt32x4._truncated(_x, y, z, w);
+  }
+
+  /// Returns a new [Int32x4] copied from [this] with a new y value.
+  Int32x4 withY(int y) {
+    int _y = _truncate(y);
+    return new NativeInt32x4._truncated(x, _y, z, w);
+  }
+
+  /// Returns a new [Int32x4] copied from [this] with a new z value.
+  Int32x4 withZ(int z) {
+    int _z = _truncate(z);
+    return new NativeInt32x4._truncated(x, y, _z, w);
+  }
+
+  /// Returns a new [Int32x4] copied from [this] with a new w value.
+  Int32x4 withW(int w) {
+    int _w = _truncate(w);
+    return new NativeInt32x4._truncated(x, y, z, _w);
+  }
+
+  /// Extracted x value. Returns `false` for 0, `true` for any other value.
+  bool get flagX => x != 0;
+
+  /// Extracted y value. Returns `false` for 0, `true` for any other value.
+  bool get flagY => y != 0;
+
+  /// Extracted z value. Returns `false` for 0, `true` for any other value.
+  bool get flagZ => z != 0;
+
+  /// Extracted w value. Returns `false` for 0, `true` for any other value.
+  bool get flagW => w != 0;
+
+  /// Returns a new [Int32x4] copied from [this] with a new x value.
+  Int32x4 withFlagX(bool flagX) {
+    int _x = flagX ? -1 : 0;
+    return new NativeInt32x4._truncated(_x, y, z, w);
+  }
+
+  /// Returns a new [Int32x4] copied from [this] with a new y value.
+  Int32x4 withFlagY(bool flagY) {
+    int _y = flagY ? -1 : 0;
+    return new NativeInt32x4._truncated(x, _y, z, w);
+  }
+
+  /// Returns a new [Int32x4] copied from [this] with a new z value.
+  Int32x4 withFlagZ(bool flagZ) {
+    int _z = flagZ ? -1 : 0;
+    return new NativeInt32x4._truncated(x, y, _z, w);
+  }
+
+  /// Returns a new [Int32x4] copied from [this] with a new w value.
+  Int32x4 withFlagW(bool flagW) {
+    int _w = flagW ? -1 : 0;
+    return new NativeInt32x4._truncated(x, y, z, _w);
+  }
+
+  /// Merge [trueValue] and [falseValue] based on [this]' bit mask:
+  /// Select bit from [trueValue] when bit in [this] is on.
+  /// Select bit from [falseValue] when bit in [this] is off.
+  Float32x4 select(Float32x4 trueValue, Float32x4 falseValue) {
+    var floatList = NativeFloat32x4._list;
+    var intView = NativeFloat32x4._uint32view;
+
+    floatList[0] = trueValue.x;
+    floatList[1] = trueValue.y;
+    floatList[2] = trueValue.z;
+    floatList[3] = trueValue.w;
+    int stx = intView[0];
+    int sty = intView[1];
+    int stz = intView[2];
+    int stw = intView[3];
+
+    floatList[0] = falseValue.x;
+    floatList[1] = falseValue.y;
+    floatList[2] = falseValue.z;
+    floatList[3] = falseValue.w;
+    int sfx = intView[0];
+    int sfy = intView[1];
+    int sfz = intView[2];
+    int sfw = intView[3];
+    int _x = (x & stx) | (~x & sfx);
+    int _y = (y & sty) | (~y & sfy);
+    int _z = (z & stz) | (~z & sfz);
+    int _w = (w & stw) | (~w & sfw);
+    intView[0] = _x;
+    intView[1] = _y;
+    intView[2] = _z;
+    intView[3] = _w;
+    return new NativeFloat32x4._truncated(
+        floatList[0], floatList[1], floatList[2], floatList[3]);
+  }
+}
+
+class NativeFloat64x2 implements Float64x2 {
+  final double x;
+  final double y;
+
+  static NativeFloat64List _list = new NativeFloat64List(2);
+  static NativeUint32List _uint32View = _list.buffer.asUint32List();
+
+  NativeFloat64x2(this.x, this.y) {
+    if (x is! num) throw new ArgumentError(x);
+    if (y is! num) throw new ArgumentError(y);
+  }
+
+  NativeFloat64x2.splat(double v) : this(v, v);
+
+  NativeFloat64x2.zero() : this.splat(0.0);
+
+  NativeFloat64x2.fromFloat32x4(Float32x4 v) : this(v.x, v.y);
+
+  /// Arguments [x] and [y] must be doubles.
+  NativeFloat64x2._doubles(this.x, this.y);
+
+  String toString() => '[$x, $y]';
+
+  /// Addition operator.
+  Float64x2 operator +(Float64x2 other) {
+    return new NativeFloat64x2._doubles(x + other.x, y + other.y);
+  }
+
+  /// Negate operator.
+  Float64x2 operator -() {
+    return new NativeFloat64x2._doubles(-x, -y);
+  }
+
+  /// Subtraction operator.
+  Float64x2 operator -(Float64x2 other) {
+    return new NativeFloat64x2._doubles(x - other.x, y - other.y);
+  }
+
+  /// Multiplication operator.
+  Float64x2 operator *(Float64x2 other) {
+    return new NativeFloat64x2._doubles(x * other.x, y * other.y);
+  }
+
+  /// Division operator.
+  Float64x2 operator /(Float64x2 other) {
+    return new NativeFloat64x2._doubles(x / other.x, y / other.y);
+  }
+
+  /// Returns a copy of [this] each lane being scaled by [s].
+  Float64x2 scale(double s) {
+    return new NativeFloat64x2._doubles(x * s, y * s);
+  }
+
+  /// Returns the absolute value of this [Float64x2].
+  Float64x2 abs() {
+    return new NativeFloat64x2._doubles(x.abs(), y.abs());
+  }
+
+  /// Clamps [this] to be in the range [lowerLimit]-[upperLimit].
+  Float64x2 clamp(Float64x2 lowerLimit, Float64x2 upperLimit) {
+    double _lx = lowerLimit.x;
+    double _ly = lowerLimit.y;
+    double _ux = upperLimit.x;
+    double _uy = upperLimit.y;
+    double _x = x;
+    double _y = y;
+    // MAX(MIN(self, upper), lower).
+    _x = _x > _ux ? _ux : _x;
+    _y = _y > _uy ? _uy : _y;
+    _x = _x < _lx ? _lx : _x;
+    _y = _y < _ly ? _ly : _y;
+    return new NativeFloat64x2._doubles(_x, _y);
+  }
+
+  /// Extract the sign bits from each lane return them in the first 2 bits.
+  int get signMask {
+    var view = _uint32View;
+    _list[0] = x;
+    _list[1] = y;
+    var mx = (view[1] & 0x80000000) >> 31;
+    var my = (view[3] & 0x80000000) >> 31;
+    return mx | my << 1;
+  }
+
+  /// Returns a new [Float64x2] copied from [this] with a new x value.
+  Float64x2 withX(double x) {
+    if (x is! num) throw new ArgumentError(x);
+    return new NativeFloat64x2._doubles(x, y);
+  }
+
+  /// Returns a new [Float64x2] copied from [this] with a new y value.
+  Float64x2 withY(double y) {
+    if (y is! num) throw new ArgumentError(y);
+    return new NativeFloat64x2._doubles(x, y);
+  }
+
+  /// Returns the lane-wise minimum value in [this] or [other].
+  Float64x2 min(Float64x2 other) {
+    return new NativeFloat64x2._doubles(
+        x < other.x ? x : other.x, y < other.y ? y : other.y);
+  }
+
+  /// Returns the lane-wise maximum value in [this] or [other].
+  Float64x2 max(Float64x2 other) {
+    return new NativeFloat64x2._doubles(
+        x > other.x ? x : other.x, y > other.y ? y : other.y);
+  }
+
+  /// Returns the lane-wise square root of [this].
+  Float64x2 sqrt() {
+    return new NativeFloat64x2._doubles(Math.sqrt(x), Math.sqrt(y));
+  }
+}
+
+/// Checks that the value is a Uint32. If not, it's not valid as an array
+/// index or offset. Also ensures that the value is non-negative.
+bool _isInvalidArrayIndex(int index) {
+  return (JS('bool', '(# >>> 0 !== #)', index, index));
+}
+
+/// Checks that [index] is a valid index into [list] which has length [length].
+///
+/// That is, [index] is an integer in the range `0..length - 1`.
+void _checkValidIndex(int index, List list, int length) {
+  if (_isInvalidArrayIndex(index) || JS('int', '#', index) >= length) {
+    throw diagnoseIndexError(list, index);
+  }
+}
+
+/// Checks that [start] and [end] form a range of a list of length [length].
+///
+/// That is: `start` and `end` are integers with `0 <= start <= end <= length`.
+/// If `end` is `null` in which case it is considered to be `length`
+///
+/// Returns the actual value of `end`, which is `length` if `end` is `null`, and
+/// the original value of `end` otherwise.
+int _checkValidRange(int start, int end, int length) {
+  if (_isInvalidArrayIndex(start) || // Ensures start is non-negative int.
+      ((end == null)
+          ? start > length
+          : (_isInvalidArrayIndex(end) || start > end || end > length))) {
+    throw diagnoseRangeError(start, end, length);
+  }
+  if (end == null) return length;
+  return end;
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/preambles/README b/sdk_nnbd/lib/_internal/js_runtime/lib/preambles/README
new file mode 100644
index 0000000..4465012
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/preambles/README
@@ -0,0 +1,17 @@
+The files in this directory polyfill some of the functionality that browsers
+provide. When running command-line JS evaluators it is frequently necessary to
+execute the preambles before executing the output of dart2js.
+
+=Usage=
+- d8:
+    d8 <sdk>/lib/_internal/js_runtime/lib/preambles/d8.js <output>.js
+
+- jsshell:
+    jsshell -f <sdk>/lib/_internal/js_runtime/lib/preambles/d8.js -f <output>.js
+
+- node.js:
+  The d8 preamble file works for most programs.
+
+  Unfortunately we are not aware of any easy way to provide multiple input files
+  to node. It seems to be necessary to concatenate the d8 preamble and the
+  dart2js output.
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/preambles/d8.js b/sdk_nnbd/lib/_internal/js_runtime/lib/preambles/d8.js
new file mode 100644
index 0000000..0174d95
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/preambles/d8.js
@@ -0,0 +1,348 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Javascript preamble, that lets the output of dart2js run on V8's d8 shell.
+
+// Node wraps files and provides them with a different `this`. The global
+// `this` can be accessed through `global`.
+
+var self = this;
+if (typeof global != "undefined") self = global;  // Node.js.
+
+(function(self) {
+  // Using strict mode to avoid accidentally defining global variables.
+  "use strict"; // Should be first statement of this function.
+
+  // Location (Uri.base)
+  var baseUri = 'org-dartlang-d8-preamble:///mock/uri/base/';
+  if (typeof process != "undefined" &&
+             typeof process.cwd == "function") {
+    // Node.js.
+    baseUri = 'file://' + process.cwd() + '/';
+  }
+  self.location = { href: baseUri };
+
+  // Event loop.
+
+  // Task queue as cyclic list queue.
+  var taskQueue = new Array(8);  // Length is power of 2.
+  var head = 0;
+  var tail = 0;
+  var mask = taskQueue.length - 1;
+  function addTask(elem) {
+    taskQueue[head] = elem;
+    head = (head + 1) & mask;
+    if (head == tail) _growTaskQueue();
+  }
+  function removeTask() {
+    if (head == tail) return;
+    var result = taskQueue[tail];
+    taskQueue[tail] = undefined;
+    tail = (tail + 1) & mask;
+    return result;
+  }
+  function _growTaskQueue() {
+    // head == tail.
+    var length = taskQueue.length;
+    var split = head;
+    taskQueue.length = length * 2;
+    if (split * 2 < length) {  // split < length / 2
+      for (var i = 0; i < split; i++) {
+        taskQueue[length + i] = taskQueue[i];
+        taskQueue[i] = undefined;
+      }
+      head += length;
+    } else {
+      for (var i = split; i < length; i++) {
+        taskQueue[length + i] = taskQueue[i];
+        taskQueue[i] = undefined;
+      }
+      tail += length;
+    }
+    mask = taskQueue.length - 1;
+  }
+
+  // Mapping from timer id to timer function.
+  // The timer id is written on the function as .$timerId.
+  // That field is cleared when the timer is cancelled, but it is not returned
+  // from the queue until its time comes.
+  var timerIds = {};
+  var timerIdCounter = 1;  // Counter used to assign ids.
+
+  // Zero-timer queue as simple array queue using push/shift.
+  var zeroTimerQueue = [];
+
+  function addTimer(f, ms) {
+    var id = timerIdCounter++;
+    f.$timerId = id;
+    timerIds[id] = f;
+    if (ms == 0 && !isNextTimerDue()) {
+      zeroTimerQueue.push(f);
+    } else {
+      addDelayedTimer(f, ms);
+    }
+    return id;
+  }
+
+  function nextZeroTimer() {
+    while (zeroTimerQueue.length > 0) {
+      var action = zeroTimerQueue.shift();
+      if (action.$timerId !== undefined) return action;
+    }
+  }
+
+  function nextEvent() {
+    var action = removeTask();
+    if (action) {
+      return action;
+    }
+    do {
+      action = nextZeroTimer();
+      if (action) break;
+      var nextList = nextDelayedTimerQueue();
+      if (!nextList) {
+        return;
+      }
+      var newTime = nextList.shift();
+      advanceTimeTo(newTime);
+      zeroTimerQueue = nextList;
+    } while (true)
+    var id = action.$timerId;
+    clearTimerId(action, id);
+    return action;
+  }
+
+  // Mocking time.
+  var timeOffset = 0;
+  var now = function() {
+    // Install the mock Date object only once.
+    // Following calls to "now" will just use the new (mocked) Date.now
+    // method directly.
+    installMockDate();
+    now = Date.now;
+    return Date.now();
+  };
+  var originalDate = Date;
+  var originalNow = originalDate.now;
+  function advanceTimeTo(time) {
+    var now = originalNow();
+    if (timeOffset < time - now) {
+      timeOffset = time - now;
+    }
+  }
+  function installMockDate() {
+    var NewDate = function Date(Y, M, D, h, m, s, ms) {
+      if (this instanceof Date) {
+        // Assume a construct call.
+        switch (arguments.length) {
+          case 0:  return new originalDate(originalNow() + timeOffset);
+          case 1:  return new originalDate(Y);
+          case 2:  return new originalDate(Y, M);
+          case 3:  return new originalDate(Y, M, D);
+          case 4:  return new originalDate(Y, M, D, h);
+          case 5:  return new originalDate(Y, M, D, h, m);
+          case 6:  return new originalDate(Y, M, D, h, m, s);
+          default: return new originalDate(Y, M, D, h, m, s, ms);
+        }
+      }
+      return new originalDate(originalNow() + timeOffset).toString();
+    };
+    NewDate.UTC = originalDate.UTC;
+    NewDate.parse = originalDate.parse;
+    NewDate.now = function now() { return originalNow() + timeOffset; };
+    NewDate.prototype = originalDate.prototype;
+    originalDate.prototype.constructor = NewDate;
+    Date = NewDate;
+  }
+
+  // Heap priority queue with key index.
+  // Each entry is list of [timeout, callback1 ... callbackn].
+  var timerHeap = [];
+  var timerIndex = {};
+  function addDelayedTimer(f, ms) {
+    var timeout = now() + ms;
+    var timerList = timerIndex[timeout];
+    if (timerList == null) {
+      timerList = [timeout, f];
+      timerIndex[timeout] = timerList;
+      var index = timerHeap.length;
+      timerHeap.length += 1;
+      bubbleUp(index, timeout, timerList);
+    } else {
+      timerList.push(f);
+    }
+  }
+
+  function isNextTimerDue() {
+    if (timerHeap.length == 0) return false;
+    var head = timerHeap[0];
+    return head[0] < originalNow() + timeOffset;
+  }
+
+  function nextDelayedTimerQueue() {
+    if (timerHeap.length == 0) return null;
+    var result = timerHeap[0];
+    var last = timerHeap.pop();
+    if (timerHeap.length > 0) {
+      bubbleDown(0, last[0], last);
+    }
+    return result;
+  }
+
+  function bubbleUp(index, key, value) {
+    while (index != 0) {
+      var parentIndex = (index - 1) >> 1;
+      var parent = timerHeap[parentIndex];
+      var parentKey = parent[0];
+      if (key > parentKey) break;
+      timerHeap[index] = parent;
+      index = parentIndex;
+    }
+    timerHeap[index] = value;
+  }
+
+  function bubbleDown(index, key, value) {
+    while (true) {
+      var leftChildIndex = index * 2 + 1;
+      if (leftChildIndex >= timerHeap.length) break;
+      var minChildIndex = leftChildIndex;
+      var minChild = timerHeap[leftChildIndex];
+      var minChildKey = minChild[0];
+      var rightChildIndex = leftChildIndex + 1;
+      if (rightChildIndex < timerHeap.length) {
+        var rightChild = timerHeap[rightChildIndex];
+        var rightKey = rightChild[0];
+        if (rightKey < minChildKey) {
+          minChildIndex = rightChildIndex;
+          minChild = rightChild;
+          minChildKey = rightKey;
+        }
+      }
+      if (minChildKey > key) break;
+      timerHeap[index] = minChild;
+      index = minChildIndex;
+    }
+    timerHeap[index] = value;
+  }
+
+  function addInterval(f, ms) {
+    var id = timerIdCounter++;
+    function repeat() {
+      // Reactivate with the same id.
+      repeat.$timerId = id;
+      timerIds[id] = repeat;
+      addDelayedTimer(repeat, ms);
+      f();
+    }
+    repeat.$timerId = id;
+    timerIds[id] = repeat;
+    addDelayedTimer(repeat, ms);
+    return id;
+  }
+
+  function cancelTimer(id) {
+    var f = timerIds[id];
+    if (f == null) return;
+    clearTimerId(f, id);
+  }
+
+  function clearTimerId(f, id) {
+    f.$timerId = undefined;
+    delete timerIds[id];
+  }
+
+  function eventLoop(action) {
+    while (action) {
+      try {
+        action();
+      } catch (e) {
+        if (typeof onerror == "function") {
+          onerror(e, null, -1);
+        } else {
+          throw e;
+        }
+      }
+      action = nextEvent();
+    }
+  }
+
+  // Global properties. "self" refers to the global object, so adding a
+  // property to "self" defines a global variable.
+  self.self = self;
+  self.dartMainRunner = function(main, args) {
+    // Initialize.
+    var action = function() { main(args); }
+    eventLoop(action);
+  };
+  self.setTimeout = addTimer;
+  self.clearTimeout = cancelTimer;
+  self.setInterval = addInterval;
+  self.clearInterval = cancelTimer;
+  self.scheduleImmediate = addTask;
+
+  function computeCurrentScript() {
+    try {
+      throw new Error();
+    } catch(e) {
+      var stack = e.stack;
+      // The V8 stack looks like:
+      //    at computeCurrentScript (preambles/d8.js:286:13)
+      //    at Object.currentScript (preambles/d8.js:308:31)
+      //    at init.currentScript (/tmp/foo.js:308:19)
+      //    at /tmp/foo.js:320:7
+      //    at /tmp/foo.js:331:4
+      // Sometimes the 'init.currentScript' line is in the format without the
+      // function name, so match with or without parentheses.
+
+      //              vvvvvvvvvvvv Optional prefix up to '('.
+      var re = /^ *at (?:[^(]*\()?(.*):[0-9]*:[0-9]*\)?$/mg
+      //              Optional ')' at end           ^^^
+
+      var lastMatch = null;
+      do {
+        var match = re.exec(stack);
+        if (match != null) lastMatch = match;
+      } while (match != null);
+      return lastMatch[1];
+    }
+  }
+
+  // Adding a 'document' is dangerous since it invalidates the 'typeof document'
+  // test to see if we are running in the browser. It means that the runtime
+  // needs to do more precise checks.
+  // Note that we can't run "currentScript" right away, since that would give
+  // us the location of the preamble file. Instead we wait for the first access
+  // which should happen just before invoking main. At this point we are in
+  // the main file and setting the currentScript property is correct.
+  var cachedCurrentScript = null;
+  self.document = { get currentScript() {
+      if (cachedCurrentScript == null) {
+        cachedCurrentScript = {src: computeCurrentScript()};
+      }
+      return cachedCurrentScript;
+    }
+  };
+
+  // Support for deferred loading.
+  self.dartDeferredLibraryLoader = function(uri, successCallback, errorCallback) {
+    try {
+      load(uri);
+      successCallback();
+    } catch (error) {
+      errorCallback(error);
+    }
+  };
+
+  // Mock cryptographically secure random by using plain random.
+  self.crypto = {getRandomValues: function(array) {
+    for (var i = 0; i < array.length; i++) {
+      array[i] = Math.random() * 256;
+    }
+  }};
+
+  // D8 Workers are not sufficiently compatible with browser Workers
+  // so pretend they don't exist.
+  // TODO(30217): Try to use D8's worker.
+  delete self.Worker;
+})(self);
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/preambles/jsshell.js b/sdk_nnbd/lib/_internal/js_runtime/lib/preambles/jsshell.js
new file mode 100644
index 0000000..a6b41c4
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/preambles/jsshell.js
@@ -0,0 +1,340 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Javascript preamble, that lets the output of dart2js run on JSShell.
+
+(function(self) {
+  // Using strict mode to avoid accidentally defining global variables.
+  "use strict"; // Should be first statement of this function.
+
+  // Location (Uri.base)
+
+  var workingDirectory = os.getenv("PWD");
+
+  // Global properties. "self" refers to the global object, so adding a
+  // property to "self" defines a global variable.
+  self.self = self;
+
+  self.location = { href: "file://" + workingDirectory + "/" };
+
+  // Event loop.
+
+  // Task queue as cyclic list queue.
+  var taskQueue = new Array(8);  // Length is power of 2.
+  var head = 0;
+  var tail = 0;
+  var mask = taskQueue.length - 1;
+  function addTask(elem) {
+    taskQueue[head] = elem;
+    head = (head + 1) & mask;
+    if (head == tail) _growTaskQueue();
+  }
+  function removeTask() {
+    if (head == tail) return;
+    var result = taskQueue[tail];
+    taskQueue[tail] = undefined;
+    tail = (tail + 1) & mask;
+    return result;
+  }
+  function _growTaskQueue() {
+    // head == tail.
+    var length = taskQueue.length;
+    var split = head;
+    taskQueue.length = length * 2;
+    if (split * 2 < length) {  // split < length / 2
+      for (var i = 0; i < split; i++) {
+        taskQueue[length + i] = taskQueue[i];
+        taskQueue[i] = undefined;
+      }
+      head += length;
+    } else {
+      for (var i = split; i < length; i++) {
+        taskQueue[length + i] = taskQueue[i];
+        taskQueue[i] = undefined;
+      }
+      tail += length;
+    }
+    mask = taskQueue.length - 1;
+  }
+
+  // Mapping from timer id to timer function.
+  // The timer id is written on the function as .$timerId.
+  // That field is cleared when the timer is cancelled, but it is not returned
+  // from the queue until its time comes.
+  var timerIds = {};
+  var timerIdCounter = 1;  // Counter used to assign ids.
+
+  // Zero-timer queue as simple array queue using push/shift.
+  var zeroTimerQueue = [];
+
+  function addTimer(f, ms) {
+    var id = timerIdCounter++;
+    f.$timerId = id;
+    timerIds[id] = f;
+    if (ms == 0 && !isNextTimerDue()) {
+      zeroTimerQueue.push(f);
+    } else {
+      addDelayedTimer(f, ms);
+    }
+    return id;
+  }
+
+  function nextZeroTimer() {
+    while (zeroTimerQueue.length > 0) {
+      var action = zeroTimerQueue.shift();
+      if (action.$timerId !== undefined) return action;
+    }
+  }
+
+  function nextEvent() {
+    var action = removeTask();
+    if (action) {
+      return action;
+    }
+    do {
+      action = nextZeroTimer();
+      if (action) break;
+      var nextList = nextDelayedTimerQueue();
+      if (!nextList) {
+        return;
+      }
+      var newTime = nextList.shift();
+      advanceTimeTo(newTime);
+      zeroTimerQueue = nextList;
+    } while (true)
+    var id = action.$timerId;
+    clearTimerId(action, id);
+    return action;
+  }
+
+  // Mocking time.
+  var timeOffset = 0;
+  var now = function() {
+    // Install the mock Date object only once.
+    // Following calls to "now" will just use the new (mocked) Date.now
+    // method directly.
+    installMockDate();
+    now = Date.now;
+    return Date.now();
+  };
+  var originalDate = Date;
+  var originalNow = originalDate.now;
+  function advanceTimeTo(time) {
+    var now = originalNow();
+    if (timeOffset < time - now) {
+      timeOffset = time - now;
+    }
+  }
+  function installMockDate() {
+    var NewDate = function Date(Y, M, D, h, m, s, ms) {
+      if (this instanceof Date) {
+        // Assume a construct call.
+        switch (arguments.length) {
+          case 0:  return new originalDate(originalNow() + timeOffset);
+          case 1:  return new originalDate(Y);
+          case 2:  return new originalDate(Y, M);
+          case 3:  return new originalDate(Y, M, D);
+          case 4:  return new originalDate(Y, M, D, h);
+          case 5:  return new originalDate(Y, M, D, h, m);
+          case 6:  return new originalDate(Y, M, D, h, m, s);
+          default: return new originalDate(Y, M, D, h, m, s, ms);
+        }
+      }
+      return new originalDate(originalNow() + timeOffset).toString();
+    };
+    NewDate.UTC = originalDate.UTC;
+    NewDate.parse = originalDate.parse;
+    NewDate.now = function now() { return originalNow() + timeOffset; };
+    NewDate.prototype = originalDate.prototype;
+    originalDate.prototype.constructor = NewDate;
+    Date = NewDate;
+  }
+
+  // Heap priority queue with key index.
+  // Each entry is list of [timeout, callback1 ... callbackn].
+  var timerHeap = [];
+  var timerIndex = {};
+  function addDelayedTimer(f, ms) {
+    var timeout = now() + ms;
+    var timerList = timerIndex[timeout];
+    if (timerList == null) {
+      timerList = [timeout, f];
+      timerIndex[timeout] = timerList;
+      var index = timerHeap.length;
+      timerHeap.length += 1;
+      bubbleUp(index, timeout, timerList);
+    } else {
+      timerList.push(f);
+    }
+  }
+
+  function isNextTimerDue() {
+    if (timerHeap.length == 0) return false;
+    var head = timerHeap[0];
+    return head[0] < originalNow() + timeOffset;
+  }
+
+  function nextDelayedTimerQueue() {
+    if (timerHeap.length == 0) return null;
+    var result = timerHeap[0];
+    var last = timerHeap.pop();
+    if (timerHeap.length > 0) {
+      bubbleDown(0, last[0], last);
+    }
+    return result;
+  }
+
+  function bubbleUp(index, key, value) {
+    while (index != 0) {
+      var parentIndex = (index - 1) >> 1;
+      var parent = timerHeap[parentIndex];
+      var parentKey = parent[0];
+      if (key > parentKey) break;
+      timerHeap[index] = parent;
+      index = parentIndex;
+    }
+    timerHeap[index] = value;
+  }
+
+  function bubbleDown(index, key, value) {
+    while (true) {
+      var leftChildIndex = index * 2 + 1;
+      if (leftChildIndex >= timerHeap.length) break;
+      var minChildIndex = leftChildIndex;
+      var minChild = timerHeap[leftChildIndex];
+      var minChildKey = minChild[0];
+      var rightChildIndex = leftChildIndex + 1;
+      if (rightChildIndex < timerHeap.length) {
+        var rightChild = timerHeap[rightChildIndex];
+        var rightKey = rightChild[0];
+        if (rightKey < minChildKey) {
+          minChildIndex = rightChildIndex;
+          minChild = rightChild;
+          minChildKey = rightKey;
+        }
+      }
+      if (minChildKey > key) break;
+      timerHeap[index] = minChild;
+      index = minChildIndex;
+    }
+    timerHeap[index] = value;
+  }
+
+  function addInterval(f, ms) {
+    var id = timerIdCounter++;
+    function repeat() {
+      // Reactivate with the same id.
+      repeat.$timerId = id;
+      timerIds[id] = repeat;
+      addDelayedTimer(repeat, ms);
+      f();
+    }
+    repeat.$timerId = id;
+    timerIds[id] = repeat;
+    addDelayedTimer(repeat, ms);
+    return id;
+  }
+
+  function cancelTimer(id) {
+    var f = timerIds[id];
+    if (f == null) return;
+    clearTimerId(f, id);
+  }
+
+  function clearTimerId(f, id) {
+    f.$timerId = undefined;
+    delete timerIds[id];
+  }
+
+  function eventLoop(action) {
+    while (action) {
+      try {
+        action();
+      } catch (e) {
+        if (typeof onerror == "function") {
+          onerror(e, null, -1);
+        } else {
+          throw e;
+        }
+      }
+      action = nextEvent();
+    }
+  }
+
+  self.dartMainRunner = function(main, args) {
+    // Initialize.
+    var action = function() { main(args); }
+    eventLoop(action);
+  };
+  self.setTimeout = addTimer;
+  self.clearTimeout = cancelTimer;
+  self.setInterval = addInterval;
+  self.clearInterval = cancelTimer;
+  self.scheduleImmediate = addTask;
+
+  function computeCurrentScript() {
+    try {
+      throw new Error();
+    } catch(e) {
+      var stack = e.stack;
+      print(stack);
+      // The jsshell stack looks like:
+      //   computeCurrentScript@...preambles/jsshell.js:23:13
+      //   self.document.currentScript@...preambles/jsshell.js:53:37
+      //   @/tmp/foo.js:308:1
+      //   @/tmp/foo.js:303:1
+      //   @/tmp/foo.js:5:1
+      var re = new RegExp("^.*@(.*):[0-9]*:[0-9]*$", "mg");
+      var lastMatch = null;
+      do {
+        var match = re.exec(stack);
+        if (match != null) lastMatch = match;
+      } while (match != null);
+      return lastMatch[1];
+    }
+  }
+
+  // Adding a 'document' is dangerous since it invalidates the 'typeof document'
+  // test to see if we are running in the browser. It means that the runtime
+  // needs to do more precise checks.
+  // Note that we can't run "currentScript" right away, since that would give
+  // us the location of the preamble file. Instead we wait for the first access
+  // which should happen just before invoking main. At this point we are in
+  // the main file and setting the currentScript property is correct.
+  // Note that we cannot use `thisFileName()`, since that would give us the
+  // preamble and not the script file.
+  var cachedCurrentScript = null;
+  self.document = { get currentScript() {
+      if (cachedCurrentScript == null) {
+        cachedCurrentScript = {src: computeCurrentScript()};
+      }
+      return cachedCurrentScript;
+    }
+  };
+
+  // Support for deferred loading.
+  self.dartDeferredLibraryLoader = function(uri, successCallback, errorCallback) {
+    try {
+      load(uri);
+      successCallback();
+    } catch (error) {
+      errorCallback(error);
+    }
+  };
+
+  // Mock cryptographically secure random by using plain random.
+  self.crypto = {getRandomValues: function(array) {
+    for (var i = 0; i < array.length; i++) {
+      array[i] = Math.random() * 256;
+    }
+  }};
+})(this)
+
+var getKeys = function(obj){
+   var keys = [];
+   for(var key in obj){
+      keys.push(key);
+   }
+   return keys;
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/regexp_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/regexp_helper.dart
new file mode 100644
index 0000000..3dacc06
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/regexp_helper.dart
@@ -0,0 +1,295 @@
+// Copyright (c) 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 _js_helper;
+
+// Helper method used by internal libraries.
+regExpGetNative(JSSyntaxRegExp regexp) => regexp._nativeRegExp;
+
+/// Returns a native version of the RegExp with the global flag set.
+///
+/// The RegExp's `lastIndex` property is zero when it is returned.
+///
+/// The returned regexp is shared, and its `lastIndex` property may be
+/// modified by other uses, so the returned regexp must be used immediately
+/// when it's returned, with no user-provided code run in between.
+regExpGetGlobalNative(JSSyntaxRegExp regexp) {
+  var nativeRegexp = regexp._nativeGlobalVersion;
+  JS('void', '#.lastIndex = 0', nativeRegexp);
+  return nativeRegexp;
+}
+
+/// Computes the number of captures in a regexp.
+///
+/// This currently involves creating a new RegExp object with a different
+/// source and running it against the empty string (the last part is usually
+/// fast).
+///
+/// The JSSyntaxRegExp could cache the result, and set the cache any time
+/// it finds a match.
+int regExpCaptureCount(JSSyntaxRegExp regexp) {
+  var nativeAnchoredRegExp = regexp._nativeAnchoredVersion;
+  var match = JS('JSExtendableArray', '#.exec("")', nativeAnchoredRegExp);
+  // The native-anchored regexp always have one capture more than the original,
+  // and always matches the empty string.
+  return match.length - 2;
+}
+
+class JSSyntaxRegExp implements RegExp {
+  final String pattern;
+  final _nativeRegExp;
+  var _nativeGlobalRegExp;
+  var _nativeAnchoredRegExp;
+
+  String toString() =>
+      'RegExp/$pattern/' + JS('String', '#.flags', _nativeRegExp);
+
+  JSSyntaxRegExp(String source,
+      {bool multiLine: false,
+      bool caseSensitive: true,
+      bool unicode: false,
+      bool dotAll: false})
+      : this.pattern = source,
+        this._nativeRegExp = makeNative(
+            source, multiLine, caseSensitive, unicode, dotAll, false);
+
+  get _nativeGlobalVersion {
+    if (_nativeGlobalRegExp != null) return _nativeGlobalRegExp;
+    return _nativeGlobalRegExp = makeNative(
+        pattern, _isMultiLine, _isCaseSensitive, _isUnicode, _isDotAll, true);
+  }
+
+  get _nativeAnchoredVersion {
+    if (_nativeAnchoredRegExp != null) return _nativeAnchoredRegExp;
+    // An "anchored version" of a regexp is created by adding "|()" to the
+    // source. This means that the regexp always matches at the first position
+    // that it tries, and you can see if the original regexp matched, or it
+    // was the added zero-width match that matched, by looking at the last
+    // capture. If it is a String, the match participated, otherwise it didn't.
+    return _nativeAnchoredRegExp = makeNative('$pattern|()', _isMultiLine,
+        _isCaseSensitive, _isUnicode, _isDotAll, true);
+  }
+
+  bool get _isMultiLine => JS('bool', '#.multiline', _nativeRegExp);
+  bool get _isCaseSensitive => JS('bool', '!#.ignoreCase', _nativeRegExp);
+  bool get _isUnicode => JS('bool', '#.unicode', _nativeRegExp);
+  bool get _isDotAll => JS('bool', '#.dotAll', _nativeRegExp);
+
+  static makeNative(String source, bool multiLine, bool caseSensitive,
+      bool unicode, bool dotAll, bool global) {
+    checkString(source);
+    String m = multiLine == true ? 'm' : '';
+    String i = caseSensitive == true ? '' : 'i';
+    String u = unicode ? 'u' : '';
+    String s = dotAll ? 's' : '';
+    String g = global ? 'g' : '';
+    // We're using the JavaScript's try catch instead of the Dart one to avoid
+    // dragging in Dart runtime support just because of using RegExp.
+    var regexp = JS(
+        '',
+        r'''
+          (function(source, modifiers) {
+            try {
+              return new RegExp(source, modifiers);
+            } catch (e) {
+              return e;
+            }
+          })(#, # + # + # + # + #)''',
+        source,
+        m,
+        i,
+        u,
+        s,
+        g);
+    if (JS('bool', '# instanceof RegExp', regexp)) return regexp;
+    // The returned value is the JavaScript exception. Turn it into a
+    // Dart exception.
+    String errorMessage = JS('String', r'String(#)', regexp);
+    throw new FormatException('Illegal RegExp pattern ($errorMessage)', source);
+  }
+
+  RegExpMatch firstMatch(String string) {
+    List m = JS('JSExtendableArray|Null', r'#.exec(#)', _nativeRegExp,
+        checkString(string));
+    if (m == null) return null;
+    return new _MatchImplementation(this, m);
+  }
+
+  bool hasMatch(String string) {
+    return JS('bool', r'#.test(#)', _nativeRegExp, checkString(string));
+  }
+
+  String stringMatch(String string) {
+    var match = firstMatch(string);
+    if (match != null) return match.group(0);
+    return null;
+  }
+
+  Iterable<RegExpMatch> allMatches(String string, [int start = 0]) {
+    checkString(string);
+    checkInt(start);
+    if (start < 0 || start > string.length) {
+      throw new RangeError.range(start, 0, string.length);
+    }
+    return new _AllMatchesIterable(this, string, start);
+  }
+
+  RegExpMatch _execGlobal(String string, int start) {
+    Object regexp = _nativeGlobalVersion;
+    JS('void', '#.lastIndex = #', regexp, start);
+    List match = JS('JSExtendableArray|Null', '#.exec(#)', regexp, string);
+    if (match == null) return null;
+    return new _MatchImplementation(this, match);
+  }
+
+  RegExpMatch _execAnchored(String string, int start) {
+    Object regexp = _nativeAnchoredVersion;
+    JS('void', '#.lastIndex = #', regexp, start);
+    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.
+    if (match.removeLast() != null) return null;
+    return new _MatchImplementation(this, match);
+  }
+
+  RegExpMatch matchAsPrefix(String string, [int start = 0]) {
+    if (start < 0 || start > string.length) {
+      throw new RangeError.range(start, 0, string.length);
+    }
+    return _execAnchored(string, start);
+  }
+
+  bool get isMultiLine => _isMultiLine;
+  bool get isCaseSensitive => _isCaseSensitive;
+  bool get isUnicode => _isUnicode;
+  bool get isDotAll => _isDotAll;
+}
+
+class _MatchImplementation implements RegExpMatch {
+  final Pattern pattern;
+  // Contains a JS RegExp match object.
+  // It is an Array of String values with extra 'index' and 'input' properties.
+  // If there were named capture groups, there will also be an extra 'groups'
+  // property containing an object with capture group names as keys and
+  // matched strings as values.
+  // We didn't force it to be JSArray<String>, so it is JSArray<dynamic>, but
+  // containing String or `undefined` values.
+  final JSArray _match;
+
+  _MatchImplementation(this.pattern, this._match) {
+    assert(JS('var', '#.input', _match) is String);
+    assert(JS('var', '#.index', _match) is int);
+  }
+
+  String get input => JS('String', '#.input', _match);
+
+  int get start =>
+      JS('returns:int;depends:none;effects:none;gvn:true', '#.index', _match);
+
+  int get end =>
+      start +
+      JS('returns:int;depends:none;effects:none;gvn:true', '#[0].length',
+          _match);
+
+  // The JS below changes the static type to avoid an implicit cast.
+  // TODO(sra): Find a nicer way to do this, e.g. unsafeCast.
+  String group(int index) => JS('String|Null', '#', _match[index]);
+
+  String operator [](int index) => group(index);
+
+  int get groupCount => _match.length - 1;
+
+  List<String> groups(List<int> groups) {
+    List<String> out = [];
+    for (int i in groups) {
+      out.add(group(i));
+    }
+    return out;
+  }
+
+  String namedGroup(String name) {
+    var groups = JS('Object', '#.groups', _match);
+    if (groups != null) {
+      var result = JS('String|Null', '#[#]', groups, name);
+      if (result != null || JS('bool', '# in #', name, groups)) {
+        return result;
+      }
+    }
+    throw ArgumentError.value(name, "name", "Not a capture group name");
+  }
+
+  Iterable<String> get groupNames {
+    var groups = JS('Object', '#.groups', _match);
+    if (groups != null) {
+      var keys = new JSArray<String>.markGrowable(
+          JS('returns:JSExtendableArray;new:true', 'Object.keys(#)', groups));
+      return SubListIterable(keys, 0, null);
+    }
+    return Iterable.empty();
+  }
+}
+
+class _AllMatchesIterable extends IterableBase<RegExpMatch> {
+  final JSSyntaxRegExp _re;
+  final String _string;
+  final int _start;
+
+  _AllMatchesIterable(this._re, this._string, this._start);
+
+  Iterator<RegExpMatch> get iterator =>
+      new _AllMatchesIterator(_re, _string, _start);
+}
+
+class _AllMatchesIterator implements Iterator<RegExpMatch> {
+  final JSSyntaxRegExp _regExp;
+  String _string;
+  int _nextIndex;
+  RegExpMatch _current;
+
+  _AllMatchesIterator(this._regExp, this._string, this._nextIndex);
+
+  RegExpMatch get current => _current;
+
+  static bool _isLeadSurrogate(int c) {
+    return c >= 0xd800 && c <= 0xdbff;
+  }
+
+  static bool _isTrailSurrogate(int c) {
+    return c >= 0xdc00 && c <= 0xdfff;
+  }
+
+  bool moveNext() {
+    if (_string == null) return false;
+    if (_nextIndex <= _string.length) {
+      var match = _regExp._execGlobal(_string, _nextIndex);
+      if (match != null) {
+        _current = match;
+        int nextIndex = match.end;
+        if (match.start == nextIndex) {
+          // Zero-width match. Advance by one more, unless the regexp
+          // is in unicode mode and it would put us within a surrogate
+          // pair. In that case, advance past the code point as a whole.
+          if (_regExp.isUnicode &&
+              _nextIndex + 1 < _string.length &&
+              _isLeadSurrogate(_string.codeUnitAt(_nextIndex)) &&
+              _isTrailSurrogate(_string.codeUnitAt(_nextIndex + 1))) {
+            nextIndex++;
+          }
+          nextIndex++;
+        }
+        _nextIndex = nextIndex;
+        return true;
+      }
+    }
+    _current = null;
+    _string = null; // Marks iteration as ended.
+    return false;
+  }
+}
+
+/// Find the first match of [regExp] in [string] at or after [start].
+RegExpMatch firstMatchAfter(JSSyntaxRegExp regExp, String string, int start) {
+  return regExp._execGlobal(string, start);
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
new file mode 100644
index 0000000..f7ca527
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
@@ -0,0 +1,2492 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 contains support for runtime type information.
+library rti;
+
+import 'dart:_foreign_helper'
+    show
+        getInterceptor,
+        getJSArrayInteropRti,
+        JS,
+        JS_BUILTIN,
+        JS_EMBEDDED_GLOBAL,
+        JS_GET_FLAG,
+        JS_GET_NAME,
+        JS_STRING_CONCAT,
+        RAW_DART_FUNCTION_REF;
+
+import 'dart:_interceptors' show JSArray, JSUnmodifiableArray;
+
+import 'dart:_js_names' show unmangleGlobalNameIfPreservedAnyways;
+
+import 'dart:_js_embedded_names'
+    show JsBuiltin, JsGetName, RtiUniverseFieldNames, RTI_UNIVERSE, TYPES;
+
+import 'dart:_recipe_syntax';
+
+/// An Rti object represents both a type (e.g `Map<int, String>`) and a type
+/// environment (`Map<int, String>` binds `Map.K=int` and `Map.V=String`).
+///
+/// There is a single [Rti] class to help reduce polymorphism in the JavaScript
+/// runtime. The class has a default constructor and no final fields so it can
+/// be created before much of the runtime exists.
+///
+/// The fields are declared in an order that gets shorter minified names for the
+/// more commonly used fields. (TODO: we should exploit the fact that an Rti
+/// instance never appears in a dynamic context, so does not need field names to
+/// be distinct from dynamic selectors).
+///
+class Rti {
+  /// JavaScript method for 'as' check. The method is called from generated code,
+  /// e.g. `o as T` generates something like `rtiForT._as(o)`.
+  @pragma('dart2js:noElision')
+  dynamic _as;
+
+  /// JavaScript method for type check.  The method is called from generated
+  /// code, e.g. parameter check for `T param` generates something like
+  /// `rtiForT._check(param)`.
+  @pragma('dart2js:noElision')
+  dynamic _check;
+
+  /// JavaScript method for 'is' test.  The method is called from generated
+  /// code, e.g. `o is T` generates something like `rtiForT._is(o)`.
+  @pragma('dart2js:noElision')
+  dynamic _is;
+
+  static void _setAsCheckFunction(Rti rti, fn) {
+    rti._as = fn;
+  }
+
+  static void _setTypeCheckFunction(Rti rti, fn) {
+    rti._check = fn;
+  }
+
+  static void _setIsTestFunction(Rti rti, fn) {
+    rti._is = fn;
+  }
+
+  @pragma('dart2js:tryInline')
+  static bool _isCheck(Rti rti, object) {
+    return JS(
+        'bool', '#.#(#)', rti, JS_GET_NAME(JsGetName.RTI_FIELD_IS), object);
+  }
+
+  /// Method called from generated code to evaluate a type environment recipe in
+  /// `this` type environment.
+  Rti _eval(recipe) {
+    // TODO(sra): Clone the fast-path of _Universe.evalInEnvironment to here.
+    return _rtiEval(this, _Utils.asString(recipe));
+  }
+
+  /// Method called from generated code to extend `this` type environment (an
+  /// interface or binding Rti) with function type arguments (a singleton
+  /// argument or tuple of arguments).
+  Rti _bind(typeOrTuple) => _rtiBind(this, _castToRti(typeOrTuple));
+
+  /// Method called from generated code to extend `this` type (as a singleton
+  /// type environment) with function type arguments (a singleton argument or
+  /// tuple of arguments).
+  Rti _bind1(Rti typeOrTuple) => _rtiBind1(this, typeOrTuple);
+
+  // Precomputed derived types. These fields are used to hold derived types that
+  // are computed eagerly.
+  // TODO(sra): Implement precomputed type optimizations.
+  dynamic _precomputed1;
+  dynamic _precomputed2;
+  dynamic _precomputed3;
+  dynamic _precomputed4;
+
+  // The Type object corresponding to this Rti.
+  Object _cachedRuntimeType;
+  static _Type _getCachedRuntimeType(Rti rti) =>
+      JS('_Type|Null', '#', rti._cachedRuntimeType);
+  static void _setCachedRuntimeType(Rti rti, _Type type) {
+    rti._cachedRuntimeType = type;
+  }
+
+  /// The kind of Rti `this` is, one of the kindXXX constants below.
+  ///
+  /// We don't use an enum since we need to create Rti objects very early.
+  ///
+  /// The zero initializer ensures dart2js type analysis considers [_kind] is
+  /// non-nullable.
+  Object /*int*/ _kind = 0;
+
+  static int _getKind(Rti rti) => _Utils.asInt(rti._kind);
+  static void _setKind(Rti rti, int kind) {
+    rti._kind = kind;
+  }
+
+  // Terminal terms.
+  static const kindNever = 1;
+  static const kindDynamic = 2;
+  static const kindVoid = 3; // TODO(sra): Use `dynamic` instead?
+  static const kindAny = 4; // Dart1-style 'dynamic' for JS-interop.
+  // Unary terms.
+  static const kindStar = 5;
+  static const kindQuestion = 6;
+  static const kindFutureOr = 7;
+  // More complex terms.
+  static const kindInterface = 8;
+  // A vector of type parameters from enclosing functions and closures.
+  static const kindBinding = 9;
+  static const kindFunction = 10;
+  static const kindGenericFunction = 11;
+  static const kindGenericFunctionParameter = 12;
+
+  static bool _isUnionOfFunctionType(Rti rti) {
+    int kind = Rti._getKind(rti);
+    if (kind == kindStar || kind == kindQuestion || kind == kindFutureOr) {
+      return _isUnionOfFunctionType(_castToRti(_getPrimary(rti)));
+    }
+    return kind == kindFunction || kind == kindGenericFunction;
+  }
+
+  /// Primary data associated with type.
+  ///
+  /// - Minified name of interface for interface types.
+  /// - Underlying type for unary terms.
+  /// - Class part of a type environment inside a generic class, or `null` for
+  ///   type tuple.
+  /// - Return type of a function type.
+  /// - Underlying function type for a generic function.
+  /// - de Bruijn index for a generic function parameter.
+  dynamic _primary;
+
+  static Object _getPrimary(Rti rti) => rti._primary;
+  static void _setPrimary(Rti rti, value) {
+    rti._primary = value;
+  }
+
+  /// Additional data associated with type.
+  ///
+  /// - The type arguments of an interface type.
+  /// - The type arguments from enclosing functions and closures for a
+  ///   kindBinding.
+  /// - The [_FunctionParameters] of a function type.
+  /// - The type parameter bounds of a generic function.
+  dynamic _rest;
+
+  static Object _getRest(Rti rti) => rti._rest;
+  static void _setRest(Rti rti, value) {
+    rti._rest = value;
+  }
+
+  static String _getInterfaceName(Rti rti) {
+    assert(_getKind(rti) == kindInterface);
+    return _Utils.asString(_getPrimary(rti));
+  }
+
+  static JSArray _getInterfaceTypeArguments(Rti rti) {
+    // The array is a plain JavaScript Array, otherwise we would need the type
+    // `JSArray<Rti>` to exist before we could create the type `JSArray<Rti>`.
+    assert(_getKind(rti) == kindInterface);
+    return JS('JSUnmodifiableArray', '#', _getRest(rti));
+  }
+
+  static Rti _getBindingBase(Rti rti) {
+    assert(_getKind(rti) == kindBinding);
+    return _castToRti(_getPrimary(rti));
+  }
+
+  static JSArray _getBindingArguments(Rti rti) {
+    assert(_getKind(rti) == kindBinding);
+    return JS('JSUnmodifiableArray', '#', _getRest(rti));
+  }
+
+  static Rti _getStarArgument(Rti rti) {
+    assert(_getKind(rti) == kindStar);
+    return _castToRti(_getPrimary(rti));
+  }
+
+  static Rti _getQuestionArgument(Rti rti) {
+    assert(_getKind(rti) == kindQuestion);
+    return _castToRti(_getPrimary(rti));
+  }
+
+  static Rti _getFutureOrArgument(Rti rti) {
+    assert(_getKind(rti) == kindFutureOr);
+    return _castToRti(_getPrimary(rti));
+  }
+
+  static Rti _getReturnType(Rti rti) {
+    assert(_getKind(rti) == kindFunction);
+    return _castToRti(_getPrimary(rti));
+  }
+
+  static _FunctionParameters _getFunctionParameters(Rti rti) {
+    assert(_getKind(rti) == kindFunction);
+    return JS('_FunctionParameters', '#', _getRest(rti));
+  }
+
+  static Rti _getGenericFunctionBase(Rti rti) {
+    assert(_getKind(rti) == kindGenericFunction);
+    return _castToRti(_getPrimary(rti));
+  }
+
+  static JSArray _getGenericFunctionBounds(Rti rti) {
+    assert(_getKind(rti) == kindGenericFunction);
+    return JS('JSUnmodifiableArray', '#', _getRest(rti));
+  }
+
+  static int _getGenericFunctionParameterIndex(Rti rti) {
+    assert(_getKind(rti) == kindGenericFunctionParameter);
+    return _Utils.asInt(_getPrimary(rti));
+  }
+
+  /// On [Rti]s that are type environments*, derived types are cached on the
+  /// environment to ensure fast canonicalization. Ground-term types (i.e. not
+  /// dependent on class or function type parameters) are cached in the
+  /// universe. This field starts as `null` and the cache is created on demand.
+  ///
+  /// *Any Rti can be a type environment, since we use the type for a function
+  /// type environment. The ambiguity between 'generic class is the environment'
+  /// and 'generic class is a singleton type argument' is resolved by using
+  /// different indexing in the recipe.
+  Object _evalCache;
+
+  static Object _getEvalCache(Rti rti) => rti._evalCache;
+  static void _setEvalCache(Rti rti, value) {
+    rti._evalCache = value;
+  }
+
+  /// On [Rti]s that are type environments*, extended environments are cached on
+  /// the base environment to ensure fast canonicalization.
+  ///
+  /// This field starts as `null` and the cache is created on demand.
+  ///
+  /// *This is valid only on kindInterface and kindBinding Rtis. The ambiguity
+  /// between 'generic class is the base environment' and 'generic class is a
+  /// singleton type argument' is resolved [TBD] (either (1) a bind1 cache, or
+  /// (2)using `env._eval("@<0>")._bind(args)` in place of `env._bind1(args)`).
+  ///
+  /// On [Rti]s that are generic function types, results of instantiation are
+  /// cached on the generic function type to ensure fast repeated
+  /// instantiations.
+  Object _bindCache;
+
+  static Object _getBindCache(Rti rti) => rti._bindCache;
+  static void _setBindCache(Rti rti, value) {
+    rti._bindCache = value;
+  }
+
+  static Rti allocate() {
+    return new Rti();
+  }
+
+  Object _canonicalRecipe;
+
+  static String _getCanonicalRecipe(Rti rti) {
+    Object s = rti._canonicalRecipe;
+    assert(_Utils.isString(s), 'Missing canonical recipe');
+    return _Utils.asString(s);
+  }
+
+  static void _setCanonicalRecipe(Rti rti, String s) {
+    rti._canonicalRecipe = s;
+  }
+}
+
+class _FunctionParameters {
+  // TODO(fishythefish): Support required named parameters.
+
+  static _FunctionParameters allocate() => _FunctionParameters();
+
+  Object _requiredPositional;
+  static JSArray _getRequiredPositional(_FunctionParameters parameters) =>
+      JS('JSUnmodifiableArray', '#', parameters._requiredPositional);
+  static void _setRequiredPositional(
+      _FunctionParameters parameters, Object requiredPositional) {
+    parameters._requiredPositional = requiredPositional;
+  }
+
+  Object _optionalPositional;
+  static JSArray _getOptionalPositional(_FunctionParameters parameters) =>
+      JS('JSUnmodifiableArray', '#', parameters._optionalPositional);
+  static void _setOptionalPositional(
+      _FunctionParameters parameters, Object optionalPositional) {
+    parameters._optionalPositional = optionalPositional;
+  }
+
+  /// These are alternating name/type pairs; that is, the optional named
+  /// parameters of the function
+  ///
+  ///   void foo({int bar, double baz})
+  ///
+  /// would be encoded as ["bar", int, "baz", double], where the even indices are
+  /// the name [String]s and the odd indices are the type [Rti]s.
+  ///
+  /// Invariant: These pairs are sorted by name in lexicographically ascending order.
+  Object _optionalNamed;
+  static JSArray _getOptionalNamed(_FunctionParameters parameters) =>
+      JS('JSUnmodifiableArray', '#', parameters._optionalNamed);
+  static void _setOptionalNamed(
+      _FunctionParameters parameters, Object optionalNamed) {
+    parameters._optionalNamed = optionalNamed;
+  }
+}
+
+Object _theUniverse() => JS_EMBEDDED_GLOBAL('', RTI_UNIVERSE);
+
+Rti _rtiEval(Rti environment, String recipe) {
+  return _Universe.evalInEnvironment(_theUniverse(), environment, recipe);
+}
+
+Rti _rtiBind1(Rti environment, Rti types) {
+  return _Universe.bind1(_theUniverse(), environment, types);
+}
+
+Rti _rtiBind(Rti environment, Rti types) {
+  return _Universe.bind(_theUniverse(), environment, types);
+}
+
+/// Evaluate a ground-term type.
+/// Called from generated code.
+Rti findType(String recipe) {
+  return _Universe.eval(_theUniverse(), recipe);
+}
+
+/// Evaluate a type recipe in the environment of an instance.
+Rti evalInInstance(instance, String recipe) {
+  return _rtiEval(instanceType(instance), recipe);
+}
+
+/// Returns [genericFunctionRti] with type parameters bound to those specified
+/// by [instantiationRti].
+///
+/// [genericFunctionRti] must be an rti representation with a number of generic
+/// type parameters matching the number of types provided by [instantiationRti].
+///
+/// Called from generated code.
+@pragma('dart2js:noInline')
+Rti instantiatedGenericFunctionType(
+    Rti genericFunctionRti, Rti instantiationRti) {
+  var bounds = Rti._getGenericFunctionBounds(genericFunctionRti);
+  var typeArguments = Rti._getInterfaceTypeArguments(instantiationRti);
+  assert(_Utils.arrayLength(bounds) == _Utils.arrayLength(typeArguments));
+
+  var cache = Rti._getBindCache(genericFunctionRti);
+  if (cache == null) {
+    cache = JS('', 'new Map()');
+    Rti._setBindCache(genericFunctionRti, cache);
+  }
+  String key = Rti._getCanonicalRecipe(instantiationRti);
+  var probe = _Utils.mapGet(cache, key);
+  if (probe != null) return _castToRti(probe);
+  Rti rti = _instantiate(_theUniverse(),
+      Rti._getGenericFunctionBase(genericFunctionRti), typeArguments, 0);
+  _Utils.mapSet(cache, key, rti);
+  return rti;
+}
+
+/// Substitutes [typeArguments] for generic function parameters in [rti].
+///
+/// Generic function parameters are de Bruijn indices counting up through the
+/// parameters' scopes to index into [typeArguments].
+///
+/// [depth] is the number of subsequent generic function parameters that are in
+/// scope. This is subtracted off the de Bruijn index for the type parameter to
+/// arrive at an potential index into [typeArguments].
+Rti _instantiate(universe, Rti rti, Object typeArguments, int depth) {
+  int kind = Rti._getKind(rti);
+  switch (kind) {
+    case Rti.kindNever:
+    case Rti.kindDynamic:
+    case Rti.kindVoid:
+    case Rti.kindAny:
+      return rti;
+    case Rti.kindStar:
+      Rti baseType = _castToRti(Rti._getPrimary(rti));
+      Rti instantiatedBaseType =
+          _instantiate(universe, baseType, typeArguments, depth);
+      if (_Utils.isIdentical(instantiatedBaseType, baseType)) return rti;
+      return _Universe._lookupStarRti(universe, instantiatedBaseType);
+    case Rti.kindQuestion:
+      Rti baseType = _castToRti(Rti._getPrimary(rti));
+      Rti instantiatedBaseType =
+          _instantiate(universe, baseType, typeArguments, depth);
+      if (_Utils.isIdentical(instantiatedBaseType, baseType)) return rti;
+      return _Universe._lookupQuestionRti(universe, instantiatedBaseType);
+    case Rti.kindFutureOr:
+      Rti baseType = _castToRti(Rti._getPrimary(rti));
+      Rti instantiatedBaseType =
+          _instantiate(universe, baseType, typeArguments, depth);
+      if (_Utils.isIdentical(instantiatedBaseType, baseType)) return rti;
+      return _Universe._lookupFutureOrRti(universe, instantiatedBaseType);
+    case Rti.kindInterface:
+      Object interfaceTypeArguments = Rti._getInterfaceTypeArguments(rti);
+      Object instantiatedInterfaceTypeArguments = _instantiateArray(
+          universe, interfaceTypeArguments, typeArguments, depth);
+      if (_Utils.isIdentical(
+          instantiatedInterfaceTypeArguments, interfaceTypeArguments))
+        return rti;
+      return _Universe._lookupInterfaceRti(universe, Rti._getInterfaceName(rti),
+          instantiatedInterfaceTypeArguments);
+    case Rti.kindBinding:
+      Rti base = Rti._getBindingBase(rti);
+      Rti instantiatedBase = _instantiate(universe, base, typeArguments, depth);
+      Object arguments = Rti._getBindingArguments(rti);
+      Object instantiatedArguments =
+          _instantiateArray(universe, arguments, typeArguments, depth);
+      if (_Utils.isIdentical(instantiatedBase, base) &&
+          _Utils.isIdentical(instantiatedArguments, arguments)) return rti;
+      return _Universe._lookupBindingRti(
+          universe, instantiatedBase, instantiatedArguments);
+    case Rti.kindFunction:
+      Rti returnType = Rti._getReturnType(rti);
+      Rti instantiatedReturnType =
+          _instantiate(universe, returnType, typeArguments, depth);
+      _FunctionParameters functionParameters = Rti._getFunctionParameters(rti);
+      _FunctionParameters instantiatedFunctionParameters =
+          _instantiateFunctionParameters(
+              universe, functionParameters, typeArguments, depth);
+      if (_Utils.isIdentical(instantiatedReturnType, returnType) &&
+          _Utils.isIdentical(
+              instantiatedFunctionParameters, functionParameters)) return rti;
+      return _Universe._lookupFunctionRti(
+          universe, instantiatedReturnType, instantiatedFunctionParameters);
+    case Rti.kindGenericFunction:
+      Object bounds = Rti._getGenericFunctionBounds(rti);
+      depth += _Utils.arrayLength(bounds);
+      Object instantiatedBounds =
+          _instantiateArray(universe, bounds, typeArguments, depth);
+      Rti base = Rti._getGenericFunctionBase(rti);
+      Rti instantiatedBase = _instantiate(universe, base, typeArguments, depth);
+      if (_Utils.isIdentical(instantiatedBounds, bounds) &&
+          _Utils.isIdentical(instantiatedBase, base)) return rti;
+      return _Universe._lookupGenericFunctionRti(
+          universe, instantiatedBase, instantiatedBounds);
+    case Rti.kindGenericFunctionParameter:
+      int index = Rti._getGenericFunctionParameterIndex(rti);
+      if (index < depth) return null;
+      return _castToRti(_Utils.arrayAt(typeArguments, index - depth));
+    default:
+      throw AssertionError(
+          'Attempted to instantiate unexpected RTI kind $kind');
+  }
+}
+
+Object _instantiateArray(
+    universe, Object rtiArray, Object typeArguments, int depth) {
+  bool changed = false;
+  int length = _Utils.arrayLength(rtiArray);
+  Object result = JS('', '[]');
+  for (int i = 0; i < length; i++) {
+    Rti rti = _castToRti(_Utils.arrayAt(rtiArray, i));
+    Rti instantiatedRti = _instantiate(universe, rti, typeArguments, depth);
+    if (!_Utils.isIdentical(instantiatedRti, rti)) {
+      changed = true;
+    }
+    _Utils.arrayPush(result, instantiatedRti);
+  }
+  return changed ? result : rtiArray;
+}
+
+Object _instantiateNamed(
+    universe, Object namedArray, Object typeArguments, int depth) {
+  bool changed = false;
+  int length = _Utils.arrayLength(namedArray);
+  assert(length.isEven);
+  Object result = JS('', '[]');
+  for (int i = 0; i < length; i += 2) {
+    String name = _Utils.asString(_Utils.arrayAt(namedArray, i));
+    Rti rti = _castToRti(_Utils.arrayAt(namedArray, i + 1));
+    Rti instantiatedRti = _instantiate(universe, rti, typeArguments, depth);
+    if (!_Utils.isIdentical(instantiatedRti, rti)) {
+      changed = true;
+    }
+    _Utils.arrayPush(result, name);
+    _Utils.arrayPush(result, instantiatedRti);
+  }
+  return changed ? result : namedArray;
+}
+
+// TODO(fishythefish): Support required named parameters.
+_FunctionParameters _instantiateFunctionParameters(universe,
+    _FunctionParameters functionParameters, Object typeArguments, int depth) {
+  Object requiredPositional =
+      _FunctionParameters._getRequiredPositional(functionParameters);
+  Object instantiatedRequiredPositional =
+      _instantiateArray(universe, requiredPositional, typeArguments, depth);
+  Object optionalPositional =
+      _FunctionParameters._getOptionalPositional(functionParameters);
+  Object instantiatedOptionalPositional =
+      _instantiateArray(universe, optionalPositional, typeArguments, depth);
+  Object optionalNamed =
+      _FunctionParameters._getOptionalNamed(functionParameters);
+  Object instantiatedOptionalNamed =
+      _instantiateNamed(universe, optionalNamed, typeArguments, depth);
+  if (_Utils.isIdentical(instantiatedRequiredPositional, requiredPositional) &&
+      _Utils.isIdentical(instantiatedOptionalPositional, optionalPositional) &&
+      _Utils.isIdentical(instantiatedOptionalNamed, optionalNamed))
+    return functionParameters;
+  _FunctionParameters result = _FunctionParameters.allocate();
+  _FunctionParameters._setRequiredPositional(
+      result, instantiatedRequiredPositional);
+  _FunctionParameters._setOptionalPositional(
+      result, instantiatedOptionalPositional);
+  _FunctionParameters._setOptionalNamed(result, instantiatedOptionalNamed);
+  return result;
+}
+
+bool _isClosure(object) => _Utils.instanceOf(object,
+    JS_BUILTIN('depends:none;effects:none;', JsBuiltin.dartClosureConstructor));
+
+/// Returns the structural function [Rti] of [closure].
+/// Called from generated code.
+Rti closureFunctionType(closure) {
+  var signatureName = JS_GET_NAME(JsGetName.SIGNATURE_NAME);
+  var signature = JS('', '#[#]', closure, signatureName);
+  if (signature != null) {
+    if (JS('bool', 'typeof # == "number"', signature)) {
+      return getTypeFromTypesTable(_Utils.asInt(signature));
+    }
+    return _castToRti(JS('', '#[#]()', closure, signatureName));
+  }
+  return null;
+}
+
+// Subclasses of Closure are synthetic classes. The synthetic classes all
+// extend a 'normal' class (Closure, BoundClosure, StaticClosure), so make
+// them appear to be the superclass.
+// TODO(sra): Can this be done less expensively, e.g. by putting $ti on the
+// prototype of Closure/BoundClosure/StaticClosure classes?
+Rti _closureInterfaceType(closure) {
+  var rti = JS('', r'#[#]', closure, JS_GET_NAME(JsGetName.RTI_NAME));
+  return rti != null
+      ? _castToRti(rti)
+      : _instanceTypeFromConstructor(
+          JS('', '#.__proto__.__proto__.constructor', closure));
+}
+
+/// Returns the Rti type of [object]. Closures have both an interface type
+/// (Closures implement `Function`) and a structural function type. Uses
+/// [testRti] to choose the appropriate type.
+///
+/// Called from generated code.
+Rti instanceOrFunctionType(object, Rti testRti) {
+  if (Rti._isUnionOfFunctionType(testRti)) {
+    if (_isClosure(object)) {
+      // If [testRti] is e.g. `FutureOr<Action>` (where `Action` is some
+      // function type), we don't need to worry about the `Future<Action>`
+      // branch because closures can't be `Future`s.
+      Rti rti = closureFunctionType(object);
+      if (rti != null) return rti;
+    }
+  }
+  return instanceType(object);
+}
+
+/// Returns the Rti type of [object].
+/// Called from generated code.
+Rti instanceType(object) {
+  if (_isClosure(object)) return _closureInterfaceType(object);
+  return _nonClosureInstanceType(object);
+}
+
+Rti _nonClosureInstanceType(object) {
+  // TODO(sra): Add specializations of this method. One possible way is to
+  // arrange that the interceptor has a _getType method that is injected into
+  // DartObject, Interceptor and JSArray. Then this method can be replaced-by
+  // `getInterceptor(o)._getType(o)`, allowing interceptor optimizations to
+  // select the specialization.
+
+  if (_Utils.instanceOf(
+      object,
+      JS_BUILTIN(
+          'depends:none;effects:none;', JsBuiltin.dartObjectConstructor))) {
+    return _instanceType(object);
+  }
+
+  if (_Utils.isArray(object)) {
+    return _arrayInstanceType(object);
+  }
+
+  var interceptor = getInterceptor(object);
+  return _instanceTypeFromConstructor(JS('', '#.constructor', interceptor));
+}
+
+/// Returns the Rti type of JavaScript Array [object].
+/// Called from generated code.
+Rti _arrayInstanceType(object) {
+  // TODO(sra): Do we need to protect against an Array passed between two Dart
+  // programs loaded into the same JavaScript isolate (e.g. via JS-interop).
+  // FWIW, the legacy rti has this problem too. Perhaps JSArrays should use a
+  // program-local `symbol` for the type field.
+  var rti = JS('', r'#[#]', object, JS_GET_NAME(JsGetName.RTI_NAME));
+  return rti != null ? _castToRti(rti) : _castToRti(getJSArrayInteropRti());
+}
+
+/// Returns the Rti type of user-defined class [object].
+/// [object] must not be an intercepted class or a closure.
+/// Called from generated code.
+Rti _instanceType(object) {
+  var rti = JS('', r'#[#]', object, JS_GET_NAME(JsGetName.RTI_NAME));
+  return rti != null
+      ? _castToRti(rti)
+      : _instanceTypeFromConstructor(JS('', '#.constructor', object));
+}
+
+String instanceTypeName(object) {
+  Rti rti = instanceType(object);
+  return _rtiToString(rti, null);
+}
+
+Rti _instanceTypeFromConstructor(constructor) {
+  // TODO(sra): Cache Rti on constructor.
+  return findType(JS('String', '#.name', constructor));
+}
+
+/// Returns the structural function type of [object], or `null` if the object is
+/// not a closure.
+Rti _instanceFunctionType(object) =>
+    _isClosure(object) ? closureFunctionType(object) : null;
+
+/// Returns Rti from types table. The types table is initialized with recipe
+/// strings.
+Rti getTypeFromTypesTable(/*int*/ _index) {
+  int index = _Utils.asInt(_index);
+  var table = JS_EMBEDDED_GLOBAL('', TYPES);
+  var type = _Utils.arrayAt(table, index);
+  if (_Utils.isString(type)) {
+    Rti rti = findType(_Utils.asString(type));
+    _Utils.arraySetAt(table, index, rti);
+    return rti;
+  }
+  return _castToRti(type);
+}
+
+Type getRuntimeType(object) {
+  Rti rti = _instanceFunctionType(object) ?? _nonClosureInstanceType(object);
+  return createRuntimeType(rti);
+}
+
+/// Called from generated code.
+Type createRuntimeType(Rti rti) {
+  _Type type = Rti._getCachedRuntimeType(rti);
+  if (type != null) return type;
+  // TODO(https://github.com/dart-lang/language/issues/428) For NNBD transition,
+  // canonicalization may be needed. It might be possible to generate a
+  // star-free recipe from the canonical recipe and evaluate that.
+  type = _Type(rti);
+  Rti._setCachedRuntimeType(rti, type);
+  return type;
+}
+
+/// Called from generated code in the constant pool.
+Type typeLiteral(String recipe) {
+  return createRuntimeType(findType(recipe));
+}
+
+/// Implementation of [Type] based on Rti.
+class _Type implements Type {
+  final Rti _rti;
+  int _hashCode;
+
+  _Type(this._rti);
+
+  int get hashCode => _hashCode ??= Rti._getCanonicalRecipe(_rti).hashCode;
+
+  @pragma('dart2js:noInline')
+  bool operator ==(other) {
+    return (other is _Type) && identical(_rti, other._rti);
+  }
+
+  @override
+  String toString() => _rtiToString(_rti, null);
+}
+
+/// Called from generated code.
+bool _generalIsTestImplementation(object) {
+  // This static method is installed on an Rti object as a JavaScript instance
+  // method. The Rti object is 'this'.
+  Rti testRti = _castToRti(JS('', 'this'));
+  Rti objectRti = instanceOrFunctionType(object, testRti);
+  return isSubtype(_theUniverse(), objectRti, testRti);
+}
+
+/// Called from generated code.
+_generalAsCheckImplementation(object) {
+  if (object == null) return object;
+  // This static method is installed on an Rti object as a JavaScript instance
+  // method. The Rti object is 'this'.
+  Rti testRti = _castToRti(JS('', 'this'));
+  if (Rti._isCheck(testRti, object)) return object;
+
+  Rti objectRti = instanceOrFunctionType(object, testRti);
+  String message =
+      _Error.compose(object, objectRti, _rtiToString(testRti, null));
+  throw _CastError.fromMessage(message);
+}
+
+/// Called from generated code.
+_generalTypeCheckImplementation(object) {
+  if (object == null) return object;
+  // This static method is installed on an Rti object as a JavaScript instance
+  // method. The Rti object is 'this'.
+  Rti testRti = _castToRti(JS('', 'this'));
+  if (Rti._isCheck(testRti, object)) return object;
+
+  Rti objectRti = instanceOrFunctionType(object, testRti);
+  String message =
+      _Error.compose(object, objectRti, _rtiToString(testRti, null));
+  throw _TypeError.fromMessage(message);
+}
+
+/// Called from generated code.
+checkTypeBound(Rti type, Rti bound, variable) {
+  if (isSubtype(_theUniverse(), type, bound)) return type;
+  String message = "Type '${_rtiToString(type, null)}'"
+      " is not a subtype of type '${_rtiToString(bound, null)}'"
+      " of '${_Utils.asString(variable)}'";
+  throw _TypeError.fromMessage(message);
+}
+
+/// Base class to _CastError and _TypeError.
+class _Error extends Error {
+  final String _message;
+  _Error(this._message);
+
+  static String compose(object, objectRti, checkedTypeDescription) {
+    String objectDescription = Error.safeToString(object);
+    objectRti ??= instanceType(object);
+    String objectTypeDescription = _rtiToString(objectRti, null);
+    return "${objectDescription}:"
+        " type '${objectTypeDescription}'"
+        " is not a subtype of type '${checkedTypeDescription}'";
+  }
+
+  @override
+  String toString() => _message;
+}
+
+class _CastError extends _Error implements CastError {
+  _CastError.fromMessage(String message) : super('CastError: $message');
+
+  factory _CastError.forType(object, String type) {
+    return _CastError.fromMessage(_Error.compose(object, null, type));
+  }
+}
+
+class _TypeError extends _Error implements TypeError {
+  _TypeError.fromMessage(String message) : super('TypeError: $message');
+
+  factory _TypeError.forType(object, String type) {
+    return _TypeError.fromMessage(_Error.compose(object, null, type));
+  }
+
+  @override
+  String get message => _message;
+}
+
+// Specializations.
+//
+// Specializations can be placed on Rti objects as the _as, _check and _is
+// 'methods'. They can also be called directly called from generated code.
+
+/// Specialization for 'is bool'.
+/// Called from generated code.
+bool _isBool(object) {
+  return true == object || false == object;
+}
+
+/// Specialization for 'as bool?'.
+/// Called from generated code.
+bool /*?*/ _asBoolNullable(object) {
+  if (_isBool(object)) return _Utils.asBool(object);
+  if (object == null) return object;
+  throw _CastError.forType(object, 'bool');
+}
+
+/// Specialization for check on 'bool?'.
+/// Called from generated code.
+bool /*?*/ _checkBoolNullable(object) {
+  if (_isBool(object)) return _Utils.asBool(object);
+  if (object == null) return object;
+  throw _TypeError.forType(object, 'bool');
+}
+
+/// Specialization for 'as double?'.
+/// Called from generated code.
+double /*?*/ _asDoubleNullable(object) {
+  if (_isNum(object)) return _Utils.asDouble(object);
+  if (object == null) return object;
+  throw _CastError.forType(object, 'double');
+}
+
+/// Specialization for check on 'double?'.
+/// Called from generated code.
+double /*?*/ _checkDoubleNullable(object) {
+  if (_isNum(object)) return _Utils.asDouble(object);
+  if (object == null) return object;
+  throw _TypeError.forType(object, 'double');
+}
+
+/// Specialization for 'is int'.
+/// Called from generated code.
+bool _isInt(object) {
+  return JS('bool', 'typeof # == "number"', object) &&
+      JS('bool', 'Math.floor(#) === #', object, object);
+}
+
+/// Specialization for 'as int?'.
+/// Called from generated code.
+int /*?*/ _asIntNullable(object) {
+  if (_isInt(object)) return _Utils.asInt(object);
+  if (object == null) return object;
+  throw _CastError.forType(object, 'int');
+}
+
+/// Specialization for check on 'int?'.
+/// Called from generated code.
+int /*?*/ _checkIntNullable(object) {
+  if (_isInt(object)) return _Utils.asInt(object);
+  if (object == null) return object;
+  throw _TypeError.forType(object, 'int');
+}
+
+/// Specialization for 'is num' and 'is double'.
+/// Called from generated code.
+bool _isNum(object) {
+  return JS('bool', 'typeof # == "number"', object);
+}
+
+/// Specialization for 'as num?'.
+/// Called from generated code.
+num /*?*/ _asNumNullable(object) {
+  if (_isNum(object)) return _Utils.asNum(object);
+  if (object == null) return object;
+  throw _CastError.forType(object, 'num');
+}
+
+/// Specialization for check on 'num?'.
+/// Called from generated code.
+num /*?*/ _checkNumNullable(object) {
+  if (_isNum(object)) return _Utils.asNum(object);
+  if (object == null) return object;
+  throw _TypeError.forType(object, 'num');
+}
+
+/// Specialization for 'is String'.
+/// Called from generated code.
+bool _isString(object) {
+  return JS('bool', 'typeof # == "string"', object);
+}
+
+/// Specialization for 'as String?'.
+/// Called from generated code.
+String /*?*/ _asStringNullable(object) {
+  if (_isString(object)) return _Utils.asString(object);
+  if (object == null) return object;
+  throw _CastError.forType(object, 'String');
+}
+
+/// Specialization for check on 'String?'.
+/// Called from generated code.
+String /*?*/ _checkStringNullable(object) {
+  if (_isString(object)) return _Utils.asString(object);
+  if (object == null) return object;
+  throw _TypeError.forType(object, 'String');
+}
+
+String _rtiArrayToString(Object array, List<String> genericContext) {
+  String s = '', sep = '';
+  for (int i = 0; i < _Utils.arrayLength(array); i++) {
+    s += sep +
+        _rtiToString(_castToRti(_Utils.arrayAt(array, i)), genericContext);
+    sep = ', ';
+  }
+  return s;
+}
+
+String _functionRtiToString(Rti functionType, List<String> genericContext,
+    {Object bounds = null}) {
+  String typeParametersText = '';
+  int outerContextLength;
+
+  if (bounds != null) {
+    int boundsLength = _Utils.arrayLength(bounds);
+    if (genericContext == null) {
+      genericContext = <String>[];
+    } else {
+      outerContextLength = genericContext.length;
+    }
+    int offset = genericContext.length;
+    for (int i = boundsLength; i > 0; i--) {
+      genericContext.add('T${offset + i}');
+    }
+
+    String typeSep = '';
+    typeParametersText = '<';
+    for (int i = 0; i < boundsLength; i++) {
+      typeParametersText += typeSep;
+      typeParametersText += genericContext[genericContext.length - 1 - i];
+      Rti boundRti = _castToRti(_Utils.arrayAt(bounds, i));
+      if (!isTopType(boundRti)) {
+        typeParametersText +=
+            ' extends ' + _rtiToString(boundRti, genericContext);
+      }
+      typeSep = ', ';
+    }
+    typeParametersText += '>';
+  }
+
+  // TODO(fishythefish): Support required named parameters.
+  Rti returnType = Rti._getReturnType(functionType);
+  _FunctionParameters parameters = Rti._getFunctionParameters(functionType);
+  var requiredPositional =
+      _FunctionParameters._getRequiredPositional(parameters);
+  int requiredPositionalLength = _Utils.arrayLength(requiredPositional);
+  var optionalPositional =
+      _FunctionParameters._getOptionalPositional(parameters);
+  int optionalPositionalLength = _Utils.arrayLength(optionalPositional);
+  var optionalNamed = _FunctionParameters._getOptionalNamed(parameters);
+  int optionalNamedLength = _Utils.arrayLength(optionalNamed);
+  assert(optionalPositionalLength == 0 || optionalNamedLength == 0);
+
+  String returnTypeText = _rtiToString(returnType, genericContext);
+
+  String argumentsText = '';
+  String sep = '';
+  for (int i = 0; i < requiredPositionalLength; i++) {
+    argumentsText += sep +
+        _rtiToString(
+            _castToRti(_Utils.arrayAt(requiredPositional, i)), genericContext);
+    sep = ', ';
+  }
+
+  if (optionalPositionalLength > 0) {
+    argumentsText += sep + '[';
+    sep = '';
+    for (int i = 0; i < optionalPositionalLength; i++) {
+      argumentsText += sep +
+          _rtiToString(_castToRti(_Utils.arrayAt(optionalPositional, i)),
+              genericContext);
+      sep = ', ';
+    }
+    argumentsText += ']';
+  }
+
+  if (optionalNamedLength > 0) {
+    argumentsText += sep + '{';
+    sep = '';
+    for (int i = 0; i < optionalNamedLength; i += 2) {
+      argumentsText += sep +
+          _rtiToString(_castToRti(_Utils.arrayAt(optionalNamed, i + 1)),
+              genericContext) +
+          ' ' +
+          _Utils.asString(_Utils.arrayAt(optionalNamed, i));
+      sep = ', ';
+    }
+    argumentsText += '}';
+  }
+
+  if (outerContextLength != null) {
+    // Pop all of the generic type parameters.
+    JS('', '#.length = #', genericContext, outerContextLength);
+  }
+
+  // TODO(fishythefish): Below is the same format as the VM. Change to:
+  //
+  //     return '${returnTypeText} Function${typeParametersText}(${argumentsText})';
+  //
+  return '${typeParametersText}(${argumentsText}) => ${returnTypeText}';
+}
+
+String _rtiToString(Rti rti, List<String> genericContext) {
+  int kind = Rti._getKind(rti);
+
+  if (kind == Rti.kindDynamic) return 'dynamic';
+  if (kind == Rti.kindVoid) return 'void';
+  if (kind == Rti.kindNever) return 'Never';
+  if (kind == Rti.kindAny) return 'any';
+
+  if (kind == Rti.kindStar) {
+    Rti starArgument = Rti._getStarArgument(rti);
+    return '${_rtiToString(starArgument, genericContext)}*';
+  }
+
+  if (kind == Rti.kindQuestion) {
+    Rti questionArgument = Rti._getQuestionArgument(rti);
+    return '${_rtiToString(questionArgument, genericContext)}?';
+  }
+
+  if (kind == Rti.kindFutureOr) {
+    Rti futureOrArgument = Rti._getFutureOrArgument(rti);
+    return 'FutureOr<${_rtiToString(futureOrArgument, genericContext)}>';
+  }
+
+  if (kind == Rti.kindInterface) {
+    String name = Rti._getInterfaceName(rti);
+    name = _unminifyOrTag(name);
+    var arguments = Rti._getInterfaceTypeArguments(rti);
+    if (arguments.length != 0) {
+      name += '<' + _rtiArrayToString(arguments, genericContext) + '>';
+    }
+    return name;
+  }
+
+  if (kind == Rti.kindFunction) {
+    return _functionRtiToString(rti, genericContext);
+  }
+
+  if (kind == Rti.kindGenericFunction) {
+    Rti baseFunctionType = Rti._getGenericFunctionBase(rti);
+    Object bounds = Rti._getGenericFunctionBounds(rti);
+    return _functionRtiToString(baseFunctionType, genericContext,
+        bounds: bounds);
+  }
+
+  if (kind == Rti.kindGenericFunctionParameter) {
+    int index = Rti._getGenericFunctionParameterIndex(rti);
+    return genericContext[genericContext.length - 1 - index];
+  }
+
+  return '?';
+}
+
+String _unminifyOrTag(String rawClassName) {
+  String preserved = unmangleGlobalNameIfPreservedAnyways(rawClassName);
+  if (preserved != null) return preserved;
+  return JS_GET_FLAG('MINIFIED') ? 'minified:$rawClassName' : rawClassName;
+}
+
+String _rtiArrayToDebugString(Object array) {
+  String s = '[', sep = '';
+  for (int i = 0; i < _Utils.arrayLength(array); i++) {
+    s += sep + _rtiToDebugString(_castToRti(_Utils.arrayAt(array, i)));
+    sep = ', ';
+  }
+  return s + ']';
+}
+
+String functionParametersToString(_FunctionParameters parameters) {
+  // TODO(fishythefish): Support required named parameters.
+  String s = '(', sep = '';
+  var requiredPositional =
+      _FunctionParameters._getRequiredPositional(parameters);
+  int requiredPositionalLength = _Utils.arrayLength(requiredPositional);
+  var optionalPositional =
+      _FunctionParameters._getOptionalPositional(parameters);
+  int optionalPositionalLength = _Utils.arrayLength(optionalPositional);
+  var optionalNamed = _FunctionParameters._getOptionalNamed(parameters);
+  int optionalNamedLength = _Utils.arrayLength(optionalNamed);
+  assert(optionalPositionalLength == 0 || optionalNamedLength == 0);
+
+  for (int i = 0; i < requiredPositionalLength; i++) {
+    s += sep +
+        _rtiToDebugString(_castToRti(_Utils.arrayAt(requiredPositional, i)));
+    sep = ', ';
+  }
+
+  if (optionalPositionalLength > 0) {
+    s += sep + '[';
+    sep = '';
+    for (int i = 0; i < optionalPositionalLength; i++) {
+      s += sep +
+          _rtiToDebugString(_castToRti(_Utils.arrayAt(optionalPositional, i)));
+      sep = ', ';
+    }
+    s += ']';
+  }
+
+  if (optionalNamedLength > 0) {
+    s += sep + '{';
+    sep = '';
+    for (int i = 0; i < optionalNamedLength; i += 2) {
+      s += sep +
+          _rtiToDebugString(_castToRti(_Utils.arrayAt(optionalNamed, i + 1))) +
+          ' ' +
+          _Utils.asString(_Utils.arrayAt(optionalNamed, i));
+      sep = ', ';
+    }
+    s += '}';
+  }
+
+  return s + ')';
+}
+
+String _rtiToDebugString(Rti rti) {
+  int kind = Rti._getKind(rti);
+
+  if (kind == Rti.kindDynamic) return 'dynamic';
+  if (kind == Rti.kindVoid) return 'void';
+  if (kind == Rti.kindNever) return 'Never';
+  if (kind == Rti.kindAny) return 'any';
+
+  if (kind == Rti.kindStar) {
+    Rti starArgument = Rti._getStarArgument(rti);
+    return 'star(${_rtiToDebugString(starArgument)})';
+  }
+
+  if (kind == Rti.kindQuestion) {
+    Rti questionArgument = Rti._getQuestionArgument(rti);
+    return 'question(${_rtiToDebugString(questionArgument)})';
+  }
+
+  if (kind == Rti.kindFutureOr) {
+    Rti futureOrArgument = Rti._getFutureOrArgument(rti);
+    return 'FutureOr(${_rtiToDebugString(futureOrArgument)})';
+  }
+
+  if (kind == Rti.kindInterface) {
+    String name = Rti._getInterfaceName(rti);
+    var arguments = Rti._getInterfaceTypeArguments(rti);
+    if (_Utils.arrayLength(arguments) == 0) {
+      return 'interface("$name")';
+    } else {
+      return 'interface("$name", ${_rtiArrayToDebugString(arguments)})';
+    }
+  }
+
+  if (kind == Rti.kindBinding) {
+    Rti base = Rti._getBindingBase(rti);
+    var arguments = Rti._getBindingArguments(rti);
+    return 'binding(${_rtiToDebugString(base)}, ${_rtiArrayToDebugString(arguments)})';
+  }
+
+  if (kind == Rti.kindFunction) {
+    Rti returnType = Rti._getReturnType(rti);
+    _FunctionParameters parameters = Rti._getFunctionParameters(rti);
+    return 'function(${_rtiToDebugString(returnType)}, ${functionParametersToString(parameters)})';
+  }
+
+  if (kind == Rti.kindGenericFunction) {
+    Rti baseFunctionType = Rti._getGenericFunctionBase(rti);
+    Object bounds = Rti._getGenericFunctionBounds(rti);
+    return 'genericFunction(${_rtiToDebugString(baseFunctionType)}, ${_rtiArrayToDebugString(bounds)})';
+  }
+
+  if (kind == Rti.kindGenericFunctionParameter) {
+    int index = Rti._getGenericFunctionParameterIndex(rti);
+    return 'genericFunctionParameter($index)';
+  }
+
+  return 'other(kind=$kind)';
+}
+
+/// Class of static methods for the universe of Rti objects.
+///
+/// The universe is the manager object for the Rti instances.
+///
+/// The universe itself is allocated at startup before any types or Dart objects
+/// can be created, so it does not have a Dart type.
+class _Universe {
+  _Universe._() {
+    throw UnimplementedError('_Universe is static methods only');
+  }
+
+  @pragma('dart2js:noInline')
+  static Object create() {
+    // This needs to be kept in sync with `FragmentEmitter.createRtiUniverse` in
+    // `fragment_emitter.dart`.
+    return JS(
+        '',
+        '{'
+            '#: new Map(),'
+            '#: {},'
+            '#: [],' // shared empty array.
+            '}',
+        RtiUniverseFieldNames.evalCache,
+        RtiUniverseFieldNames.typeRules,
+        RtiUniverseFieldNames.sharedEmptyArray);
+  }
+
+  // Field accessors.
+
+  static evalCache(universe) =>
+      JS('', '#.#', universe, RtiUniverseFieldNames.evalCache);
+
+  static Object typeRules(universe) =>
+      JS('', '#.#', universe, RtiUniverseFieldNames.typeRules);
+
+  static Object findRule(universe, String targetType) =>
+      JS('', '#.#', typeRules(universe), targetType);
+
+  static void addRules(universe, rules) {
+    // TODO(fishythefish): Use `Object.assign()` when IE11 is deprecated.
+    var keys = JS('JSArray', 'Object.keys(#)', rules);
+    int length = _Utils.arrayLength(keys);
+    Object ruleset = typeRules(universe);
+    for (int i = 0; i < length; i++) {
+      String targetType = _Utils.asString(_Utils.arrayAt(keys, i));
+      JS('', '#[#] = #[#]', ruleset, targetType, rules, targetType);
+    }
+  }
+
+  static Object sharedEmptyArray(universe) =>
+      JS('JSArray', '#.#', universe, RtiUniverseFieldNames.sharedEmptyArray);
+
+  /// Evaluates [recipe] in the global environment.
+  static Rti eval(Object universe, String recipe) {
+    var cache = evalCache(universe);
+    var probe = _cacheGet(cache, recipe);
+    if (probe != null) return _castToRti(probe);
+    Rti rti = _parseRecipe(universe, null, recipe);
+    _cacheSet(cache, recipe, rti);
+    return rti;
+  }
+
+  static Rti evalInEnvironment(
+      Object universe, Rti environment, String recipe) {
+    var cache = Rti._getEvalCache(environment);
+    if (cache == null) {
+      cache = JS('', 'new Map()');
+      Rti._setEvalCache(environment, cache);
+    }
+    var probe = _cacheGet(cache, recipe);
+    if (probe != null) return _castToRti(probe);
+    Rti rti = _parseRecipe(universe, environment, recipe);
+    _cacheSet(cache, recipe, rti);
+    return rti;
+  }
+
+  static Rti bind(Object universe, Rti environment, Rti argumentsRti) {
+    var cache = Rti._getBindCache(environment);
+    if (cache == null) {
+      cache = JS('', 'new Map()');
+      Rti._setBindCache(environment, cache);
+    }
+    String argumentsRecipe = Rti._getCanonicalRecipe(argumentsRti);
+    var probe = _cacheGet(cache, argumentsRecipe);
+    if (probe != null) return _castToRti(probe);
+    var argumentsArray;
+    if (Rti._getKind(argumentsRti) == Rti.kindBinding) {
+      argumentsArray = Rti._getBindingArguments(argumentsRti);
+    } else {
+      argumentsArray = JS('', '[#]', argumentsRti);
+    }
+    Rti rti = _lookupBindingRti(universe, environment, argumentsArray);
+    _cacheSet(cache, argumentsRecipe, rti);
+    return rti;
+  }
+
+  static Rti bind1(Object universe, Rti environment, Rti argumentsRti) {
+    throw UnimplementedError('_Universe.bind1');
+  }
+
+  static Rti evalTypeVariable(Object universe, Rti environment, String name) {
+    if (Rti._getKind(environment) == Rti.kindBinding) {
+      environment = Rti._getBindingBase(environment);
+    }
+
+    assert(Rti._getKind(environment) == Rti.kindInterface);
+    String interfaceName = Rti._getInterfaceName(environment);
+    Object rule = _Universe.findRule(universe, interfaceName);
+    assert(rule != null);
+    String recipe = TypeRule.lookupTypeVariable(rule, name);
+    return _Universe.evalInEnvironment(universe, environment, recipe);
+  }
+
+  static _cacheGet(cache, key) => JS('', '#.get(#)', cache, key);
+  static void _cacheSet(cache, key, value) {
+    JS('', '#.set(#, #)', cache, key, value);
+  }
+
+  static Rti _parseRecipe(Object universe, Object environment, String recipe) {
+    Object parser = _Parser.create(universe, environment, recipe);
+    Rti rti = _Parser.parse(parser);
+    if (rti != null) return rti;
+    throw UnimplementedError('_Universe._parseRecipe("$recipe")');
+  }
+
+  static Rti _finishRti(Object universe, Rti rti) {
+    // Enter fresh Rti in global table under it's canonical recipe.
+    String key = Rti._getCanonicalRecipe(rti);
+    _cacheSet(evalCache(universe), key, rti);
+
+    // Set up methods to perform type tests.
+
+    // TODO(sra): Find better way to install specializations. Perhaps the
+    // installed version should replace itself with the specialization.
+    var checkFn = RAW_DART_FUNCTION_REF(_generalTypeCheckImplementation);
+    var asFn = RAW_DART_FUNCTION_REF(_generalAsCheckImplementation);
+    var isFn = RAW_DART_FUNCTION_REF(_generalIsTestImplementation);
+
+    if (JS_GET_NAME(JsGetName.INT_RECIPE) == key) {
+      isFn = RAW_DART_FUNCTION_REF(_isInt);
+    } else if (JS_GET_NAME(JsGetName.DOUBLE_RECIPE) == key) {
+      isFn = RAW_DART_FUNCTION_REF(_isNum);
+    } else if (JS_GET_NAME(JsGetName.NUM_RECIPE) == key) {
+      isFn = RAW_DART_FUNCTION_REF(_isNum);
+    } else if (JS_GET_NAME(JsGetName.STRING_RECIPE) == key) {
+      isFn = RAW_DART_FUNCTION_REF(_isString);
+    } else if (JS_GET_NAME(JsGetName.BOOL_RECIPE) == key) {
+      isFn = RAW_DART_FUNCTION_REF(_isBool);
+    }
+
+    Rti._setAsCheckFunction(rti, asFn);
+    Rti._setTypeCheckFunction(rti, checkFn);
+    Rti._setIsTestFunction(rti, isFn);
+    return rti;
+  }
+
+  // For each kind of Rti there are three methods:
+  //
+  // * `lookupXXX` which takes the component parts and returns an existing Rti
+  //   object if it exists.
+  // * `canonicalRecipeOfXXX` that returns the compositional canonical recipe
+  //   for the proposed type.
+  // * `createXXX` to create the type if it does not exist.
+
+  static String _canonicalRecipeOfDynamic() => Recipe.pushDynamicString;
+  static String _canonicalRecipeOfVoid() => Recipe.pushVoidString;
+  static String _canonicalRecipeOfNever() =>
+      Recipe.pushNeverExtensionString + Recipe.extensionOpString;
+  static String _canonicalRecipeOfAny() =>
+      Recipe.pushAnyExtensionString + Recipe.extensionOpString;
+
+  static String _canonicalRecipeOfStar(Rti baseType) =>
+      Rti._getCanonicalRecipe(baseType) + Recipe.wrapStarString;
+  static String _canonicalRecipeOfQuestion(Rti baseType) =>
+      Rti._getCanonicalRecipe(baseType) + Recipe.wrapQuestionString;
+  static String _canonicalRecipeOfFutureOr(Rti baseType) =>
+      Rti._getCanonicalRecipe(baseType) + Recipe.wrapFutureOrString;
+
+  static String _canonicalRecipeOfGenericFunctionParameter(int index) =>
+      '$index' + Recipe.genericFunctionTypeParameterIndexString;
+
+  static Rti _lookupDynamicRti(universe) {
+    return _lookupTerminalRti(
+        universe, Rti.kindDynamic, _canonicalRecipeOfDynamic());
+  }
+
+  static Rti _lookupVoidRti(universe) {
+    return _lookupTerminalRti(universe, Rti.kindVoid, _canonicalRecipeOfVoid());
+  }
+
+  static Rti _lookupNeverRti(universe) {
+    return _lookupTerminalRti(
+        universe, Rti.kindNever, _canonicalRecipeOfNever());
+  }
+
+  static Rti _lookupAnyRti(universe) {
+    return _lookupTerminalRti(universe, Rti.kindAny, _canonicalRecipeOfAny());
+  }
+
+  static Rti _lookupTerminalRti(universe, int kind, String canonicalRecipe) {
+    var cache = evalCache(universe);
+    var probe = _cacheGet(cache, canonicalRecipe);
+    if (probe != null) return _castToRti(probe);
+    return _createTerminalRti(universe, kind, canonicalRecipe);
+  }
+
+  static Rti _createTerminalRti(universe, int kind, String canonicalRecipe) {
+    Rti rti = Rti.allocate();
+    Rti._setKind(rti, kind);
+    Rti._setCanonicalRecipe(rti, canonicalRecipe);
+    return _finishRti(universe, rti);
+  }
+
+  static Rti _lookupStarRti(universe, Rti baseType) => _lookupUnaryRti(
+      universe, Rti.kindStar, baseType, _canonicalRecipeOfStar(baseType));
+
+  static Rti _lookupQuestionRti(universe, Rti baseType) => _lookupUnaryRti(
+      universe,
+      Rti.kindQuestion,
+      baseType,
+      _canonicalRecipeOfQuestion(baseType));
+
+  static Rti _lookupFutureOrRti(universe, Rti baseType) => _lookupUnaryRti(
+      universe,
+      Rti.kindFutureOr,
+      baseType,
+      _canonicalRecipeOfFutureOr(baseType));
+
+  static Rti _lookupUnaryRti(
+      universe, int kind, Rti baseType, String canonicalRecipe) {
+    var cache = evalCache(universe);
+    var probe = _cacheGet(cache, canonicalRecipe);
+    if (probe != null) return _castToRti(probe);
+    return _createUnaryRti(universe, kind, baseType, canonicalRecipe);
+  }
+
+  static Rti _createUnaryRti(
+      universe, int kind, Rti baseType, String canonicalRecipe) {
+    Rti rti = Rti.allocate();
+    Rti._setKind(rti, kind);
+    Rti._setPrimary(rti, baseType);
+    Rti._setCanonicalRecipe(rti, canonicalRecipe);
+    return _finishRti(universe, rti);
+  }
+
+  static Rti _lookupGenericFunctionParameterRti(universe, int index) {
+    String canonicalRecipe = _canonicalRecipeOfGenericFunctionParameter(index);
+    var cache = evalCache(universe);
+    var probe = _cacheGet(cache, canonicalRecipe);
+    if (probe != null) return _castToRti(probe);
+    return _createGenericFunctionParameterRti(universe, index, canonicalRecipe);
+  }
+
+  static Rti _createGenericFunctionParameterRti(
+      universe, int index, String canonicalRecipe) {
+    Rti rti = Rti.allocate();
+    Rti._setKind(rti, Rti.kindGenericFunctionParameter);
+    Rti._setPrimary(rti, index);
+    Rti._setCanonicalRecipe(rti, canonicalRecipe);
+    return _finishRti(universe, rti);
+  }
+
+  static String _canonicalRecipeJoin(Object arguments) {
+    String s = '', sep = '';
+    int length = _Utils.arrayLength(arguments);
+    for (int i = 0; i < length; i++) {
+      Rti argument = _castToRti(_Utils.arrayAt(arguments, i));
+      String subrecipe = Rti._getCanonicalRecipe(argument);
+      s += sep + subrecipe;
+      sep = Recipe.separatorString;
+    }
+    return s;
+  }
+
+  static String _canonicalRecipeJoinNamed(Object arguments) {
+    String s = '', sep = '';
+    int length = _Utils.arrayLength(arguments);
+    assert(length.isEven);
+    for (int i = 0; i < length; i += 2) {
+      String name = _Utils.asString(_Utils.arrayAt(arguments, i));
+      Rti type = _castToRti(_Utils.arrayAt(arguments, i + 1));
+      String subrecipe = Rti._getCanonicalRecipe(type);
+      s += sep + name + Recipe.nameSeparatorString + subrecipe;
+      sep = Recipe.separatorString;
+    }
+    return s;
+  }
+
+  static String _canonicalRecipeOfInterface(String name, Object arguments) {
+    assert(_Utils.isString(name));
+    String s = _Utils.asString(name);
+    int length = _Utils.arrayLength(arguments);
+    if (length != 0) {
+      s += Recipe.startTypeArgumentsString +
+          _canonicalRecipeJoin(arguments) +
+          Recipe.endTypeArgumentsString;
+    }
+    return s;
+  }
+
+  static Rti _lookupInterfaceRti(
+      Object universe, String name, Object arguments) {
+    String key = _canonicalRecipeOfInterface(name, arguments);
+    var cache = evalCache(universe);
+    var probe = _cacheGet(cache, key);
+    if (probe != null) return _castToRti(probe);
+    return _createInterfaceRti(universe, name, arguments, key);
+  }
+
+  static Rti _createInterfaceRti(
+      Object universe, String name, Object typeArguments, String key) {
+    Rti rti = Rti.allocate();
+    Rti._setKind(rti, Rti.kindInterface);
+    Rti._setPrimary(rti, name);
+    Rti._setRest(rti, typeArguments);
+    Rti._setCanonicalRecipe(rti, key);
+    return _finishRti(universe, rti);
+  }
+
+  static String _canonicalRecipeOfBinding(Rti base, Object arguments) {
+    String s = Rti._getCanonicalRecipe(base);
+    s += Recipe
+        .toTypeString; // TODO(sra): Omit when base encoding is Rti without ToType.
+    s += Recipe.startTypeArgumentsString +
+        _canonicalRecipeJoin(arguments) +
+        Recipe.endTypeArgumentsString;
+    return s;
+  }
+
+  /// [arguments] becomes owned by the created Rti.
+  static Rti _lookupBindingRti(Object universe, Rti base, Object arguments) {
+    Rti newBase = base;
+    Object newArguments = arguments;
+    if (Rti._getKind(base) == Rti.kindBinding) {
+      newBase = Rti._getBindingBase(base);
+      newArguments =
+          _Utils.arrayConcat(Rti._getBindingArguments(base), arguments);
+    }
+    String key = _canonicalRecipeOfBinding(newBase, newArguments);
+    var cache = evalCache(universe);
+    var probe = _cacheGet(cache, key);
+    if (probe != null) return _castToRti(probe);
+    return _createBindingRti(universe, newBase, newArguments, key);
+  }
+
+  static Rti _createBindingRti(
+      Object universe, Rti base, Object arguments, String key) {
+    Rti rti = Rti.allocate();
+    Rti._setKind(rti, Rti.kindBinding);
+    Rti._setPrimary(rti, base);
+    Rti._setRest(rti, arguments);
+    Rti._setCanonicalRecipe(rti, key);
+    return _finishRti(universe, rti);
+  }
+
+  static String _canonicalRecipeOfFunction(
+          Rti returnType, _FunctionParameters parameters) =>
+      Rti._getCanonicalRecipe(returnType) +
+      _canonicalRecipeOfFunctionParameters(parameters);
+
+  // TODO(fishythefish): Support required named parameters.
+  static String _canonicalRecipeOfFunctionParameters(
+      _FunctionParameters parameters) {
+    var requiredPositional =
+        _FunctionParameters._getRequiredPositional(parameters);
+    int requiredPositionalLength = _Utils.arrayLength(requiredPositional);
+    var optionalPositional =
+        _FunctionParameters._getOptionalPositional(parameters);
+    int optionalPositionalLength = _Utils.arrayLength(optionalPositional);
+    var optionalNamed = _FunctionParameters._getOptionalNamed(parameters);
+    int optionalNamedLength = _Utils.arrayLength(optionalNamed);
+    assert(optionalPositionalLength == 0 || optionalNamedLength == 0);
+
+    String recipe = Recipe.startFunctionArgumentsString +
+        _canonicalRecipeJoin(requiredPositional);
+
+    if (optionalPositionalLength > 0) {
+      String sep = requiredPositionalLength > 0 ? Recipe.separatorString : '';
+      recipe += sep +
+          Recipe.startOptionalGroupString +
+          _canonicalRecipeJoin(optionalPositional) +
+          Recipe.endOptionalGroupString;
+    }
+
+    if (optionalNamedLength > 0) {
+      String sep = requiredPositionalLength > 0 ? Recipe.separatorString : '';
+      recipe += sep +
+          Recipe.startNamedGroupString +
+          _canonicalRecipeJoinNamed(optionalNamed) +
+          Recipe.endNamedGroupString;
+    }
+
+    return recipe + Recipe.endFunctionArgumentsString;
+  }
+
+  static Rti _lookupFunctionRti(
+      Object universe, Rti returnType, _FunctionParameters parameters) {
+    String key = _canonicalRecipeOfFunction(returnType, parameters);
+    var cache = evalCache(universe);
+    var probe = _cacheGet(cache, key);
+    if (probe != null) return _castToRti(probe);
+    return _createFunctionRti(universe, returnType, parameters, key);
+  }
+
+  static Rti _createFunctionRti(Object universe, Rti returnType,
+      _FunctionParameters parameters, String canonicalRecipe) {
+    Rti rti = Rti.allocate();
+    Rti._setKind(rti, Rti.kindFunction);
+    Rti._setPrimary(rti, returnType);
+    Rti._setRest(rti, parameters);
+    Rti._setCanonicalRecipe(rti, canonicalRecipe);
+    return _finishRti(universe, rti);
+  }
+
+  static String _canonicalRecipeOfGenericFunction(
+          Rti baseFunctionType, Object bounds) =>
+      Rti._getCanonicalRecipe(baseFunctionType) +
+      Recipe.startTypeArgumentsString +
+      _canonicalRecipeJoin(bounds) +
+      Recipe.endTypeArgumentsString;
+
+  static Rti _lookupGenericFunctionRti(
+      Object universe, Rti baseFunctionType, Object bounds) {
+    String key = _canonicalRecipeOfGenericFunction(baseFunctionType, bounds);
+    var cache = evalCache(universe);
+    var probe = _cacheGet(cache, key);
+    if (probe != null) return _castToRti(probe);
+    return _createGenericFunctionRti(universe, baseFunctionType, bounds, key);
+  }
+
+  static Rti _createGenericFunctionRti(Object universe, Rti baseFunctionType,
+      Object bounds, String canonicalRecipe) {
+    Rti rti = Rti.allocate();
+    Rti._setKind(rti, Rti.kindGenericFunction);
+    Rti._setPrimary(rti, baseFunctionType);
+    Rti._setRest(rti, bounds);
+    Rti._setCanonicalRecipe(rti, canonicalRecipe);
+    return _finishRti(universe, rti);
+  }
+}
+
+/// Class of static methods implementing recipe parser.
+///
+/// The recipe is a sequence of operations on a stack machine. The operations
+/// are described below using the format
+///
+///      operation: stack elements before --- stack elements after
+///
+/// integer:  --- integer-value
+///
+/// identifier:  --- string-value
+///
+/// identifier-with-one-period:  --- type-variable-value
+///
+///   Period may be in any position, including first and last e.g. `.x`.
+///
+/// ',':  ---
+///
+///   Ignored. Used to separate elements.
+///
+/// ';': item  ---  ToType(item)
+///
+///   Used to separate elements.
+///
+/// '@': --- dynamicType
+///
+/// '~': --- voidType
+///
+/// '?':  type  ---  type?
+///
+/// '&':  0  ---  NeverType
+/// '&':  1  ---  anyType
+///
+///   Escape op-code with small integer values for encoding rare operations.
+///
+/// '<':  --- position
+///
+///   Saves (pushes) position register, sets position register to end of stack.
+///
+/// '>':  name saved-position type ... type  ---  name<type, ..., type>
+/// '>':  type saved-position type ... type  ---  binding(type, type, ..., type)
+///
+///   When first element is a String: Creates interface type from string 'name'
+///   and the types pushed since the position register was last set. The types
+///   are converted with a ToType operation. Restores position register to
+///   previous saved value.
+///
+///   When first element is an Rti: Creates binding Rti wrapping the first
+///   element. Binding Rtis are flattened: if the first element is a binding
+///   Rti, the new binding Rti has the concatentation of the first element
+///   bindings and new type.
+///
+///
+/// The ToType operation coerces an item to an Rti. This saves encoding looking
+/// up simple interface names and indexed variables.
+///
+///   ToType(string): Creates an interface Rti for the non-generic class.
+///   ToType(integer): Indexes into the environment.
+///   ToType(Rti): Same Rti
+///
+///
+/// Notes on enviroments and indexing.
+///
+/// To avoid creating a binding Rti for a single function type parameter, the
+/// type is passed without creating a 1-tuple object. This means that the
+/// interface Rti for, say, `Map<num,dynamic>` serves as two environments with
+/// different shapes. It is a class environment (K=num, V=dynamic) and a simple
+/// 1-tuple environment. This is supported by index '0' refering to the whole
+/// type, and '1 and '2' refering to K and V positionally:
+///
+///     interface("Map", [num,dynamic])
+///     0                 1   2
+///
+/// Thus the type expression `List<K>` encodes as `List<1>` and in this
+/// environment evaluates to `List<num>`. `List<Map<K,V>>` could be encoded as
+/// either `List<0>` or `List<Map<1,2>>` (and in this environment evaluates to
+/// `List<Map<num,dynamic>>`).
+///
+/// When `Map<num,dynamic>` is combined with a binding `<int,bool>` (e.g. inside
+/// the instance method `Map<K,V>.cast<RK,RV>()`), '0' refers to the base object
+/// of the binding, and then the numbering counts the bindings followed by the
+/// class parameters.
+///
+///     binding(interface("Map", [num,dynamic]), [int, bool])
+///             0                 3   4           1    2
+///
+/// Any environment can be reconstructed via a recipe. The above enviroment for
+/// method `cast` can be constructed as the ground term
+/// `Map<num,dynamic><int,bool>`, or (somewhat pointlessly) reconstructed via
+/// `0<1,2>` or `Map<3,4><1,2>`. The ability to construct an environment
+/// directly rather than via `bind` calls is used in folding sequences of `eval`
+/// and `bind` calls.
+///
+/// While a single type parameter is passed as the type, multiple type
+/// parameters are passed as a tuple. Tuples are encoded as a binding with an
+/// ignored base. `dynamic` can be used as the base, giving an encoding like
+/// `@<int,bool>`.
+///
+/// Bindings flatten, so `@<int><bool><num>` is the same as `@<int,bool,num>`.
+///
+/// The base of a binding does not have to have type parameters. Consider
+/// `CodeUnits`, which mixes in `ListMixin<int>`. The environment inside of
+/// `ListMixin.fold` (from the call `x.codeUnits.fold<bool>(...)`) would be
+///
+///     binding(interface("CodeUnits", []), [bool])
+///
+/// This can be encoded as `CodeUnits;<bool>` (note the `;` to force ToType to
+/// avoid creating an interface type Rti with a single class type
+/// argument). Metadata about the supertypes is used to resolve the recipe
+/// `ListMixin.E` to `int`.
+
+class _Parser {
+  _Parser._() {
+    throw UnimplementedError('_Parser is static methods only');
+  }
+
+  /// Creates a parser object for parsing a recipe against an environment in a
+  /// universe.
+  ///
+  /// Marked as no-inline so the object literal is not cloned by inlining.
+  @pragma('dart2js:noInline')
+  static Object create(Object universe, Object environment, String recipe) {
+    return JS(
+        '',
+        '{'
+            'u:#,' // universe
+            'e:#,' // environment
+            'r:#,' // recipe
+            's:[],' // stack
+            'p:0,' // position of sequence start.
+            '}',
+        universe,
+        environment,
+        recipe);
+  }
+
+  // Field accessors for the parser.
+  static Object universe(Object parser) => JS('', '#.u', parser);
+  static Rti environment(Object parser) => JS('Rti', '#.e', parser);
+  static String recipe(Object parser) => JS('String', '#.r', parser);
+  static Object stack(Object parser) => JS('', '#.s', parser);
+  static int position(Object parser) => JS('int', '#.p', parser);
+  static void setPosition(Object parser, int p) {
+    JS('', '#.p = #', parser, p);
+  }
+
+  static int charCodeAt(String s, int i) => JS('int', '#.charCodeAt(#)', s, i);
+  static void push(Object stack, Object value) {
+    JS('', '#.push(#)', stack, value);
+  }
+
+  static Object pop(Object stack) => JS('', '#.pop()', stack);
+
+  static Rti parse(Object parser) {
+    String source = _Parser.recipe(parser);
+    Object stack = _Parser.stack(parser);
+    int i = 0;
+    while (i < source.length) {
+      int ch = charCodeAt(source, i);
+      if (Recipe.isDigit(ch)) {
+        i = handleDigit(i + 1, ch, source, stack);
+      } else if (Recipe.isIdentifierStart(ch)) {
+        i = handleIdentifer(parser, i, source, stack, false);
+      } else if (ch == Recipe.period) {
+        i = handleIdentifer(parser, i, source, stack, true);
+      } else {
+        i++;
+        switch (ch) {
+          case Recipe.separator:
+            break;
+
+          case Recipe.nameSeparator:
+            break;
+
+          case Recipe.toType:
+            push(stack,
+                toType(universe(parser), environment(parser), pop(stack)));
+            break;
+
+          case Recipe.genericFunctionTypeParameterIndex:
+            push(stack,
+                toGenericFunctionParameter(universe(parser), pop(stack)));
+            break;
+
+          case Recipe.pushDynamic:
+            push(stack, _Universe._lookupDynamicRti(universe(parser)));
+            break;
+
+          case Recipe.pushVoid:
+            push(stack, _Universe._lookupVoidRti(universe(parser)));
+            break;
+
+          case Recipe.startTypeArguments:
+            pushStackFrame(parser, stack);
+            break;
+
+          case Recipe.endTypeArguments:
+            handleTypeArguments(parser, stack);
+            break;
+
+          case Recipe.extensionOp:
+            handleExtendedOperations(parser, stack);
+            break;
+
+          case Recipe.wrapStar:
+            Object u = universe(parser);
+            push(
+                stack,
+                _Universe._lookupStarRti(
+                    u, toType(u, environment(parser), pop(stack))));
+            break;
+
+          case Recipe.wrapQuestion:
+            Object u = universe(parser);
+            push(
+                stack,
+                _Universe._lookupQuestionRti(
+                    u, toType(u, environment(parser), pop(stack))));
+            break;
+
+          case Recipe.wrapFutureOr:
+            Object u = universe(parser);
+            push(
+                stack,
+                _Universe._lookupFutureOrRti(
+                    u, toType(u, environment(parser), pop(stack))));
+            break;
+
+          case Recipe.startFunctionArguments:
+            pushStackFrame(parser, stack);
+            break;
+
+          case Recipe.endFunctionArguments:
+            handleFunctionArguments(parser, stack);
+            break;
+
+          case Recipe.startOptionalGroup:
+            pushStackFrame(parser, stack);
+            break;
+
+          case Recipe.endOptionalGroup:
+            handleOptionalGroup(parser, stack);
+            break;
+
+          case Recipe.startNamedGroup:
+            pushStackFrame(parser, stack);
+            break;
+
+          case Recipe.endNamedGroup:
+            handleNamedGroup(parser, stack);
+            break;
+
+          default:
+            JS('', 'throw "Bad character " + #', ch);
+        }
+      }
+    }
+    Object item = pop(stack);
+    return toType(universe(parser), environment(parser), item);
+  }
+
+  static void pushStackFrame(Object parser, Object stack) {
+    push(stack, position(parser));
+    setPosition(parser, _Utils.arrayLength(stack));
+  }
+
+  static int handleDigit(int i, int digit, String source, Object stack) {
+    int value = Recipe.digitValue(digit);
+    for (; i < source.length; i++) {
+      int ch = charCodeAt(source, i);
+      if (!Recipe.isDigit(ch)) break;
+      value = value * 10 + Recipe.digitValue(ch);
+    }
+    push(stack, value);
+    return i;
+  }
+
+  static int handleIdentifer(
+      Object parser, int start, String source, Object stack, bool hasPeriod) {
+    int i = start + 1;
+    for (; i < source.length; i++) {
+      int ch = charCodeAt(source, i);
+      if (ch == Recipe.period) {
+        if (hasPeriod) break;
+        hasPeriod = true;
+      } else if (Recipe.isIdentifierStart(ch) || Recipe.isDigit(ch)) {
+        // Accept.
+      } else {
+        break;
+      }
+    }
+    String string = _Utils.substring(source, start, i);
+    if (hasPeriod) {
+      push(
+          stack,
+          _Universe.evalTypeVariable(
+              universe(parser), environment(parser), string));
+    } else {
+      push(stack, string);
+    }
+    return i;
+  }
+
+  static void handleTypeArguments(Object parser, Object stack) {
+    Object universe = _Parser.universe(parser);
+    Object arguments = collectArray(parser, stack);
+    Object head = pop(stack);
+    if (_Utils.isString(head)) {
+      String name = _Utils.asString(head);
+      push(stack, _Universe._lookupInterfaceRti(universe, name, arguments));
+    } else {
+      Rti base = toType(universe, environment(parser), head);
+      switch (Rti._getKind(base)) {
+        case Rti.kindFunction:
+          push(stack,
+              _Universe._lookupGenericFunctionRti(universe, base, arguments));
+          break;
+
+        default:
+          push(stack, _Universe._lookupBindingRti(universe, base, arguments));
+          break;
+      }
+    }
+  }
+
+  static const int optionalPositionalSentinel = -1;
+  static const int optionalNamedSentinel = -2;
+
+  static void handleFunctionArguments(Object parser, Object stack) {
+    Object universe = _Parser.universe(parser);
+    _FunctionParameters parameters = _FunctionParameters.allocate();
+    var optionalPositional = _Universe.sharedEmptyArray(universe);
+    var optionalNamed = _Universe.sharedEmptyArray(universe);
+
+    Object head = pop(stack);
+    if (_Utils.isNum(head)) {
+      int sentinel = _Utils.asInt(head);
+      switch (sentinel) {
+        case optionalPositionalSentinel:
+          optionalPositional = pop(stack);
+          break;
+
+        case optionalNamedSentinel:
+          optionalNamed = pop(stack);
+          break;
+
+        default:
+          push(stack, head);
+          break;
+      }
+    } else {
+      push(stack, head);
+    }
+
+    _FunctionParameters._setRequiredPositional(
+        parameters, collectArray(parser, stack));
+    _FunctionParameters._setOptionalPositional(parameters, optionalPositional);
+    _FunctionParameters._setOptionalNamed(parameters, optionalNamed);
+    Rti returnType = toType(universe, environment(parser), pop(stack));
+    push(stack, _Universe._lookupFunctionRti(universe, returnType, parameters));
+  }
+
+  static void handleOptionalGroup(Object parser, Object stack) {
+    Object parameters = collectArray(parser, stack);
+    push(stack, parameters);
+    push(stack, optionalPositionalSentinel);
+  }
+
+  static void handleNamedGroup(Object parser, Object stack) {
+    Object parameters = collectNamed(parser, stack);
+    push(stack, parameters);
+    push(stack, optionalNamedSentinel);
+  }
+
+  static void handleExtendedOperations(Object parser, Object stack) {
+    Object top = pop(stack);
+    if (0 == top) {
+      push(stack, _Universe._lookupNeverRti(universe(parser)));
+      return;
+    }
+    if (1 == top) {
+      push(stack, _Universe._lookupAnyRti(universe(parser)));
+      return;
+    }
+    throw AssertionError('Unexpected extended operation $top');
+  }
+
+  static Object collectArray(Object parser, Object stack) {
+    var array = _Utils.arraySplice(stack, position(parser));
+    toTypes(_Parser.universe(parser), environment(parser), array);
+    setPosition(parser, _Utils.asInt(pop(stack)));
+    return array;
+  }
+
+  static Object collectNamed(Object parser, Object stack) {
+    var array = _Utils.arraySplice(stack, position(parser));
+    toTypesNamed(_Parser.universe(parser), environment(parser), array);
+    setPosition(parser, _Utils.asInt(pop(stack)));
+    return array;
+  }
+
+  /// Coerce a stack item into an Rti object. Strings are converted to interface
+  /// types, integers are looked up in the type environment.
+  static Rti toType(Object universe, Rti environment, Object item) {
+    if (_Utils.isString(item)) {
+      String name = _Utils.asString(item);
+      // TODO(sra): Compile this out for minified code.
+      if ('dynamic' == name) {
+        return _Universe._lookupDynamicRti(universe);
+      }
+      return _Universe._lookupInterfaceRti(
+          universe, name, _Universe.sharedEmptyArray(universe));
+    } else if (_Utils.isNum(item)) {
+      return _Parser.indexToType(universe, environment, _Utils.asInt(item));
+    } else {
+      return _castToRti(item);
+    }
+  }
+
+  static void toTypes(Object universe, Rti environment, Object items) {
+    int length = _Utils.arrayLength(items);
+    for (int i = 0; i < length; i++) {
+      var item = _Utils.arrayAt(items, i);
+      Rti type = toType(universe, environment, item);
+      _Utils.arraySetAt(items, i, type);
+    }
+  }
+
+  static void toTypesNamed(Object universe, Rti environment, Object items) {
+    int length = _Utils.arrayLength(items);
+    assert(length.isEven);
+    for (int i = 1; i < length; i += 2) {
+      var item = _Utils.arrayAt(items, i);
+      Rti type = toType(universe, environment, item);
+      _Utils.arraySetAt(items, i, type);
+    }
+  }
+
+  static Rti indexToType(Object universe, Rti environment, int index) {
+    int kind = Rti._getKind(environment);
+    if (kind == Rti.kindBinding) {
+      if (index == 0) return Rti._getBindingBase(environment);
+      var typeArguments = Rti._getBindingArguments(environment);
+      int len = _Utils.arrayLength(typeArguments);
+      if (index <= len) {
+        return _castToRti(_Utils.arrayAt(typeArguments, index - 1));
+      }
+      // Is index into interface Rti in base.
+      index -= len;
+      environment = Rti._getBindingBase(environment);
+      kind = Rti._getKind(environment);
+    } else {
+      if (index == 0) return environment;
+    }
+    if (kind != Rti.kindInterface) {
+      throw AssertionError('Indexed base must be an interface type');
+    }
+    var typeArguments = Rti._getInterfaceTypeArguments(environment);
+    int len = _Utils.arrayLength(typeArguments);
+    if (index <= len) {
+      return _castToRti(_Utils.arrayAt(typeArguments, index - 1));
+    }
+    throw AssertionError('Bad index $index for $environment');
+  }
+
+  static Rti toGenericFunctionParameter(Object universe, Object item) {
+    assert(_Utils.isNum(item));
+    return _Universe._lookupGenericFunctionParameterRti(
+        universe, _Utils.asInt(item));
+  }
+}
+
+/// Represents the set of supertypes and type variable bindings for a given
+/// target type. The target type itself is not stored on the [TypeRule].
+class TypeRule {
+  TypeRule._() {
+    throw UnimplementedError("TypeRule is static methods only.");
+  }
+
+  static String lookupTypeVariable(rule, String typeVariable) =>
+      JS('', '#.#', rule, typeVariable);
+
+  static JSArray lookupSupertype(rule, String supertype) =>
+      JS('', '#.#', rule, supertype);
+}
+
+// -------- Subtype tests ------------------------------------------------------
+
+// Future entry point from compiled code.
+bool isSubtype(universe, Rti s, Rti t) {
+  return _isSubtype(universe, s, null, t, null);
+}
+
+bool _isSubtype(universe, Rti s, sEnv, Rti t, tEnv) {
+  // TODO(fishythefish): Update for NNBD. See
+  // https://github.com/dart-lang/language/blob/master/resources/type-system/subtyping.md#rules
+
+  // Subtyping is reflexive.
+  if (_Utils.isIdentical(s, t)) return true;
+
+  if (isTopType(t)) return true;
+
+  if (isJsInteropType(s)) return true;
+
+  if (isTopType(s)) {
+    if (isGenericFunctionTypeParameter(t)) return false;
+    if (isFutureOrType(t)) {
+      // [t] is FutureOr<T>. Check [s] <: T.
+      Rti tTypeArgument = Rti._getFutureOrArgument(t);
+      return _isSubtype(universe, s, sEnv, tTypeArgument, tEnv);
+    }
+    return false;
+  }
+
+  // Generic function type parameters must match exactly, which would have
+  // exited earlier.
+  if (isGenericFunctionTypeParameter(s)) return false;
+  if (isGenericFunctionTypeParameter(t)) return false;
+
+  if (isNullType(s)) return true;
+
+  if (isFutureOrType(t)) {
+    // [t] is FutureOr<T>.
+    Rti tTypeArgument = Rti._getFutureOrArgument(t);
+    if (isFutureOrType(s)) {
+      // [s] is FutureOr<S>. Check S <: T.
+      Rti sTypeArgument = Rti._getFutureOrArgument(s);
+      return _isSubtype(universe, sTypeArgument, sEnv, tTypeArgument, tEnv);
+    } else if (_isSubtype(universe, s, sEnv, tTypeArgument, tEnv)) {
+      // `true` because [s] <: T.
+      return true;
+    } else {
+      // Check [s] <: Future<T>.
+      String futureClass = JS_GET_NAME(JsGetName.FUTURE_CLASS_TYPE_NAME);
+      var argumentsArray = JS('', '[#]', tTypeArgument);
+      return _isSubtypeOfInterface(
+          universe, s, sEnv, futureClass, argumentsArray, tEnv);
+    }
+  }
+
+  if (isGenericFunctionKind(t)) {
+    return _isGenericFunctionSubtype(universe, s, sEnv, t, tEnv);
+  }
+
+  if (isFunctionKind(t)) {
+    return _isFunctionSubtype(universe, s, sEnv, t, tEnv);
+  }
+
+  if (isFunctionKind(s) || isGenericFunctionKind(s)) {
+    return isFunctionType(t);
+  }
+
+  assert(Rti._getKind(t) == Rti.kindInterface);
+  String tName = Rti._getInterfaceName(t);
+  var tArgs = Rti._getInterfaceTypeArguments(t);
+
+  return _isSubtypeOfInterface(universe, s, sEnv, tName, tArgs, tEnv);
+}
+
+bool _isGenericFunctionSubtype(universe, Rti s, sEnv, Rti t, tEnv) {
+  assert(isGenericFunctionKind(t));
+  if (!isGenericFunctionKind(s)) return false;
+
+  var sBounds = Rti._getGenericFunctionBounds(s);
+  var tBounds = Rti._getGenericFunctionBounds(t);
+  if (!typesEqual(sBounds, tBounds)) return false;
+  // TODO(fishythefish): Extend [sEnv] and [tEnv] with bindings for the [s]
+  // and [t] type parameters to enable checking the bound against
+  // non-type-parameter terms.
+
+  return _isFunctionSubtype(universe, Rti._getGenericFunctionBase(s), sEnv,
+      Rti._getGenericFunctionBase(t), tEnv);
+}
+
+// TODO(fishythefish): Support required named parameters.
+bool _isFunctionSubtype(universe, Rti s, sEnv, Rti t, tEnv) {
+  assert(isFunctionKind(t));
+  if (!isFunctionKind(s)) return false;
+
+  Rti sReturnType = Rti._getReturnType(s);
+  Rti tReturnType = Rti._getReturnType(t);
+  if (!_isSubtype(universe, sReturnType, sEnv, tReturnType, tEnv)) return false;
+
+  _FunctionParameters sParameters = Rti._getFunctionParameters(s);
+  _FunctionParameters tParameters = Rti._getFunctionParameters(t);
+
+  var sRequiredPositional =
+      _FunctionParameters._getRequiredPositional(sParameters);
+  var tRequiredPositional =
+      _FunctionParameters._getRequiredPositional(tParameters);
+  int sRequiredPositionalLength = _Utils.arrayLength(sRequiredPositional);
+  int tRequiredPositionalLength = _Utils.arrayLength(tRequiredPositional);
+  if (sRequiredPositionalLength > tRequiredPositionalLength) return false;
+  int requiredPositionalDelta =
+      tRequiredPositionalLength - sRequiredPositionalLength;
+
+  var sOptionalPositional =
+      _FunctionParameters._getOptionalPositional(sParameters);
+  var tOptionalPositional =
+      _FunctionParameters._getOptionalPositional(tParameters);
+  int sOptionalPositionalLength = _Utils.arrayLength(sOptionalPositional);
+  int tOptionalPositionalLength = _Utils.arrayLength(tOptionalPositional);
+  if (sRequiredPositionalLength + sOptionalPositionalLength <
+      tRequiredPositionalLength + tOptionalPositionalLength) return false;
+
+  for (int i = 0; i < sRequiredPositionalLength; i++) {
+    Rti sParameter = _castToRti(_Utils.arrayAt(sRequiredPositional, i));
+    Rti tParameter = _castToRti(_Utils.arrayAt(tRequiredPositional, i));
+    if (!_isSubtype(universe, tParameter, tEnv, sParameter, sEnv)) return false;
+  }
+
+  for (int i = 0; i < requiredPositionalDelta; i++) {
+    Rti sParameter = _castToRti(_Utils.arrayAt(sOptionalPositional, i));
+    Rti tParameter = _castToRti(
+        _Utils.arrayAt(tRequiredPositional, sRequiredPositionalLength + i));
+    if (!_isSubtype(universe, tParameter, tEnv, sParameter, sEnv)) return false;
+  }
+
+  for (int i = 0; i < tOptionalPositionalLength; i++) {
+    Rti sParameter = _castToRti(
+        _Utils.arrayAt(sOptionalPositional, requiredPositionalDelta + i));
+    Rti tParameter = _castToRti(_Utils.arrayAt(tOptionalPositional, i));
+    if (!_isSubtype(universe, tParameter, tEnv, sParameter, sEnv)) return false;
+  }
+
+  var sOptionalNamed = _FunctionParameters._getOptionalNamed(sParameters);
+  var tOptionalNamed = _FunctionParameters._getOptionalNamed(tParameters);
+  int sOptionalNamedLength = _Utils.arrayLength(sOptionalNamed);
+  int tOptionalNamedLength = _Utils.arrayLength(tOptionalNamed);
+
+  for (int i = 0, j = 0; j < tOptionalNamedLength; j += 2) {
+    String sName;
+    String tName = _Utils.asString(_Utils.arrayAt(tOptionalNamed, j));
+    do {
+      if (i >= sOptionalNamedLength) return false;
+      sName = _Utils.asString(_Utils.arrayAt(sOptionalNamed, i));
+      i += 2;
+    } while (_Utils.stringLessThan(sName, tName));
+    if (_Utils.stringLessThan(tName, sName)) return false;
+    Rti sType = _castToRti(_Utils.arrayAt(sOptionalNamed, i - 1));
+    Rti tType = _castToRti(_Utils.arrayAt(tOptionalNamed, j + 1));
+    if (!_isSubtype(universe, tType, tEnv, sType, sEnv)) return false;
+  }
+
+  return true;
+}
+
+bool _isSubtypeOfInterface(
+    universe, Rti s, sEnv, String tName, Object tArgs, tEnv) {
+  assert(Rti._getKind(s) == Rti.kindInterface);
+  String sName = Rti._getInterfaceName(s);
+
+  if (sName == tName) {
+    var sArgs = Rti._getInterfaceTypeArguments(s);
+    int length = _Utils.arrayLength(sArgs);
+    assert(length == _Utils.arrayLength(tArgs));
+    for (int i = 0; i < length; i++) {
+      Rti sArg = _castToRti(_Utils.arrayAt(sArgs, i));
+      Rti tArg = _castToRti(_Utils.arrayAt(tArgs, i));
+      if (!_isSubtype(universe, sArg, sEnv, tArg, tEnv)) return false;
+    }
+    return true;
+  }
+
+  Object rule = _Universe.findRule(universe, sName);
+  if (rule == null) return false;
+  var supertypeArgs = TypeRule.lookupSupertype(rule, tName);
+  if (supertypeArgs == null) return false;
+  int length = _Utils.arrayLength(supertypeArgs);
+  assert(length == _Utils.arrayLength(tArgs));
+  for (int i = 0; i < length; i++) {
+    String recipe = _Utils.asString(_Utils.arrayAt(supertypeArgs, i));
+    Rti supertypeArg = _Universe.evalInEnvironment(universe, s, recipe);
+    Rti tArg = _castToRti(_Utils.arrayAt(tArgs, i));
+    if (!_isSubtype(universe, supertypeArg, sEnv, tArg, tEnv)) return false;
+  }
+
+  return true;
+}
+
+/// Types are equal if they are structurally equal up to renaming of bound type
+/// variables and equating all top types.
+///
+/// We ignore renaming of bound type variables because we operate on de Bruijn
+/// indices, not names.
+bool typeEqual(Rti s, Rti t) {
+  if (_Utils.isIdentical(s, t)) return true;
+
+  if (isTopType(s)) return isTopType(t);
+
+  int sKind = Rti._getKind(s);
+  int tKind = Rti._getKind(t);
+  if (sKind != tKind) return false;
+
+  switch (sKind) {
+    case Rti.kindStar:
+    case Rti.kindQuestion:
+    case Rti.kindFutureOr:
+      return typeEqual(
+          _castToRti(Rti._getPrimary(s)), _castToRti(Rti._getPrimary(t)));
+
+    case Rti.kindInterface:
+      if (Rti._getInterfaceName(s) != Rti._getInterfaceName(t)) return false;
+      return typesEqual(
+          Rti._getInterfaceTypeArguments(s), Rti._getInterfaceTypeArguments(t));
+
+    case Rti.kindBinding:
+      return typeEqual(Rti._getBindingBase(s), Rti._getBindingBase(t)) &&
+          typesEqual(Rti._getBindingArguments(s), Rti._getBindingArguments(t));
+
+    case Rti.kindFunction:
+      return typeEqual(Rti._getReturnType(s), Rti._getReturnType(t)) &&
+          functionParametersEqual(
+              Rti._getFunctionParameters(s), Rti._getFunctionParameters(t));
+
+    case Rti.kindGenericFunction:
+      return typeEqual(
+              Rti._getGenericFunctionBase(s), Rti._getGenericFunctionBase(t)) &&
+          typesEqual(Rti._getGenericFunctionBounds(s),
+              Rti._getGenericFunctionBounds(t));
+
+    default:
+      return false;
+  }
+}
+
+bool typesEqual(Object sArray, Object tArray) {
+  int sLength = _Utils.arrayLength(sArray);
+  int tLength = _Utils.arrayLength(tArray);
+  if (sLength != tLength) return false;
+  for (int i = 0; i < sLength; i++) {
+    if (!typeEqual(_castToRti(_Utils.arrayAt(sArray, i)),
+        _castToRti(_Utils.arrayAt(tArray, i)))) return false;
+  }
+  return true;
+}
+
+bool namedTypesEqual(Object sArray, Object tArray) {
+  int sLength = _Utils.arrayLength(sArray);
+  int tLength = _Utils.arrayLength(tArray);
+  assert(sLength.isEven);
+  assert(tLength.isEven);
+  if (sLength != tLength) return false;
+  for (int i = 0; i < sLength; i += 2) {
+    if (_Utils.asString(_Utils.arrayAt(sArray, i)) !=
+        _Utils.asString(_Utils.arrayAt(tArray, i))) return false;
+    if (!typeEqual(_castToRti(_Utils.arrayAt(sArray, i + 1)),
+        _castToRti(_Utils.arrayAt(tArray, i + 1)))) return false;
+  }
+  return true;
+}
+
+// TODO(fishythefish): Support required named parameters.
+bool functionParametersEqual(
+        _FunctionParameters sParameters, _FunctionParameters tParameters) =>
+    typesEqual(_FunctionParameters._getRequiredPositional(sParameters),
+        _FunctionParameters._getRequiredPositional(tParameters)) &&
+    typesEqual(_FunctionParameters._getOptionalPositional(sParameters),
+        _FunctionParameters._getOptionalPositional(tParameters)) &&
+    namedTypesEqual(_FunctionParameters._getOptionalNamed(sParameters),
+        _FunctionParameters._getOptionalNamed(tParameters));
+
+bool isTopType(Rti t) =>
+    isDynamicType(t) || isVoidType(t) || isObjectType(t) || isJsInteropType(t);
+
+bool isDynamicType(Rti t) => Rti._getKind(t) == Rti.kindDynamic;
+bool isVoidType(Rti t) => Rti._getKind(t) == Rti.kindVoid;
+bool isJsInteropType(Rti t) => Rti._getKind(t) == Rti.kindAny;
+
+bool isFutureOrType(Rti t) => Rti._getKind(t) == Rti.kindFutureOr;
+
+bool isFunctionKind(Rti t) => Rti._getKind(t) == Rti.kindFunction;
+bool isGenericFunctionKind(Rti t) => Rti._getKind(t) == Rti.kindGenericFunction;
+
+bool isGenericFunctionTypeParameter(Rti t) =>
+    Rti._getKind(t) == Rti.kindGenericFunctionParameter;
+
+bool isObjectType(Rti t) =>
+    Rti._getKind(t) == Rti.kindInterface &&
+    Rti._getInterfaceName(t) == JS_GET_NAME(JsGetName.OBJECT_CLASS_TYPE_NAME);
+
+// TODO(fishythefish): Which representation should we use for NNBD?
+// Do we also need to check for `Never?`, etc.?
+bool isNullType(Rti t) =>
+    Rti._getKind(t) == Rti.kindInterface &&
+    Rti._getInterfaceName(t) == JS_GET_NAME(JsGetName.NULL_CLASS_TYPE_NAME);
+
+bool isFunctionType(Rti t) =>
+    Rti._getKind(t) == Rti.kindInterface &&
+    Rti._getInterfaceName(t) == JS_GET_NAME(JsGetName.FUNCTION_CLASS_TYPE_NAME);
+
+/// Unchecked cast to Rti.
+Rti _castToRti(s) => JS('Rti', '#', s);
+
+///
+class _Utils {
+  static bool asBool(Object o) => JS('bool', '#', o);
+  static double asDouble(Object o) => JS('double', '#', o);
+  static int asInt(Object o) => JS('int', '#', o);
+  static num asNum(Object o) => JS('num', '#', o);
+  static String asString(Object o) => JS('String', '#', o);
+
+  static bool isString(Object o) => JS('bool', 'typeof # == "string"', o);
+  static bool isNum(Object o) => JS('bool', 'typeof # == "number"', o);
+
+  static bool instanceOf(Object o, Object constructor) =>
+      JS('bool', '# instanceof #', o, constructor);
+
+  static bool isIdentical(s, t) => JS('bool', '# === #', s, t);
+
+  static bool isArray(Object o) => JS('bool', 'Array.isArray(#)', o);
+
+  static int arrayLength(Object array) => JS('int', '#.length', array);
+
+  static Object arrayAt(Object array, int i) => JS('', '#[#]', array, i);
+
+  static void arraySetAt(Object array, int i, Object value) {
+    JS('', '#[#] = #', array, i, value);
+  }
+
+  static JSArray arrayShallowCopy(Object array) =>
+      JS('JSArray', '#.slice()', array);
+
+  static JSArray arraySplice(Object array, int position) =>
+      JS('JSArray', '#.splice(#)', array, position);
+
+  static JSArray arrayConcat(Object a1, Object a2) =>
+      JS('JSArray', '#.concat(#)', a1, a2);
+
+  static void arrayPush(Object array, Object value) {
+    JS('', '#.push(#)', array, value);
+  }
+
+  static String substring(String s, int start, int end) =>
+      JS('String', '#.substring(#, #)', s, start, end);
+
+  static bool stringLessThan(String s1, String s2) =>
+      JS('bool', '# < #', s1, s2);
+
+  static mapGet(cache, key) => JS('', '#.get(#)', cache, key);
+
+  static void mapSet(cache, key, value) {
+    JS('', '#.set(#, #)', cache, key, value);
+  }
+}
+// -------- Entry points for testing -------------------------------------------
+
+String testingCanonicalRecipe(rti) {
+  return Rti._getCanonicalRecipe(rti);
+}
+
+String testingRtiToString(rti) {
+  return _rtiToString(_castToRti(rti), null);
+}
+
+String testingRtiToDebugString(rti) {
+  return _rtiToDebugString(_castToRti(rti));
+}
+
+Object testingCreateUniverse() {
+  return _Universe.create();
+}
+
+void testingAddRules(universe, rules) {
+  _Universe.addRules(universe, rules);
+}
+
+bool testingIsSubtype(universe, rti1, rti2) {
+  return isSubtype(universe, _castToRti(rti1), _castToRti(rti2));
+}
+
+Object testingUniverseEval(universe, String recipe) {
+  return _Universe.eval(universe, recipe);
+}
+
+Object testingEnvironmentEval(universe, environment, String recipe) {
+  return _Universe.evalInEnvironment(universe, _castToRti(environment), recipe);
+}
+
+Object testingEnvironmentBind(universe, environment, arguments) {
+  return _Universe.bind(
+      universe, _castToRti(environment), _castToRti(arguments));
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart
new file mode 100644
index 0000000..f87406b
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Contains error codes that transformed async/async* functions use to
+/// communicate with js_helper functions.
+
+const int SUCCESS = 0;
+const int ERROR = 1;
+const int STREAM_WAS_CANCELED = 2;
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/embedded_names.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/embedded_names.dart
new file mode 100644
index 0000000..50cf7e8
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/embedded_names.dart
@@ -0,0 +1,452 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Contains the names of globals that are embedded into the output by the
+/// compiler.
+///
+/// Variables embedded this way should be access with `JS_EMBEDDED_GLOBAL` from
+/// the `_foreign_helper` library.
+///
+/// This library is shared between the compiler and the runtime system.
+library dart2js._embedded_names;
+
+/// The name of the property that is used to mark a type as typedef.
+///
+/// Without reflection typedefs are removed (expanded to their function type)
+/// but with reflection an object is needed to have the typedef's name. The
+/// object is marked with this property.
+///
+/// This property name only lives on internal type-objects and is only used
+/// when reflection is enabled.
+const TYPEDEF_PREDICATE_PROPERTY_NAME = r"$$isTypedef";
+
+/// The name of the property that is used to find the function type of a
+/// typedef.
+///
+/// Without reflection typedefs are removed (expanded to their function type)
+/// but with reflection an object is needed to have the typedef's name.
+///
+/// The typedef's object contains a pointer to its function type (as an index
+/// into the embedded global [TYPES]) in this property.
+///
+/// This property name only lives on internal type-objects and is only used
+/// when reflection is enabled.
+const TYPEDEF_TYPE_PROPERTY_NAME = r"$typedefType";
+
+/// The name of the property that is used to find the native superclass of
+/// an extended class.
+///
+/// Every class that extends a native class has this property set on its
+/// native class.
+const NATIVE_SUPERCLASS_TAG_NAME = r"$nativeSuperclassTag";
+
+/// The name of the static-function property name.
+///
+/// This property is set for all tear-offs of static functions, and provides
+/// the static function's unique (potentially minified) name.
+const STATIC_FUNCTION_NAME_PROPERTY_NAME = r'$static_name';
+
+/// The name of the embedded global for metadata.
+///
+/// Use [JsBuiltin.getMetadata] instead of directly accessing this embedded
+/// global.
+const METADATA = 'metadata';
+
+/// A list of types used in the program e.g. for reflection or encoding of
+/// function types.
+///
+/// Use [JsBuiltin.getType] instead of directly accessing this embedded global.
+const TYPES = 'types';
+
+/// Returns a function that maps a name of a class to its type.
+///
+/// This embedded global is used by the runtime when computing the internal
+/// runtime-type-information (rti) object.
+const GET_TYPE_FROM_NAME = 'getTypeFromName';
+
+/// A JS map from mangled global names to their unmangled names.
+///
+/// If the program does not use reflection, this embedded global may be empty
+/// (but not null or undefined).
+const MANGLED_GLOBAL_NAMES = 'mangledGlobalNames';
+
+/// A JS map from mangled instance names to their unmangled names.
+///
+/// This embedded global is mainly used for reflection, but is also used to
+/// map const-symbols (`const Symbol('x')`) to the mangled instance names.
+///
+/// This embedded global may be empty (but not null or undefined).
+const MANGLED_NAMES = 'mangledNames';
+
+/// A JS map from dispatch tags (usually constructor names of DOM classes) to
+/// interceptor class. This map is used to find the correct interceptor for
+/// native classes.
+///
+/// This embedded global is used for natives.
+const INTERCEPTORS_BY_TAG = 'interceptorsByTag';
+
+/// A JS map from dispatch tags (usually constructor names of DOM classes) to
+/// booleans. Every tag entry of [INTERCEPTORS_BY_TAG] has a corresponding
+/// entry in the leaf-tags map.
+///
+/// A tag-entry is true, when a class can be treated as leaf class in the
+/// hierarchy. That is, even though it might have subclasses, all subclasses
+/// have the same code for the used methods.
+///
+/// This embedded global is used for natives.
+const LEAF_TAGS = 'leafTags';
+
+/// A JS function that returns the isolate tag for a given name.
+///
+/// This function uses the [ISOLATE_TAG] (below) to construct a name that is
+/// unique per isolate.
+///
+/// This embedded global is used for natives.
+// TODO(floitsch): should we rename this variable to avoid confusion with
+//    [INTERCEPTORS_BY_TAG] and [LEAF_TAGS].
+const GET_ISOLATE_TAG = 'getIsolateTag';
+
+/// A string that is different for each running isolate.
+///
+/// When this embedded global is initialized a global variable is used to
+/// ensure that no other running isolate uses the same isolate-tag string.
+///
+/// This embedded global is used for natives.
+// TODO(floitsch): should we rename this variable to avoid confusion with
+//    [INTERCEPTORS_BY_TAG] and [LEAF_TAGS].
+const ISOLATE_TAG = 'isolateTag';
+
+/// This embedded global (a function) returns the isolate-specific dispatch-tag
+/// that is used to accelerate interceptor calls.
+const DISPATCH_PROPERTY_NAME = "dispatchPropertyName";
+
+/// An embedded global that maps a [Type] to the [Interceptor] and constructors
+/// for that type.
+///
+/// More documentation can be found in the interceptors library (close to its
+/// use).
+const TYPE_TO_INTERCEPTOR_MAP = "typeToInterceptorMap";
+
+/// The current script's URI when the program was loaded.
+///
+/// This embedded global is set at startup, just before invoking `main`.
+const CURRENT_SCRIPT = 'currentScript';
+
+/// Contains a map from load-ids to lists of part indexes.
+///
+/// To load the deferred library that is represented by the load-id, the runtime
+/// must load all associated URIs (named in DEFERRED_PART_URIS) and initialize
+/// all the loaded hunks (DEFERRED_PART_HASHES).
+///
+/// This embedded global is only used for deferred loading.
+const DEFERRED_LIBRARY_PARTS = 'deferredLibraryParts';
+
+/// Contains a list of URIs (Strings), indexed by part.
+///
+/// The lists in the DEFERRED_LIBRARY_PARTS map contain indexes into this list.
+///
+/// This embedded global is only used for deferred loading.
+const DEFERRED_PART_URIS = 'deferredPartUris';
+
+/// Contains a list of hashes, indexed by part.
+///
+/// The lists in the DEFERRED_LIBRARY_PARTS map contain indexes into this list.
+///
+/// The hashes are associated with the URIs of the load-ids (see
+/// [DEFERRED_PART_URIS]). They are SHA1 (or similar) hashes of the code that
+/// must be loaded. By using cryptographic hashes we can (1) handle loading in
+/// the same web page the parts from multiple Dart applications (2) avoid
+/// loading similar code multiple times.
+///
+/// This embedded global is only used for deferred loading.
+const DEFERRED_PART_HASHES = 'deferredPartHashes';
+
+/// Initialize a loaded hunk.
+///
+/// Once a hunk (the code from a deferred URI) has been loaded it must be
+/// initialized. Calling this function with the corresponding hash (see
+/// [DEFERRED_LIBRARY_HASHES]) initializes the code.
+///
+/// This embedded global is only used for deferred loading.
+const INITIALIZE_LOADED_HUNK = 'initializeLoadedHunk';
+
+/// Returns, whether a hunk (identified by its hash) has already been loaded.
+///
+/// This embedded global is only used for deferred loading.
+const IS_HUNK_LOADED = 'isHunkLoaded';
+
+/// Returns, whether a hunk (identified by its hash) has already been
+/// initialized.
+///
+/// This embedded global is only used for deferred loading.
+const IS_HUNK_INITIALIZED = 'isHunkInitialized';
+
+/// A set (implemented as map to booleans) of hunks (identified by hashes) that
+/// have already been initialized.
+///
+/// This embedded global is only used for deferred loading.
+///
+/// This global is an emitter-internal embedded global, and not used by the
+/// runtime. The constant remains in this file to make sure that other embedded
+/// globals don't clash with it.
+const DEFERRED_INITIALIZED = 'deferredInitialized';
+
+/// A 'Universe' object used by 'dart:_rti'.
+///
+/// This embedded global is used for --experiment-new-rti.
+const RTI_UNIVERSE = 'typeUniverse';
+
+/// Returns a function that creates all precompiled functions (in particular
+/// constructors).
+///
+/// That is, the function returns the array that the full emitter would
+/// otherwise build dynamically when it finishes all classes.
+///
+/// This constant is only used in CSP mode.
+///
+/// This global is an emitter-internal embedded global, and not used by the
+/// runtime. The constant remains in this file to make sure that other embedded
+/// globals don't clash with it.
+const PRECOMPILED = 'precompiled';
+
+/// An emitter-internal embedded global. This global is not used by the runtime.
+const FINISHED_CLASSES = 'finishedClasses';
+
+/// A JavaScript object literal that maps the (minified) JavaScript constructor
+/// name (as given by [JsBuiltin.rawRtiToJsConstructorName] to the
+/// JavaScript constructor.
+///
+/// This embedded global is only used by reflection.
+const ALL_CLASSES = 'allClasses';
+
+/// A map from element to type information.
+///
+/// This embedded global is only used by reflection.
+const TYPE_INFORMATION = 'typeInformation';
+
+/// A map from statics to their descriptors.
+///
+/// This embedded global is only used by reflection.
+const STATICS = 'statics';
+
+/// An array of library descriptors.
+///
+/// The descriptor contains information such as name, uri, classes, ...
+///
+/// This embedded global is only used by reflection.
+const LIBRARIES = 'libraries';
+
+/// A map from lazy statics to their initializers.
+///
+/// This embedded global is only used by reflection.
+const LAZIES = 'lazies';
+
+/// Names that are supported by [JS_GET_NAME].
+// TODO(herhut): Make entries lower case (as in fields) and find a better name.
+enum JsGetName {
+  GETTER_PREFIX,
+  SETTER_PREFIX,
+  CALL_PREFIX,
+  CALL_PREFIX0,
+  CALL_PREFIX1,
+  CALL_PREFIX2,
+  CALL_PREFIX3,
+  CALL_PREFIX4,
+  CALL_PREFIX5,
+  CALL_CATCH_ALL,
+  REFLECTABLE,
+  CLASS_DESCRIPTOR_PROPERTY,
+  REQUIRED_PARAMETER_PROPERTY,
+  DEFAULT_VALUES_PROPERTY,
+  CALL_NAME_PROPERTY,
+  DEFERRED_ACTION_PROPERTY,
+
+  /// Prefix used for generated type argument substitutions on classes.
+  OPERATOR_AS_PREFIX,
+
+  /// Name used for generated function types on classes and methods.
+  SIGNATURE_NAME,
+
+  /// Name of JavaScript property used to store runtime-type information on
+  /// instances of parameterized classes.
+  RTI_NAME,
+
+  /// Name used to tag typedefs.
+  TYPEDEF_TAG,
+
+  /// Name used to tag a function type.
+  FUNCTION_TYPE_TAG,
+
+  /// Name used to tag bounds of a generic function type. If bounds are present,
+  /// the property value is an Array of bounds (the length gives the number of
+  /// type parameters). If absent, the type is not a generic function type.
+  FUNCTION_TYPE_GENERIC_BOUNDS_TAG,
+
+  /// Name used to tag void return in function type representations in
+  /// JavaScript.
+  FUNCTION_TYPE_VOID_RETURN_TAG,
+
+  /// Name used to tag return types in function type representations in
+  /// JavaScript.
+  FUNCTION_TYPE_RETURN_TYPE_TAG,
+
+  /// Name used to tag required parameters in function type representations
+  /// in JavaScript.
+  FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG,
+
+  /// Name used to tag optional parameters in function type representations
+  /// in JavaScript.
+  FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG,
+
+  /// Name used to tag named parameters in function type representations in
+  /// JavaScript.
+  FUNCTION_TYPE_NAMED_PARAMETERS_TAG,
+
+  /// Name used to tag a FutureOr type.
+  FUTURE_OR_TAG,
+
+  /// Name used to tag type arguments types in FutureOr type representations in
+  /// JavaScript.
+  FUTURE_OR_TYPE_ARGUMENT_TAG,
+
+  /// String representation of the type of the Future class.
+  FUTURE_CLASS_TYPE_NAME,
+
+  /// Field name used for determining if an object or its interceptor has
+  /// JavaScript indexing behavior.
+  IS_INDEXABLE_FIELD_NAME,
+
+  /// String representation of the type of the null class.
+  NULL_CLASS_TYPE_NAME,
+
+  /// String representation of the type of the object class.
+  OBJECT_CLASS_TYPE_NAME,
+
+  /// String representation of the type of the function class.
+  FUNCTION_CLASS_TYPE_NAME,
+
+  /// String recipe for the [bool] type.
+  BOOL_RECIPE,
+
+  /// String recipe for the [double] type.
+  DOUBLE_RECIPE,
+
+  /// String recipe for the [int] type.
+  INT_RECIPE,
+
+  /// String recipe for the [num] type.
+  NUM_RECIPE,
+
+  /// String recipe for the [String] type.
+  STRING_RECIPE,
+
+  /// Property name for Rti._is field.
+  RTI_FIELD_IS,
+}
+
+enum JsBuiltin {
+  /// Returns the JavaScript constructor function for Dart's Object class.
+  /// This can be used for type tests, as in
+  ///
+  ///     var constructor = JS_BUILTIN('', JsBuiltin.dartObjectConstructor);
+  ///     if (JS('bool', '# instanceof #', obj, constructor))
+  ///       ...
+  dartObjectConstructor,
+
+  /// Returns the JavaScript constructor function for the runtime's Closure
+  /// class, the base class of all closure objects.  This can be used for type
+  /// tests, as in
+  ///
+  ///     var constructor = JS_BUILTIN('', JsBuiltin.dartClosureConstructor);
+  ///     if (JS('bool', '# instanceof #', obj, constructor))
+  ///       ...
+  dartClosureConstructor,
+
+  /// Returns the JavaScript-constructor name given an [isCheckProperty].
+  ///
+  /// This relies on a deterministic encoding of is-check properties (for
+  /// example `$isFoo` for a class `Foo`). In minified code the returned
+  /// classname is the minified name of the class.
+  ///
+  ///     JS_BUILTIN('returns:String;depends:none;effects:none',
+  ///                JsBuiltin.isCheckPropertyToJsConstructorName,
+  ///                isCheckProperty);
+  isCheckPropertyToJsConstructorName,
+
+  /// Returns true if the given type is a function type. Returns false for
+  /// the one `Function` type singleton. (See [isFunctionTypeSingleton]).
+  ///
+  ///     JS_BUILTIN('bool', JsBuiltin.isFunctionType, o)
+  isFunctionType,
+
+  /// Returns true if the given type is a FutureOr type.
+  ///
+  ///     JS_BUILTIN('bool', JsBuiltin.isFutureOrType, o)
+  isFutureOrType,
+
+  /// Returns true if the given type is the `void` type.
+  ///
+  ///     JS_BUILTIN('bool', JsBuiltin.isVoidType, o)
+  isVoidType,
+
+  /// Returns true if the given type is the `dynamic` type.
+  ///
+  ///     JS_BUILTIN('bool', JsBuiltin.isDynamicType, o)
+  isDynamicType,
+
+  /// Returns true if the given type is a type argument of a js-interop class
+  /// or a supertype of a js-interop class.
+  ///
+  ///     JS_BUILTIN('bool', JsBuiltin.isJsInteropTypeArgument, o)
+  isJsInteropTypeArgument,
+
+  /// Returns the JavaScript-constructor name given an rti encoding.
+  ///
+  ///     JS_BUILTIN('String', JsBuiltin.rawRtiToJsConstructorName, rti)
+  rawRtiToJsConstructorName,
+
+  /// Returns the raw runtime type of the given object. The given argument
+  /// [o] should be the interceptor (for non-Dart objects).
+  ///
+  ///     JS_BUILTIN('', JsBuiltin.rawRuntimeType, o)
+  rawRuntimeType,
+
+  /// Returns whether the given type is a subtype of other.
+  ///
+  /// The argument `other` is the name of the potential supertype. It is
+  /// computed by `runtimeTypeToString`;
+  ///
+  /// *The `other` name must be passed in before the `type`.*
+  ///
+  ///     JS_BUILTIN('returns:bool;effects:none;depends:none',
+  ///                JsBuiltin.isSubtype, other, type);
+  isSubtype,
+
+  /// Returns true if the given type equals the type given as second
+  /// argument. Use the JS_GET_NAME helpers to get the type representation
+  /// for various Dart classes.
+  ///
+  ///     JS_BUILTIN('returns:bool;effects:none;depends:none',
+  ///                JsBuiltin.isFunctionTypeLiteral, type, name);
+  isGivenTypeRti,
+
+  /// Returns the metadata of the given [index].
+  ///
+  ///     JS_BUILTIN('returns:var;effects:none;depends:none',
+  ///                JsBuiltin.getMetadata, index);
+  getMetadata,
+
+  /// Returns the type of the given [index].
+  ///
+  ///     JS_BUILTIN('returns:var;effects:none;depends:none',
+  ///                JsBuiltin.getType, index);
+  getType,
+}
+
+/// Names of fields of the Rti Universe object.
+class RtiUniverseFieldNames {
+  static String evalCache = 'eC';
+  static String typeRules = 'tR';
+  static String sharedEmptyArray = 'sEA';
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
new file mode 100644
index 0000000..7666379
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
@@ -0,0 +1,230 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Constants and predicates used for encoding and decoding type recipes.
+///
+/// This library is shared between the compiler and the runtime system.
+library dart2js._recipe_syntax;
+
+abstract class Recipe {
+  Recipe._();
+
+  // Operators.
+
+  static const int separator = _comma;
+  static const String separatorString = _commaString;
+
+  static const int toType = _semicolon;
+  static const String toTypeString = _semicolonString;
+
+  static const int pushDynamic = _at;
+  static const String pushDynamicString = _atString;
+  static const int pushVoid = _tilde;
+  static const String pushVoidString = _tildeString;
+
+  static const int wrapStar = _asterisk;
+  static const String wrapStarString = _asteriskString;
+  static const int wrapQuestion = _question;
+  static const String wrapQuestionString = _questionString;
+  static const int wrapFutureOr = _slash;
+  static const String wrapFutureOrString = _slashString;
+
+  static const int startTypeArguments = _lessThan;
+  static const String startTypeArgumentsString = _lessThanString;
+  static const int endTypeArguments = _greaterThan;
+  static const String endTypeArgumentsString = _greaterThanString;
+
+  static const int startFunctionArguments = _leftParen;
+  static const String startFunctionArgumentsString = _leftParenString;
+  static const int endFunctionArguments = _rightParen;
+  static const String endFunctionArgumentsString = _rightParenString;
+  static const int startOptionalGroup = _leftBracket;
+  static const String startOptionalGroupString = _leftBracketString;
+  static const int endOptionalGroup = _rightBracket;
+  static const String endOptionalGroupString = _rightBracketString;
+  static const int startNamedGroup = _leftBrace;
+  static const String startNamedGroupString = _leftBraceString;
+  static const int endNamedGroup = _rightBrace;
+  static const String endNamedGroupString = _rightBraceString;
+  static const int nameSeparator = _colon;
+  static const String nameSeparatorString = _colonString;
+
+  static const int genericFunctionTypeParameterIndex = _circumflex;
+  static const String genericFunctionTypeParameterIndexString =
+      _circumflexString;
+
+  static const int extensionOp = _ampersand;
+  static const String extensionOpString = _ampersandString;
+  static const int pushNeverExtension = 0;
+  static const String pushNeverExtensionString = '$pushNeverExtension';
+  static const int pushAnyExtension = 1;
+  static const String pushAnyExtensionString = '$pushAnyExtension';
+
+  // Number and name components.
+
+  static bool isDigit(int code) => code >= _digit0 && code <= _digit9;
+  static int digitValue(int code) => code - _digit0;
+
+  static bool isIdentifierStart(int ch) =>
+      (((ch | 32) - _lowercaseA) & 0xffff) < 26 ||
+      (ch == _underscore) ||
+      (ch == _dollar);
+
+  static const int period = _period;
+
+  // Private names.
+
+  static const int _formfeed = 0x0C;
+  static const String _formfeedString = '\f';
+
+  static const int _space = 0x20;
+  static const String _spaceString = ' ';
+  static const int _exclamation = 0x21;
+  static const String _exclamationString = '!';
+  static const int _hash = 0x23;
+  static const String _hashString = '#';
+  static const int _dollar = 0x24;
+  static const String _dollarString = r'$';
+  static const int _percent = 0x25;
+  static const String _percentString = '%';
+  static const int _ampersand = 0x26;
+  static const String _ampersandString = '&';
+  static const int _apostrophe = 0x27;
+  static const String _apostropheString = "'";
+  static const int _leftParen = 0x28;
+  static const String _leftParenString = '(';
+  static const int _rightParen = 0x29;
+  static const String _rightParenString = ')';
+  static const int _asterisk = 0x2A;
+  static const String _asteriskString = '*';
+  static const int _plus = 0x2B;
+  static const String _plusString = '+';
+  static const int _comma = 0x2C;
+  static const String _commaString = ',';
+  static const int _minus = 0x2D;
+  static const String _minusString = '-';
+  static const int _period = 0x2E;
+  static const String _periodString = '.';
+  static const int _slash = 0x2F;
+  static const String _slashString = '/';
+
+  static const int _digit0 = 0x30;
+  static const int _digit9 = 0x39;
+
+  static const int _colon = 0x3A;
+  static const String _colonString = ':';
+  static const int _semicolon = 0x3B;
+  static const String _semicolonString = ';';
+  static const int _lessThan = 0x3C;
+  static const String _lessThanString = '<';
+  static const int _equals = 0x3D;
+  static const String _equalsString = '=';
+  static const int _greaterThan = 0x3E;
+  static const String _greaterThanString = '>';
+  static const int _question = 0x3F;
+  static const String _questionString = '?';
+  static const int _at = 0x40;
+  static const String _atString = '@';
+
+  static const int _uppercaseA = 0x41;
+  static const int _uppercaseZ = 0x5A;
+
+  static const int _leftBracket = 0x5B;
+  static const String _leftBracketString = '[';
+  static const int _backslash = 0x5C;
+  static const String _backslashString = r'\';
+  static const int _rightBracket = 0x5D;
+  static const String _rightBracketString = ']';
+  static const int _circumflex = 0x5E;
+  static const String _circumflexString = '^';
+  static const int _underscore = 0x5F;
+  static const String _underscoreString = '_';
+  static const int _backtick = 0x60;
+  static const String _backtickString = '`';
+
+  static const int _lowercaseA = 0x61;
+  static const int _lowercaseZ = 0x7A;
+
+  static const int _leftBrace = 0x7B;
+  static const String _leftBraceString = '{';
+  static const int _vertical = 0x7C;
+  static const String _verticalString = '|';
+  static const int _rightBrace = 0x7D;
+  static const String _rightBraceString = '}';
+  static const int _tilde = 0x7E;
+  static const String _tildeString = '~';
+
+  static void testEquivalence() {
+    void test(String label, int charCode, String str) {
+      if (String.fromCharCode(charCode) != str) {
+        throw StateError("$label: String.fromCharCode($charCode) != $str");
+      }
+    }
+
+    void testExtension(String label, int op, String str) {
+      if ('$op' != str) {
+        throw StateError("$label: $op.toString() != $str");
+      }
+    }
+
+    test("separator", separator, separatorString);
+    test("toType", toType, toTypeString);
+    test("pushDynamic", pushDynamic, pushDynamicString);
+    test("pushVoid", pushVoid, pushVoidString);
+    test("wrapStar", wrapStar, wrapStarString);
+    test("wrapQuestion", wrapQuestion, wrapQuestionString);
+    test("wrapFutureOr", wrapFutureOr, wrapFutureOrString);
+    test("startTypeArguments", startTypeArguments, startTypeArgumentsString);
+    test("endTypeArguments", endTypeArguments, endTypeArgumentsString);
+    test("startFunctionArguments", startFunctionArguments,
+        startFunctionArgumentsString);
+    test("endFunctionArguments", endFunctionArguments,
+        endFunctionArgumentsString);
+    test("startOptionalGroup", startOptionalGroup, startOptionalGroupString);
+    test("endOptionalGroup", endOptionalGroup, endOptionalGroupString);
+    test("startNamedGroup", startNamedGroup, startNamedGroupString);
+    test("endNamedGroup", endNamedGroup, endNamedGroupString);
+    test("nameSeparator", nameSeparator, nameSeparatorString);
+    test("genericFunctionTypeParameterIndex", genericFunctionTypeParameterIndex,
+        genericFunctionTypeParameterIndexString);
+    test("extensionOp", extensionOp, extensionOpString);
+    testExtension(
+        "pushNeverExtension", pushNeverExtension, pushNeverExtensionString);
+    testExtension("pushAnyExtension", pushAnyExtension, pushAnyExtensionString);
+
+    test("_formfeed", _formfeed, _formfeedString);
+    test("_space", _space, _spaceString);
+    test("_exclamation", _exclamation, _exclamationString);
+    test("_hash", _hash, _hashString);
+    test("_dollar", _dollar, _dollarString);
+    test("_percent", _percent, _percentString);
+    test("_ampersand", _ampersand, _ampersandString);
+    test("_apostrophe", _apostrophe, _apostropheString);
+    test("_leftParen", _leftParen, _leftParenString);
+    test("_rightParen", _rightParen, _rightParenString);
+    test("_asterisk", _asterisk, _asteriskString);
+    test("_plus", _plus, _plusString);
+    test("_comma", _comma, _commaString);
+    test("_minus", _minus, _minusString);
+    test("_period", _period, _periodString);
+    test("_slash", _slash, _slashString);
+    test("_colon", _colon, _colonString);
+    test("_semicolon", _semicolon, _semicolonString);
+    test("_lessThan", _lessThan, _lessThanString);
+    test("_equals", _equals, _equalsString);
+    test("_greaterThan", _greaterThan, _greaterThanString);
+    test("_question", _question, _questionString);
+    test("_at", _at, _atString);
+    test("_leftBracket", _leftBracket, _leftBracketString);
+    test("_backslash", _backslash, _backslashString);
+    test("_rightBracket", _rightBracket, _rightBracketString);
+    test("_circumflex", _circumflex, _circumflexString);
+    test("_underscore", _underscore, _underscoreString);
+    test("_backtick", _backtick, _backtickString);
+    test("_leftBrace", _leftBrace, _leftBraceString);
+    test("_vertical", _vertical, _verticalString);
+    test("_rightBrace", _rightBrace, _rightBraceString);
+    test("_tilde", _tilde, _tildeString);
+  }
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/string_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/string_helper.dart
new file mode 100644
index 0000000..ea5374e
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/string_helper.dart
@@ -0,0 +1,331 @@
+// Copyright (c) 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 _js_helper;
+
+stringIndexOfStringUnchecked(receiver, other, startIndex) {
+  return JS('int', '#.indexOf(#, #)', receiver, other, startIndex);
+}
+
+substring1Unchecked(receiver, startIndex) {
+  return JS('String', '#.substring(#)', receiver, startIndex);
+}
+
+substring2Unchecked(receiver, startIndex, endIndex) {
+  return JS('String', '#.substring(#, #)', receiver, startIndex, endIndex);
+}
+
+stringContainsStringUnchecked(receiver, other, startIndex) {
+  return stringIndexOfStringUnchecked(receiver, other, startIndex) >= 0;
+}
+
+List<String> stringSplitUnchecked(String receiver, pattern) {
+  return new JSArray<String>.markGrowable(JS(
+      'returns:JSExtendableArray;new:true', '#.split(#)', receiver, pattern));
+}
+
+class StringMatch implements Match {
+  const StringMatch(int this.start, String this.input, String this.pattern);
+
+  int get end => start + pattern.length;
+  String operator [](int g) => group(g);
+  int get groupCount => 0;
+
+  String group(int group_) {
+    if (group_ != 0) {
+      throw new RangeError.value(group_);
+    }
+    return pattern;
+  }
+
+  List<String> groups(List<int> groups_) {
+    List<String> result = new List<String>();
+    for (int g in groups_) {
+      result.add(group(g));
+    }
+    return result;
+  }
+
+  final int start;
+  final String input;
+  final String pattern;
+}
+
+Iterable<Match> allMatchesInStringUnchecked(
+    String pattern, String string, int startIndex) {
+  return new _StringAllMatchesIterable(string, pattern, startIndex);
+}
+
+class _StringAllMatchesIterable extends Iterable<Match> {
+  final String _input;
+  final String _pattern;
+  final int _index;
+
+  _StringAllMatchesIterable(this._input, this._pattern, this._index);
+
+  Iterator<Match> get iterator =>
+      new _StringAllMatchesIterator(_input, _pattern, _index);
+
+  Match get first {
+    int index = stringIndexOfStringUnchecked(_input, _pattern, _index);
+    if (index >= 0) {
+      return new StringMatch(index, _input, _pattern);
+    }
+    throw IterableElementError.noElement();
+  }
+}
+
+class _StringAllMatchesIterator implements Iterator<Match> {
+  final String _input;
+  final String _pattern;
+  int _index;
+  Match _current;
+
+  _StringAllMatchesIterator(this._input, this._pattern, this._index);
+
+  bool moveNext() {
+    if (_index + _pattern.length > _input.length) {
+      _current = null;
+      return false;
+    }
+    var index = stringIndexOfStringUnchecked(_input, _pattern, _index);
+    if (index < 0) {
+      _index = _input.length + 1;
+      _current = null;
+      return false;
+    }
+    int end = index + _pattern.length;
+    _current = new StringMatch(index, _input, _pattern);
+    // Empty match, don't start at same location again.
+    if (end == _index) end++;
+    _index = end;
+    return true;
+  }
+
+  Match get current => _current;
+}
+
+stringContainsUnchecked(receiver, other, startIndex) {
+  if (other is String) {
+    return stringContainsStringUnchecked(receiver, other, startIndex);
+  } else if (other is JSSyntaxRegExp) {
+    return other.hasMatch(receiver.substring(startIndex));
+  } else {
+    var substr = receiver.substring(startIndex);
+    return other.allMatches(substr).isNotEmpty;
+  }
+}
+
+String stringReplaceJS(String receiver, jsRegExp, String replacement) {
+  return JS('String', r'#.replace(#, #)', receiver, jsRegExp,
+      escapeReplacement(replacement));
+}
+
+String escapeReplacement(String replacement) {
+  // The JavaScript `String.prototype.replace` method recognizes replacement
+  // patterns in the replacement string. Dart does not have that behavior, so
+  // the replacement patterns need to be escaped.
+
+  // `String.prototype.replace` tends to be slower when there are replacement
+  // patterns, and the escaping itself uses replacement patterns, so it is
+  // worthwhile checking for `$` first.
+  if (stringContainsStringUnchecked(replacement, r'$', 0)) {
+    return JS('String', r'#.replace(/\$/g, "$$$$")', replacement);
+  }
+  return replacement;
+}
+
+stringReplaceFirstRE(receiver, regexp, replacement, startIndex) {
+  var match = regexp._execGlobal(receiver, startIndex);
+  if (match == null) return receiver;
+  var start = match.start;
+  var end = match.end;
+  return stringReplaceRangeUnchecked(receiver, start, end, replacement);
+}
+
+/// Returns a string for a RegExp pattern that matches [string]. This is done by
+/// escaping all RegExp metacharacters.
+quoteStringForRegExp(string) {
+  // We test and replace essentially the same RegExp because replacement when
+  // there are replacement patterns is slow enough to be worth avoiding.
+  if (JS('bool', r'/[[\]{}()*+?.\\^$|]/.test(#)', string)) {
+    return JS('String', r'#.replace(/[[\]{}()*+?.\\^$|]/g, "\\$&")', string);
+  }
+  return string;
+}
+
+stringReplaceAllUnchecked(receiver, pattern, replacement) {
+  checkString(replacement);
+  if (pattern is String) {
+    return stringReplaceAllUncheckedString(receiver, pattern, replacement);
+  }
+
+  if (pattern is JSSyntaxRegExp) {
+    var re = regExpGetGlobalNative(pattern);
+    return stringReplaceJS(receiver, re, replacement);
+  }
+
+  checkNull(pattern);
+  // TODO(floitsch): implement generic String.replace (with patterns).
+  throw "String.replaceAll(Pattern) UNIMPLEMENTED";
+}
+
+/// Replaces all non-overlapping occurences of [pattern] in [receiver] with
+/// [replacement].  This should be replace with
+/// (String.prototype.replaceAll)[https://github.com/tc39/proposal-string-replace-all]
+/// when available.
+String stringReplaceAllUncheckedString(
+    String receiver, String pattern, String replacement) {
+  if (pattern == "") {
+    if (receiver == "") {
+      return JS('String', '#', replacement); // help type inference.
+    }
+    StringBuffer result = new StringBuffer('');
+    int length = receiver.length;
+    result.write(replacement);
+    for (int i = 0; i < length; i++) {
+      result.write(receiver[i]);
+      result.write(replacement);
+    }
+    return result.toString();
+  }
+
+  if (!const bool.fromEnvironment(
+      'dart2js.testing.String.replaceAll.force.regexp')) {
+    // First check for no match.
+    int index = stringIndexOfStringUnchecked(receiver, pattern, 0);
+    if (index < 0) return receiver;
+
+    // The fastest approach in general is to replace with a global RegExp, but
+    // this requires the receiver string to be long enough to amortize the cost
+    // of creating the RegExp, and the replacement to have no '$' patterns,
+    // which tend to make `String.prototype.replace` much slower. In these
+    // cases, using split-join usually wins.
+    if (receiver.length < 500 ||
+        stringContainsStringUnchecked(replacement, r'$', 0)) {
+      return stringReplaceAllUsingSplitJoin(receiver, pattern, replacement);
+    }
+  }
+  var quoted = quoteStringForRegExp(pattern);
+  var replacer = JS('', "new RegExp(#, 'g')", quoted);
+  return stringReplaceJS(receiver, replacer, replacement);
+}
+
+String stringReplaceAllUsingSplitJoin(receiver, pattern, replacement) {
+  return JS('String', '#.split(#).join(#)', receiver, pattern, replacement);
+}
+
+String _matchString(Match match) => match[0];
+String _stringIdentity(String string) => string;
+
+stringReplaceAllFuncUnchecked(receiver, pattern, onMatch, onNonMatch) {
+  if (onMatch == null) onMatch = _matchString;
+  if (onNonMatch == null) onNonMatch = _stringIdentity;
+  if (pattern is String) {
+    return stringReplaceAllStringFuncUnchecked(
+        receiver, pattern, onMatch, onNonMatch);
+  }
+  // Placing the Pattern test here is indistinguishable from placing it at the
+  // top of the method but it saves an extra check on the `pattern is String`
+  // path.
+  if (pattern is! Pattern) {
+    throw new ArgumentError.value(pattern, 'pattern', 'is not a Pattern');
+  }
+  StringBuffer buffer = new StringBuffer('');
+  int startIndex = 0;
+  for (Match match in pattern.allMatches(receiver)) {
+    buffer.write(onNonMatch(receiver.substring(startIndex, match.start)));
+    buffer.write(onMatch(match));
+    startIndex = match.end;
+  }
+  buffer.write(onNonMatch(receiver.substring(startIndex)));
+  return buffer.toString();
+}
+
+stringReplaceAllEmptyFuncUnchecked(receiver, onMatch, onNonMatch) {
+  // Pattern is the empty string.
+  StringBuffer buffer = new StringBuffer('');
+  int length = receiver.length;
+  int i = 0;
+  buffer.write(onNonMatch(""));
+  while (i < length) {
+    buffer.write(onMatch(new StringMatch(i, receiver, "")));
+    // Special case to avoid splitting a surrogate pair.
+    int code = receiver.codeUnitAt(i);
+    if ((code & ~0x3FF) == 0xD800 && length > i + 1) {
+      // Leading surrogate;
+      code = receiver.codeUnitAt(i + 1);
+      if ((code & ~0x3FF) == 0xDC00) {
+        // Matching trailing surrogate.
+        buffer.write(onNonMatch(receiver.substring(i, i + 2)));
+        i += 2;
+        continue;
+      }
+    }
+    buffer.write(onNonMatch(receiver[i]));
+    i++;
+  }
+  buffer.write(onMatch(new StringMatch(i, receiver, "")));
+  buffer.write(onNonMatch(""));
+  return buffer.toString();
+}
+
+stringReplaceAllStringFuncUnchecked(receiver, pattern, onMatch, onNonMatch) {
+  int patternLength = pattern.length;
+  if (patternLength == 0) {
+    return stringReplaceAllEmptyFuncUnchecked(receiver, onMatch, onNonMatch);
+  }
+  int length = receiver.length;
+  StringBuffer buffer = new StringBuffer('');
+  int startIndex = 0;
+  while (startIndex < length) {
+    int position = stringIndexOfStringUnchecked(receiver, pattern, startIndex);
+    if (position == -1) {
+      break;
+    }
+    buffer.write(onNonMatch(receiver.substring(startIndex, position)));
+    buffer.write(onMatch(new StringMatch(position, receiver, pattern)));
+    startIndex = position + patternLength;
+  }
+  buffer.write(onNonMatch(receiver.substring(startIndex)));
+  return buffer.toString();
+}
+
+stringReplaceFirstUnchecked(receiver, pattern, replacement, int startIndex) {
+  if (pattern is String) {
+    int index = stringIndexOfStringUnchecked(receiver, pattern, startIndex);
+    if (index < 0) return receiver;
+    int end = index + pattern.length;
+    return stringReplaceRangeUnchecked(receiver, index, end, replacement);
+  }
+  if (pattern is JSSyntaxRegExp) {
+    return startIndex == 0
+        ? stringReplaceJS(receiver, regExpGetNative(pattern), replacement)
+        : stringReplaceFirstRE(receiver, pattern, replacement, startIndex);
+  }
+  checkNull(pattern);
+  Iterator<Match> matches = pattern.allMatches(receiver, startIndex).iterator;
+  if (!matches.moveNext()) return receiver;
+  Match match = matches.current;
+  return receiver.replaceRange(match.start, match.end, replacement);
+}
+
+stringReplaceFirstMappedUnchecked(receiver, pattern, replace, int startIndex) {
+  Iterator<Match> matches = pattern.allMatches(receiver, startIndex).iterator;
+  if (!matches.moveNext()) return receiver;
+  Match match = matches.current;
+  String replacement = "${replace(match)}";
+  return receiver.replaceRange(match.start, match.end, replacement);
+}
+
+stringJoinUnchecked(array, separator) {
+  return JS('String', r'#.join(#)', array, separator);
+}
+
+String stringReplaceRangeUnchecked(
+    String receiver, int start, int end, String replacement) {
+  var prefix = JS('String', '#.substring(0, #)', receiver, start);
+  var suffix = JS('String', '#.substring(#)', receiver, end);
+  return "$prefix$replacement$suffix";
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/typed_data_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/typed_data_patch.dart
new file mode 100644
index 0000000..615c9da
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/typed_data_patch.dart
@@ -0,0 +1,190 @@
+// 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:_js_helper' show patch;
+import 'dart:_native_typed_data';
+
+@patch
+class ByteData {
+  @patch
+  factory ByteData(int length) = NativeByteData;
+}
+
+@patch
+class Float32List {
+  @patch
+  factory Float32List(int length) = NativeFloat32List;
+
+  @patch
+  factory Float32List.fromList(List<double> elements) =
+      NativeFloat32List.fromList;
+}
+
+@patch
+class Float64List {
+  @patch
+  factory Float64List(int length) = NativeFloat64List;
+
+  @patch
+  factory Float64List.fromList(List<double> elements) =
+      NativeFloat64List.fromList;
+}
+
+@patch
+class Int16List {
+  @patch
+  factory Int16List(int length) = NativeInt16List;
+
+  @patch
+  factory Int16List.fromList(List<int> elements) = NativeInt16List.fromList;
+}
+
+@patch
+class Int32List {
+  @patch
+  factory Int32List(int length) = NativeInt32List;
+
+  @patch
+  factory Int32List.fromList(List<int> elements) = NativeInt32List.fromList;
+}
+
+@patch
+class Int8List {
+  @patch
+  factory Int8List(int length) = NativeInt8List;
+
+  @patch
+  factory Int8List.fromList(List<int> elements) = NativeInt8List.fromList;
+}
+
+@patch
+class Uint32List {
+  @patch
+  factory Uint32List(int length) = NativeUint32List;
+
+  @patch
+  factory Uint32List.fromList(List<int> elements) = NativeUint32List.fromList;
+}
+
+@patch
+class Uint16List {
+  @patch
+  factory Uint16List(int length) = NativeUint16List;
+
+  @patch
+  factory Uint16List.fromList(List<int> elements) = NativeUint16List.fromList;
+}
+
+@patch
+class Uint8ClampedList {
+  @patch
+  factory Uint8ClampedList(int length) = NativeUint8ClampedList;
+
+  @patch
+  factory Uint8ClampedList.fromList(List<int> elements) =
+      NativeUint8ClampedList.fromList;
+}
+
+@patch
+class Uint8List {
+  @patch
+  factory Uint8List(int length) = NativeUint8List;
+
+  @patch
+  factory Uint8List.fromList(List<int> elements) = NativeUint8List.fromList;
+}
+
+@patch
+class Int64List {
+  @patch
+  factory Int64List(int length) {
+    throw new UnsupportedError("Int64List not supported by dart2js.");
+  }
+
+  @patch
+  factory Int64List.fromList(List<int> elements) {
+    throw new UnsupportedError("Int64List not supported by dart2js.");
+  }
+}
+
+@patch
+class Uint64List {
+  @patch
+  factory Uint64List(int length) {
+    throw new UnsupportedError("Uint64List not supported by dart2js.");
+  }
+
+  @patch
+  factory Uint64List.fromList(List<int> elements) {
+    throw new UnsupportedError("Uint64List not supported by dart2js.");
+  }
+}
+
+@patch
+class Int32x4List {
+  @patch
+  factory Int32x4List(int length) = NativeInt32x4List;
+
+  @patch
+  factory Int32x4List.fromList(List<Int32x4> elements) =
+      NativeInt32x4List.fromList;
+}
+
+@patch
+class Float32x4List {
+  @patch
+  factory Float32x4List(int length) = NativeFloat32x4List;
+
+  @patch
+  factory Float32x4List.fromList(List<Float32x4> elements) =
+      NativeFloat32x4List.fromList;
+}
+
+@patch
+class Float64x2List {
+  @patch
+  factory Float64x2List(int length) = NativeFloat64x2List;
+
+  @patch
+  factory Float64x2List.fromList(List<Float64x2> elements) =
+      NativeFloat64x2List.fromList;
+}
+
+@patch
+class Float32x4 {
+  @patch
+  factory Float32x4(double x, double y, double z, double w) = NativeFloat32x4;
+  @patch
+  factory Float32x4.splat(double v) = NativeFloat32x4.splat;
+  @patch
+  factory Float32x4.zero() = NativeFloat32x4.zero;
+  @patch
+  factory Float32x4.fromInt32x4Bits(Int32x4 x) =
+      NativeFloat32x4.fromInt32x4Bits;
+  @patch
+  factory Float32x4.fromFloat64x2(Float64x2 v) = NativeFloat32x4.fromFloat64x2;
+}
+
+@patch
+class Int32x4 {
+  @patch
+  factory Int32x4(int x, int y, int z, int w) = NativeInt32x4;
+  @patch
+  factory Int32x4.bool(bool x, bool y, bool z, bool w) = NativeInt32x4.bool;
+  @patch
+  factory Int32x4.fromFloat32x4Bits(Float32x4 x) =
+      NativeInt32x4.fromFloat32x4Bits;
+}
+
+@patch
+class Float64x2 {
+  @patch
+  factory Float64x2(double x, double y) = NativeFloat64x2;
+  @patch
+  factory Float64x2.splat(double v) = NativeFloat64x2.splat;
+  @patch
+  factory Float64x2.zero() = NativeFloat64x2.zero;
+  @patch
+  factory Float64x2.fromFloat32x4(Float32x4 v) = NativeFloat64x2.fromFloat32x4;
+}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/pubspec.yaml b/sdk_nnbd/lib/_internal/js_runtime/pubspec.yaml
new file mode 100644
index 0000000..821aaac
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/js_runtime/pubspec.yaml
@@ -0,0 +1,6 @@
+# Note: This package is not meant to be uploaded to pub. This file is used to
+# make it easier to develop on dart2js.
+name: js_runtime
+publish_to: none
+environment:
+  sdk: '>=2.0.0 <3.0.0'
diff --git a/sdk_nnbd/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk_nnbd/lib/_internal/sdk_library_metadata/lib/libraries.dart
new file mode 100644
index 0000000..ba141fa
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/sdk_library_metadata/lib/libraries.dart
@@ -0,0 +1,329 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library libraries;
+
+/**
+ * A bit flag used by [LibraryInfo] indicating that a library is used by dart2js
+ */
+const int DART2JS_PLATFORM = 1;
+
+/**
+ * A bit flag used by [LibraryInfo] indicating that a library is used by the VM
+ */
+const int VM_PLATFORM = 2;
+
+/// The contexts that a library can be used from.
+enum Category {
+  /// Indicates that a library can be used in a browser context.
+  client,
+
+  /// Indicates that a library can be used in a command line context.
+  server,
+
+  /// Indicates that a library can be used from embedded devices.
+  embedded
+}
+
+Category parseCategory(String name) {
+  switch (name) {
+    case "Client":
+      return Category.client;
+    case "Server":
+      return Category.server;
+    case "Embedded":
+      return Category.embedded;
+  }
+  return null;
+}
+
+/// Mapping of "dart:" library name (e.g. "core") to information about that
+/// library.
+const Map<String, LibraryInfo> libraries = const {
+  "async": const LibraryInfo("async/async.dart",
+      categories: "Client,Server",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/async_patch.dart"),
+  "_chrome": const LibraryInfo("_chrome/dart2js/chrome_dart2js.dart",
+      categories: "Client", documented: false),
+  "collection": const LibraryInfo("collection/collection.dart",
+      categories: "Client,Server,Embedded",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/collection_patch.dart"),
+  "convert": const LibraryInfo("convert/convert.dart",
+      categories: "Client,Server",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/convert_patch.dart"),
+  "core": const LibraryInfo("core/core.dart",
+      categories: "Client,Server,Embedded",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/core_patch.dart"),
+  "developer": const LibraryInfo("developer/developer.dart",
+      categories: "Client,Server,Embedded",
+      maturity: Maturity.UNSTABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/developer_patch.dart"),
+  "ffi": const LibraryInfo("ffi/ffi.dart",
+      categories: "Server",
+      // TODO(dacoharkes): Update maturity when we release dart:ffi.
+      // https://github.com/dart-lang/sdk/issues/34452
+      maturity: Maturity.EXPERIMENTAL),
+  "html": const LibraryInfo("html/dart2js/html_dart2js.dart",
+      categories: "Client",
+      maturity: Maturity.WEB_STABLE,
+      platforms: DART2JS_PLATFORM),
+  "html_common": const LibraryInfo("html/html_common/html_common.dart",
+      categories: "Client",
+      maturity: Maturity.WEB_STABLE,
+      dart2jsPath: "html/html_common/html_common_dart2js.dart",
+      documented: false,
+      implementation: true),
+  "indexed_db": const LibraryInfo("indexed_db/dart2js/indexed_db_dart2js.dart",
+      categories: "Client",
+      maturity: Maturity.WEB_STABLE,
+      platforms: DART2JS_PLATFORM),
+  "_http":
+      const LibraryInfo("_http/http.dart", categories: "", documented: false),
+  "io": const LibraryInfo("io/io.dart",
+      categories: "Server",
+      dart2jsPatchPath: "_internal/js_runtime/lib/io_patch.dart"),
+  "isolate": const LibraryInfo("isolate/isolate.dart",
+      categories: "Client,Server",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/isolate_patch.dart"),
+  "js": const LibraryInfo("js/dart2js/js_dart2js.dart",
+      categories: "Client",
+      maturity: Maturity.STABLE,
+      platforms: DART2JS_PLATFORM),
+  "_js": const LibraryInfo("js/_js.dart",
+      categories: "Client",
+      dart2jsPatchPath: "js/_js_client.dart",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+  "js_util": const LibraryInfo("js_util/dart2js/js_util_dart2js.dart",
+      categories: "Client",
+      maturity: Maturity.STABLE,
+      platforms: DART2JS_PLATFORM),
+  "math": const LibraryInfo("math/math.dart",
+      categories: "Client,Server,Embedded",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/math_patch.dart"),
+  "mirrors": const LibraryInfo("mirrors/mirrors.dart",
+      categories: "Client,Server",
+      maturity: Maturity.UNSTABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/mirrors_patch_cfe.dart"),
+  "nativewrappers": const LibraryInfo("html/dartium/nativewrappers.dart",
+      categories: "Client",
+      implementation: true,
+      documented: false,
+      platforms: VM_PLATFORM),
+  "typed_data": const LibraryInfo("typed_data/typed_data.dart",
+      categories: "Client,Server,Embedded",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/typed_data_patch.dart"),
+  "_native_typed_data": const LibraryInfo(
+      "_internal/js_runtime/lib/native_typed_data.dart",
+      categories: "",
+      implementation: true,
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+  "cli": const LibraryInfo("cli/cli.dart",
+      categories: "Server",
+      dart2jsPatchPath: "_internal/js_runtime/lib/cli_patch.dart"),
+  "svg": const LibraryInfo("svg/dart2js/svg_dart2js.dart",
+      categories: "Client",
+      maturity: Maturity.WEB_STABLE,
+      platforms: DART2JS_PLATFORM),
+  "wasm": const LibraryInfo("wasm/wasm.dart",
+      categories: "Server", maturity: Maturity.EXPERIMENTAL),
+  "web_audio": const LibraryInfo("web_audio/dart2js/web_audio_dart2js.dart",
+      categories: "Client",
+      maturity: Maturity.WEB_STABLE,
+      platforms: DART2JS_PLATFORM),
+  "web_gl": const LibraryInfo("web_gl/dart2js/web_gl_dart2js.dart",
+      categories: "Client",
+      maturity: Maturity.WEB_STABLE,
+      platforms: DART2JS_PLATFORM),
+  "web_sql": const LibraryInfo("web_sql/dart2js/web_sql_dart2js.dart",
+      categories: "Client",
+      maturity: Maturity.WEB_STABLE,
+      platforms: DART2JS_PLATFORM),
+  "_internal": const LibraryInfo("internal/internal.dart",
+      categories: "",
+      documented: false,
+      dart2jsPatchPath: "_internal/js_runtime/lib/internal_patch.dart"),
+  "_js_helper": const LibraryInfo("_internal/js_runtime/lib/js_helper.dart",
+      categories: "", documented: false, platforms: DART2JS_PLATFORM),
+  "_rti": const LibraryInfo("_internal/js_runtime/lib/rti.dart",
+      categories: "", documented: false, platforms: DART2JS_PLATFORM),
+  "_interceptors": const LibraryInfo(
+      "_internal/js_runtime/lib/interceptors.dart",
+      categories: "",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+  "_foreign_helper": const LibraryInfo(
+      "_internal/js_runtime/lib/foreign_helper.dart",
+      categories: "",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+  "_js_names": const LibraryInfo("_internal/js_runtime/lib/js_names.dart",
+      categories: "", documented: false, platforms: DART2JS_PLATFORM),
+  "_js_primitives": const LibraryInfo(
+      "_internal/js_runtime/lib/js_primitives.dart",
+      categories: "",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+  "_js_embedded_names": const LibraryInfo(
+      "_internal/js_runtime/lib/shared/embedded_names.dart",
+      categories: "",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+  "_async_await_error_codes": const LibraryInfo(
+      "_internal/js_runtime/lib/shared/async_await_error_codes.dart",
+      categories: "",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+  "_recipe_syntax": const LibraryInfo(
+      "_internal/js_runtime/lib/shared/recipe_syntax.dart",
+      categories: "",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+  "_metadata": const LibraryInfo("html/html_common/metadata.dart",
+      categories: "", documented: false, platforms: DART2JS_PLATFORM),
+};
+
+/**
+ * Information about a "dart:" library.
+ */
+class LibraryInfo {
+  /**
+   * Path to the library's *.dart file relative to this file.
+   */
+  final String path;
+
+  /**
+   * The categories in which the library can be used encoded as a
+   * comma-separated String.
+   */
+  final String _categories;
+
+  /**
+   * Path to the dart2js library's *.dart file relative to this file
+   * or null if dart2js uses the common library path defined above.
+   * Access using the [#getDart2JsPath()] method.
+   */
+  final String dart2jsPath;
+
+  /**
+   * Path to the dart2js library's patch file relative to this file
+   * or null if no dart2js patch file associated with this library.
+   * Access using the [#getDart2JsPatchPath()] method.
+   */
+  final String dart2jsPatchPath;
+
+  /**
+   * True if this library is documented and should be shown to the user.
+   */
+  final bool documented;
+
+  /**
+   * Bit flags indicating which platforms consume this library.
+   * See [DART2JS_LIBRARY] and [VM_LIBRARY].
+   */
+  final int platforms;
+
+  /**
+   * True if the library contains implementation details for another library.
+   * The implication is that these libraries are less commonly used
+   * and that tools like Dart Editor should not show these libraries
+   * in a list of all libraries unless the user specifically asks the tool to
+   * do so.
+   */
+  final bool implementation;
+
+  /**
+   * States the current maturity of this library.
+   */
+  final Maturity maturity;
+
+  const LibraryInfo(this.path,
+      {String categories: "",
+      this.dart2jsPath,
+      this.dart2jsPatchPath,
+      this.implementation: false,
+      this.documented: true,
+      this.maturity: Maturity.UNSPECIFIED,
+      this.platforms: DART2JS_PLATFORM | VM_PLATFORM})
+      : _categories = categories;
+
+  bool get isDart2jsLibrary => (platforms & DART2JS_PLATFORM) != 0;
+  bool get isVmLibrary => (platforms & VM_PLATFORM) != 0;
+
+  /**
+   * The categories in which the library can be used.
+   *
+   * If no categories are specified, the library is internal and can not be
+   * loaded by user code.
+   */
+  List<Category> get categories {
+    // `"".split(,)` returns [""] not [], so we handle that case separately.
+    if (_categories == "") return const <Category>[];
+    return _categories.split(",").map(parseCategory).toList();
+  }
+
+  bool get isInternal => categories.isEmpty;
+
+  /// The original "categories" String that was passed to the constructor.
+  ///
+  /// Can be used to construct a slightly modified copy of this LibraryInfo.
+  String get categoriesString {
+    return _categories;
+  }
+}
+
+/**
+ * Abstraction to capture the maturity of a library.
+ */
+class Maturity {
+  final int level;
+  final String name;
+  final String description;
+
+  const Maturity(this.level, this.name, this.description);
+
+  String toString() => "$name: $level\n$description\n";
+
+  static const Maturity DEPRECATED = const Maturity(0, "Deprecated",
+      "This library will be remove before next major release.");
+
+  static const Maturity EXPERIMENTAL = const Maturity(
+      1,
+      "Experimental",
+      "This library is experimental and will likely change or be removed\n"
+          "in future versions.");
+
+  static const Maturity UNSTABLE = const Maturity(
+      2,
+      "Unstable",
+      "This library is in still changing and have not yet endured\n"
+          "sufficient real-world testing.\n"
+          "Backwards-compatibility is NOT guaranteed.");
+
+  static const Maturity WEB_STABLE = const Maturity(
+      3,
+      "Web Stable",
+      "This library is tracking the DOM evolution as defined by WC3.\n"
+          "Backwards-compatibility is NOT guaranteed.");
+
+  static const Maturity STABLE = const Maturity(
+      4,
+      "Stable",
+      "The library is stable. API backwards-compatibility is guaranteed.\n"
+          "However implementation details might change.");
+
+  static const Maturity LOCKED = const Maturity(5, "Locked",
+      "This library will not change except when serious bugs are encountered.");
+
+  static const Maturity UNSPECIFIED = const Maturity(-1, "Unspecified",
+      "The maturity for this library has not been specified.");
+}
diff --git a/sdk_nnbd/lib/_internal/sdk_library_metadata/pubspec.yaml b/sdk_nnbd/lib/_internal/sdk_library_metadata/pubspec.yaml
new file mode 100644
index 0000000..08b5518
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/sdk_library_metadata/pubspec.yaml
@@ -0,0 +1,6 @@
+# Note: This package is not meant to be uploaded to pub. This file is used to
+# make it easer to depend on libraries.dart from sdk packages like dart2js.
+name: sdk_library_metadata
+publish_to: none
+environment:
+  sdk: '>=2.0.0 <3.0.0'
diff --git a/sdk_nnbd/lib/async/async.dart b/sdk_nnbd/lib/async/async.dart
new file mode 100644
index 0000000..b3a5dbd
--- /dev/null
+++ b/sdk_nnbd/lib/async/async.dart
@@ -0,0 +1,119 @@
+// Copyright (c) 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.
+
+/**
+ * Support for asynchronous programming,
+ * with classes such as Future and Stream.
+ *
+ * Understanding [Future]s and [Stream]s is a prerequisite for
+ * writing just about any Dart program.
+ *
+ * To use this library in your code:
+ *
+ *     import 'dart:async';
+ *
+ * ## Future
+ *
+ * A Future object represents a computation whose return value
+ * might not yet be available.
+ * The Future returns the value of the computation
+ * when it completes at some time in the future.
+ * Futures are often used for potentially lengthy computations
+ * such as I/O and interaction with users.
+ *
+ * Many methods in the Dart libraries return Futures when
+ * performing tasks. For example, when binding an HttpServer
+ * to a host and port, the `bind()` method returns a Future.
+ *
+ *      HttpServer.bind('127.0.0.1', 4444)
+ *          .then((server) => print('${server.isBroadcast}'))
+ *          .catchError(print);
+ *
+ * [Future.then] registers a callback function that runs
+ * when the Future's operation, in this case the `bind()` method,
+ * completes successfully.
+ * The value returned by the operation
+ * is passed into the callback function.
+ * In this example, the `bind()` method returns the HttpServer
+ * object. The callback function prints one of its properties.
+ * [Future.catchError] registers a callback function that
+ * runs if an error occurs within the Future.
+ *
+ * ## Stream
+ *
+ * A Stream provides an asynchronous sequence of data.
+ * Examples of data sequences include individual events, like mouse clicks,
+ * or sequential chunks of larger data, like multiple byte lists with the
+ * contents of a file
+ * such as mouse clicks, and a stream of byte lists read from a file.
+ * The following example opens a file for reading.
+ * [Stream.listen] registers a callback function that runs
+ * each time more data is available.
+ *
+ *     Stream<List<int>> stream = new File('quotes.txt').openRead();
+ *     stream.transform(utf8.decoder).listen(print);
+ *
+ * The stream emits a sequence of a list of bytes.
+ * The program must interpret the bytes or handle the raw byte data.
+ * Here, the code uses a UTF-8 decoder (provided in the `dart:convert` library)
+ * to convert the sequence of bytes into a sequence
+ * of Dart strings.
+ *
+ * Another common use of streams is for user-generated events
+ * in a web app: The following code listens for mouse clicks on a button.
+ *
+ *     querySelector('#myButton').onClick.listen((_) => print('Click.'));
+ *
+ * ## Other resources
+ *
+ * * The [dart:async section of the library tour][asynchronous-programming]:
+ *   A brief overview of asynchronous programming.
+ *
+ * * [Use Future-Based APIs][futures-tutorial]: A closer look at Futures and
+ *   how to use them to write asynchronous Dart code.
+ *
+ * * [Futures and Error Handling][futures-error-handling]: Everything you
+ *   wanted to know about handling errors and exceptions when working with
+ *   Futures (but were afraid to ask).
+ *
+ * * [The Event Loop and Dart](https://www.dartlang.org/articles/event-loop/):
+ *   Learn how Dart handles the event queue and microtask queue, so you can
+ *   write better asynchronous code with fewer surprises.
+ *
+ * * [test package: Asynchronous Tests][test-readme]: How to test asynchronous
+ *   code.
+ *
+ * [asynchronous-programming]: https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartasync---asynchronous-programming
+ * [futures-tutorial]: https://www.dartlang.org/docs/tutorials/futures/
+ * [futures-error-handling]: https://www.dartlang.org/articles/futures-and-error-handling/
+ * [test-readme]: https://pub.dartlang.org/packages/test
+ *
+ * {@category Core}
+ */
+library dart.async;
+
+import "dart:collection" show HashMap, IterableBase;
+import "dart:_internal"
+    show
+        CastStream,
+        CastStreamTransformer,
+        EmptyIterator,
+        IterableElementError,
+        printToZone,
+        printToConsole,
+        Since;
+
+part 'async_error.dart';
+part 'broadcast_stream_controller.dart';
+part 'deferred_load.dart';
+part 'future.dart';
+part 'future_impl.dart';
+part 'schedule_microtask.dart';
+part 'stream.dart';
+part 'stream_controller.dart';
+part 'stream_impl.dart';
+part 'stream_pipe.dart';
+part 'stream_transformers.dart';
+part 'timer.dart';
+part 'zone.dart';
diff --git a/sdk_nnbd/lib/async/async_error.dart b/sdk_nnbd/lib/async/async_error.dart
new file mode 100644
index 0000000..1520c54
--- /dev/null
+++ b/sdk_nnbd/lib/async/async_error.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 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 dart.async;
+
+_invokeErrorHandler(
+    Function errorHandler, Object error, StackTrace stackTrace) {
+  if (errorHandler is ZoneBinaryCallback<dynamic, Null, Null>) {
+    // Dynamic invocation because we don't know the actual type of the
+    // first argument or the error object, but we should successfully call
+    // the handler if they match up.
+    // TODO(lrn): Should we? Why not the same below for the unary case?
+    return (errorHandler as dynamic)(error, stackTrace);
+  } else {
+    ZoneUnaryCallback unaryErrorHandler = errorHandler;
+    return unaryErrorHandler(error);
+  }
+}
diff --git a/sdk_nnbd/lib/async/async_sources.gni b/sdk_nnbd/lib/async/async_sources.gni
new file mode 100644
index 0000000..3299cd4
--- /dev/null
+++ b/sdk_nnbd/lib/async/async_sources.gni
@@ -0,0 +1,23 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for 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 file contains all sources for the dart:async library.
+async_sdk_sources = [
+  "async.dart",
+
+  # The above file needs to be first as it lists the parts below.
+  "async_error.dart",
+  "broadcast_stream_controller.dart",
+  "deferred_load.dart",
+  "future.dart",
+  "future_impl.dart",
+  "schedule_microtask.dart",
+  "stream.dart",
+  "stream_controller.dart",
+  "stream_impl.dart",
+  "stream_pipe.dart",
+  "stream_transformers.dart",
+  "timer.dart",
+  "zone.dart",
+]
diff --git a/sdk_nnbd/lib/async/broadcast_stream_controller.dart b/sdk_nnbd/lib/async/broadcast_stream_controller.dart
new file mode 100644
index 0000000..32e4582
--- /dev/null
+++ b/sdk_nnbd/lib/async/broadcast_stream_controller.dart
@@ -0,0 +1,510 @@
+// Copyright (c) 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 dart.async;
+
+class _BroadcastStream<T> extends _ControllerStream<T> {
+  _BroadcastStream(_StreamControllerLifecycle<T> controller)
+      : super(controller);
+
+  bool get isBroadcast => true;
+}
+
+class _BroadcastSubscription<T> extends _ControllerSubscription<T> {
+  static const int _STATE_EVENT_ID = 1;
+  static const int _STATE_FIRING = 2;
+  static const int _STATE_REMOVE_AFTER_FIRING = 4;
+  // TODO(lrn): Use the _state field on _ControllerSubscription to
+  // also store this state. Requires that the subscription implementation
+  // does not assume that it's use of the state integer is the only use.
+  int _eventState = 0; // Initialized to help dart2js type inference.
+
+  _BroadcastSubscription<T> _next;
+  _BroadcastSubscription<T> _previous;
+
+  _BroadcastSubscription(_StreamControllerLifecycle<T> controller,
+      void onData(T data), Function onError, void onDone(), bool cancelOnError)
+      : super(controller, onData, onError, onDone, cancelOnError) {
+    _next = _previous = this;
+  }
+
+  bool _expectsEvent(int eventId) => (_eventState & _STATE_EVENT_ID) == eventId;
+
+  void _toggleEventId() {
+    _eventState ^= _STATE_EVENT_ID;
+  }
+
+  bool get _isFiring => (_eventState & _STATE_FIRING) != 0;
+
+  void _setRemoveAfterFiring() {
+    assert(_isFiring);
+    _eventState |= _STATE_REMOVE_AFTER_FIRING;
+  }
+
+  bool get _removeAfterFiring =>
+      (_eventState & _STATE_REMOVE_AFTER_FIRING) != 0;
+
+  // The controller._recordPause doesn't do anything for a broadcast controller,
+  // so we don't bother calling it.
+  void _onPause() {}
+
+  // The controller._recordResume doesn't do anything for a broadcast
+  // controller, so we don't bother calling it.
+  void _onResume() {}
+
+  // _onCancel is inherited.
+}
+
+abstract class _BroadcastStreamController<T>
+    implements _StreamControllerBase<T> {
+  static const int _STATE_INITIAL = 0;
+  static const int _STATE_EVENT_ID = 1;
+  static const int _STATE_FIRING = 2;
+  static const int _STATE_CLOSED = 4;
+  static const int _STATE_ADDSTREAM = 8;
+
+  ControllerCallback onListen;
+  ControllerCancelCallback onCancel;
+
+  // State of the controller.
+  int _state;
+
+  // Double-linked list of active listeners.
+  _BroadcastSubscription<T> _firstSubscription;
+  _BroadcastSubscription<T> _lastSubscription;
+
+  // Extra state used during an [addStream] call.
+  _AddStreamState<T> _addStreamState;
+
+  /**
+   * Future returned by [close] and [done].
+   *
+   * The future is completed whenever the done event has been sent to all
+   * relevant listeners.
+   * The relevant listeners are the ones that were listening when [close] was
+   * called. When all of these have been canceled (sending the done event makes
+   * them cancel, but they can also be canceled before sending the event),
+   * this future completes.
+   *
+   * Any attempt to listen after calling [close] will throw, so there won't
+   * be any further listeners.
+   */
+  _Future _doneFuture;
+
+  _BroadcastStreamController(this.onListen, this.onCancel)
+      : _state = _STATE_INITIAL;
+
+  ControllerCallback get onPause {
+    throw new UnsupportedError(
+        "Broadcast stream controllers do not support pause callbacks");
+  }
+
+  void set onPause(void onPauseHandler()) {
+    throw new UnsupportedError(
+        "Broadcast stream controllers do not support pause callbacks");
+  }
+
+  ControllerCallback get onResume {
+    throw new UnsupportedError(
+        "Broadcast stream controllers do not support pause callbacks");
+  }
+
+  void set onResume(void onResumeHandler()) {
+    throw new UnsupportedError(
+        "Broadcast stream controllers do not support pause callbacks");
+  }
+
+  // StreamController interface.
+
+  Stream<T> get stream => new _BroadcastStream<T>(this);
+
+  StreamSink<T> get sink => new _StreamSinkWrapper<T>(this);
+
+  bool get isClosed => (_state & _STATE_CLOSED) != 0;
+
+  /**
+   * A broadcast controller is never paused.
+   *
+   * Each receiving stream may be paused individually, and they handle their
+   * own buffering.
+   */
+  bool get isPaused => false;
+
+  /** Whether there are currently one or more subscribers. */
+  bool get hasListener => !_isEmpty;
+
+  /**
+   * Test whether the stream has exactly one listener.
+   *
+   * Assumes that the stream has a listener (not [_isEmpty]).
+   */
+  bool get _hasOneListener {
+    assert(!_isEmpty);
+    return identical(_firstSubscription, _lastSubscription);
+  }
+
+  /** Whether an event is being fired (sent to some, but not all, listeners). */
+  bool get _isFiring => (_state & _STATE_FIRING) != 0;
+
+  bool get _isAddingStream => (_state & _STATE_ADDSTREAM) != 0;
+
+  bool get _mayAddEvent => (_state < _STATE_CLOSED);
+
+  _Future _ensureDoneFuture() {
+    if (_doneFuture != null) return _doneFuture;
+    return _doneFuture = new _Future();
+  }
+
+  // Linked list helpers
+
+  bool get _isEmpty => _firstSubscription == null;
+
+  /** Adds subscription to linked list of active listeners. */
+  void _addListener(_BroadcastSubscription<T> subscription) {
+    assert(identical(subscription._next, subscription));
+    subscription._eventState = (_state & _STATE_EVENT_ID);
+    // Insert in linked list as last subscription.
+    _BroadcastSubscription<T> oldLast = _lastSubscription;
+    _lastSubscription = subscription;
+    subscription._next = null;
+    subscription._previous = oldLast;
+    if (oldLast == null) {
+      _firstSubscription = subscription;
+    } else {
+      oldLast._next = subscription;
+    }
+  }
+
+  void _removeListener(_BroadcastSubscription<T> subscription) {
+    assert(identical(subscription._controller, this));
+    assert(!identical(subscription._next, subscription));
+    _BroadcastSubscription<T> previous = subscription._previous;
+    _BroadcastSubscription<T> next = subscription._next;
+    if (previous == null) {
+      // This was the first subscription.
+      _firstSubscription = next;
+    } else {
+      previous._next = next;
+    }
+    if (next == null) {
+      // This was the last subscription.
+      _lastSubscription = previous;
+    } else {
+      next._previous = previous;
+    }
+
+    subscription._next = subscription._previous = subscription;
+  }
+
+  // _StreamControllerLifecycle interface.
+
+  StreamSubscription<T> _subscribe(void onData(T data), Function onError,
+      void onDone(), bool cancelOnError) {
+    if (isClosed) {
+      onDone ??= _nullDoneHandler;
+      return new _DoneStreamSubscription<T>(onDone);
+    }
+    StreamSubscription<T> subscription = new _BroadcastSubscription<T>(
+        this, onData, onError, onDone, cancelOnError);
+    _addListener(subscription);
+    if (identical(_firstSubscription, _lastSubscription)) {
+      // Only one listener, so it must be the first listener.
+      _runGuarded(onListen);
+    }
+    return subscription;
+  }
+
+  Future _recordCancel(StreamSubscription<T> sub) {
+    _BroadcastSubscription<T> subscription = sub;
+    // If already removed by the stream, don't remove it again.
+    if (identical(subscription._next, subscription)) return null;
+    if (subscription._isFiring) {
+      subscription._setRemoveAfterFiring();
+    } else {
+      _removeListener(subscription);
+      // If we are currently firing an event, the empty-check is performed at
+      // the end of the listener loop instead of here.
+      if (!_isFiring && _isEmpty) {
+        _callOnCancel();
+      }
+    }
+    return null;
+  }
+
+  void _recordPause(StreamSubscription<T> subscription) {}
+  void _recordResume(StreamSubscription<T> subscription) {}
+
+  // EventSink interface.
+
+  Error _addEventError() {
+    if (isClosed) {
+      return new StateError("Cannot add new events after calling close");
+    }
+    assert(_isAddingStream);
+    return new StateError("Cannot add new events while doing an addStream");
+  }
+
+  void add(T data) {
+    if (!_mayAddEvent) throw _addEventError();
+    _sendData(data);
+  }
+
+  void addError(Object error, [StackTrace stackTrace]) {
+    error = _nonNullError(error);
+    if (!_mayAddEvent) throw _addEventError();
+    AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
+    if (replacement != null) {
+      error = _nonNullError(replacement.error);
+      stackTrace = replacement.stackTrace;
+    }
+    _sendError(error, stackTrace);
+  }
+
+  Future close() {
+    if (isClosed) {
+      assert(_doneFuture != null);
+      return _doneFuture;
+    }
+    if (!_mayAddEvent) throw _addEventError();
+    _state |= _STATE_CLOSED;
+    Future doneFuture = _ensureDoneFuture();
+    _sendDone();
+    return doneFuture;
+  }
+
+  Future get done => _ensureDoneFuture();
+
+  Future addStream(Stream<T> stream, {bool cancelOnError}) {
+    if (!_mayAddEvent) throw _addEventError();
+    _state |= _STATE_ADDSTREAM;
+    _addStreamState = new _AddStreamState(this, stream, cancelOnError ?? false);
+    return _addStreamState.addStreamFuture;
+  }
+
+  // _EventSink interface, called from AddStreamState.
+  void _add(T data) {
+    _sendData(data);
+  }
+
+  void _addError(Object error, StackTrace stackTrace) {
+    _sendError(error, stackTrace);
+  }
+
+  void _close() {
+    assert(_isAddingStream);
+    _AddStreamState addState = _addStreamState;
+    _addStreamState = null;
+    _state &= ~_STATE_ADDSTREAM;
+    addState.complete();
+  }
+
+  // Event handling.
+  void _forEachListener(
+      void action(_BufferingStreamSubscription<T> subscription)) {
+    if (_isFiring) {
+      throw new StateError(
+          "Cannot fire new event. Controller is already firing an event");
+    }
+    if (_isEmpty) return;
+
+    // Get event id of this event.
+    int id = (_state & _STATE_EVENT_ID);
+    // Start firing (set the _STATE_FIRING bit). We don't do [onCancel]
+    // callbacks while firing, and we prevent reentrancy of this function.
+    //
+    // Set [_state]'s event id to the next event's id.
+    // Any listeners added while firing this event will expect the next event,
+    // not this one, and won't get notified.
+    _state ^= _STATE_EVENT_ID | _STATE_FIRING;
+    _BroadcastSubscription<T> subscription = _firstSubscription;
+    while (subscription != null) {
+      if (subscription._expectsEvent(id)) {
+        subscription._eventState |= _BroadcastSubscription._STATE_FIRING;
+        action(subscription);
+        subscription._toggleEventId();
+        _BroadcastSubscription<T> next = subscription._next;
+        if (subscription._removeAfterFiring) {
+          _removeListener(subscription);
+        }
+        subscription._eventState &= ~_BroadcastSubscription._STATE_FIRING;
+        subscription = next;
+      } else {
+        subscription = subscription._next;
+      }
+    }
+    _state &= ~_STATE_FIRING;
+
+    if (_isEmpty) {
+      _callOnCancel();
+    }
+  }
+
+  void _callOnCancel() {
+    assert(_isEmpty);
+    if (isClosed && _doneFuture._mayComplete) {
+      // When closed, _doneFuture is not null.
+      _doneFuture._asyncComplete(null);
+    }
+    _runGuarded(onCancel);
+  }
+}
+
+class _SyncBroadcastStreamController<T> extends _BroadcastStreamController<T>
+    implements SynchronousStreamController<T> {
+  _SyncBroadcastStreamController(void onListen(), void onCancel())
+      : super(onListen, onCancel);
+
+  // EventDispatch interface.
+
+  bool get _mayAddEvent => super._mayAddEvent && !_isFiring;
+
+  _addEventError() {
+    if (_isFiring) {
+      return new StateError(
+          "Cannot fire new event. Controller is already firing an event");
+    }
+    return super._addEventError();
+  }
+
+  void _sendData(T data) {
+    if (_isEmpty) return;
+    if (_hasOneListener) {
+      _state |= _BroadcastStreamController._STATE_FIRING;
+      _BroadcastSubscription<T> subscription = _firstSubscription;
+      subscription._add(data);
+      _state &= ~_BroadcastStreamController._STATE_FIRING;
+      if (_isEmpty) {
+        _callOnCancel();
+      }
+      return;
+    }
+    _forEachListener((_BufferingStreamSubscription<T> subscription) {
+      subscription._add(data);
+    });
+  }
+
+  void _sendError(Object error, StackTrace stackTrace) {
+    if (_isEmpty) return;
+    _forEachListener((_BufferingStreamSubscription<T> subscription) {
+      subscription._addError(error, stackTrace);
+    });
+  }
+
+  void _sendDone() {
+    if (!_isEmpty) {
+      _forEachListener((_BufferingStreamSubscription<T> subscription) {
+        subscription._close();
+      });
+    } else {
+      assert(_doneFuture != null);
+      assert(_doneFuture._mayComplete);
+      _doneFuture._asyncComplete(null);
+    }
+  }
+}
+
+class _AsyncBroadcastStreamController<T> extends _BroadcastStreamController<T> {
+  _AsyncBroadcastStreamController(void onListen(), void onCancel())
+      : super(onListen, onCancel);
+
+  // EventDispatch interface.
+
+  void _sendData(T data) {
+    for (_BroadcastSubscription<T> subscription = _firstSubscription;
+        subscription != null;
+        subscription = subscription._next) {
+      subscription._addPending(new _DelayedData<T>(data));
+    }
+  }
+
+  void _sendError(Object error, StackTrace stackTrace) {
+    for (_BroadcastSubscription<T> subscription = _firstSubscription;
+        subscription != null;
+        subscription = subscription._next) {
+      subscription._addPending(new _DelayedError(error, stackTrace));
+    }
+  }
+
+  void _sendDone() {
+    if (!_isEmpty) {
+      for (_BroadcastSubscription<T> subscription = _firstSubscription;
+          subscription != null;
+          subscription = subscription._next) {
+        subscription._addPending(const _DelayedDone());
+      }
+    } else {
+      assert(_doneFuture != null);
+      assert(_doneFuture._mayComplete);
+      _doneFuture._asyncComplete(null);
+    }
+  }
+}
+
+/**
+ * Stream controller that is used by [Stream.asBroadcastStream].
+ *
+ * This stream controller allows incoming events while it is firing
+ * other events. This is handled by delaying the events until the
+ * current event is done firing, and then fire the pending events.
+ *
+ * This class extends [_SyncBroadcastStreamController]. Events of
+ * an "asBroadcastStream" stream are always initiated by events
+ * on another stream, and it is fine to forward them synchronously.
+ */
+class _AsBroadcastStreamController<T> extends _SyncBroadcastStreamController<T>
+    implements _EventDispatch<T> {
+  _StreamImplEvents<T> _pending;
+
+  _AsBroadcastStreamController(void onListen(), void onCancel())
+      : super(onListen, onCancel);
+
+  bool get _hasPending => _pending != null && !_pending.isEmpty;
+
+  void _addPendingEvent(_DelayedEvent event) {
+    _pending ??= new _StreamImplEvents<T>();
+    _pending.add(event);
+  }
+
+  void add(T data) {
+    if (!isClosed && _isFiring) {
+      _addPendingEvent(new _DelayedData<T>(data));
+      return;
+    }
+    super.add(data);
+    while (_hasPending) {
+      _pending.handleNext(this);
+    }
+  }
+
+  void addError(Object error, [StackTrace stackTrace]) {
+    if (!isClosed && _isFiring) {
+      _addPendingEvent(new _DelayedError(error, stackTrace));
+      return;
+    }
+    if (!_mayAddEvent) throw _addEventError();
+    _sendError(error, stackTrace);
+    while (_hasPending) {
+      _pending.handleNext(this);
+    }
+  }
+
+  Future close() {
+    if (!isClosed && _isFiring) {
+      _addPendingEvent(const _DelayedDone());
+      _state |= _BroadcastStreamController._STATE_CLOSED;
+      return super.done;
+    }
+    Future result = super.close();
+    assert(!_hasPending);
+    return result;
+  }
+
+  void _callOnCancel() {
+    if (_hasPending) {
+      _pending.clear();
+      _pending = null;
+    }
+    super._callOnCancel();
+  }
+}
diff --git a/sdk_nnbd/lib/async/deferred_load.dart b/sdk_nnbd/lib/async/deferred_load.dart
new file mode 100644
index 0000000..f83d4b8
--- /dev/null
+++ b/sdk_nnbd/lib/async/deferred_load.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.
+
+part of dart.async;
+
+/**
+ * Indicates that loading of [libraryName] is deferred.
+ *
+ * This class is obsolete. Instead use the syntax:
+ * import "library.dart" deferred as prefix;
+ */
+@Deprecated("Dart sdk v. 1.8")
+class DeferredLibrary {
+  final String libraryName;
+  final String uri;
+
+  const DeferredLibrary(this.libraryName, {this.uri});
+
+  /**
+   * Ensure that [libraryName] has been loaded.
+   *
+   * If the library fails to load, the Future will complete with a
+   * DeferredLoadException.
+   */
+  external Future<Null> load();
+}
+
+/**
+ * Thrown when a deferred library fails to load.
+ */
+class DeferredLoadException implements Exception {
+  DeferredLoadException(this._s);
+  String toString() => "DeferredLoadException: '$_s'";
+  final String _s;
+}
diff --git a/sdk_nnbd/lib/async/future.dart b/sdk_nnbd/lib/async/future.dart
new file mode 100644
index 0000000..b9d22c1
--- /dev/null
+++ b/sdk_nnbd/lib/async/future.dart
@@ -0,0 +1,931 @@
+// Copyright (c) 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 dart.async;
+
+/// A type representing values that are either `Future<T>` or `T`.
+///
+/// This class declaration is a public stand-in for an internal
+/// future-or-value generic type. References to this class are resolved to the
+/// internal type.
+///
+/// It is a compile-time error for any class to extend, mix in or implement
+/// `FutureOr`.
+///
+/// Note: the `FutureOr<T>` type is interpreted as `dynamic` in non strong-mode.
+///
+/// # Examples
+/// ``` dart
+/// // The `Future<T>.then` function takes a callback [f] that returns either
+/// // an `S` or a `Future<S>`.
+/// Future<S> then<S>(FutureOr<S> f(T x), ...);
+///
+/// // `Completer<T>.complete` takes either a `T` or `Future<T>`.
+/// void complete(FutureOr<T> value);
+/// ```
+///
+/// # Advanced
+/// The `FutureOr<int>` type is actually the "type union" of the types `int` and
+/// `Future<int>`. This type union is defined in such a way that
+/// `FutureOr<Object>` is both a super- and sub-type of `Object` (sub-type
+/// because `Object` is one of the types of the union, super-type because
+/// `Object` is a super-type of both of the types of the union). Together it
+/// means that `FutureOr<Object>` is equivalent to `Object`.
+///
+/// As a corollary, `FutureOr<Object>` is equivalent to
+/// `FutureOr<FutureOr<Object>>`, `FutureOr<Future<Object>>` is equivalent to
+/// `Future<Object>`.
+abstract class FutureOr<T> {
+  // Private generative constructor, so that it is not subclassable, mixable, or
+  // instantiable.
+  FutureOr._() {
+    throw new UnsupportedError("FutureOr can't be instantiated");
+  }
+}
+
+/**
+ * An object representing a delayed computation.
+ *
+ * A [Future] is used to represent a potential value, or error,
+ * that will be available at some time in the future.
+ * Receivers of a [Future] can register callbacks
+ * that handle the value or error once it is available.
+ * For example:
+ *
+ *     Future<int> future = getFuture();
+ *     future.then((value) => handleValue(value))
+ *           .catchError((error) => handleError(error));
+ *
+ * A [Future] can be completed in two ways:
+ * with a value ("the future succeeds")
+ * or with an error ("the future fails").
+ * Users can install callbacks for each case.
+ *
+ * In some cases we say that a future is completed with another future.
+ * This is a short way of stating that the future is completed in the same way,
+ * with the same value or error,
+ * as the other future once that completes.
+ * Whenever a function in the core library may complete a future
+ * (for example [Completer.complete] or [new Future.value]),
+ * then it also accepts another future and does this work for the developer.
+ *
+ * The result of registering a pair of callbacks is a new Future (the
+ * "successor") which in turn is completed with the result of invoking the
+ * corresponding callback.
+ * The successor is completed with an error if the invoked callback throws.
+ * For example:
+ * ```
+ * Future<int> successor = future.then((int value) {
+ *     // Invoked when the future is completed with a value.
+ *     return 42;  // The successor is completed with the value 42.
+ *   },
+ *   onError: (e) {
+ *     // Invoked when the future is completed with an error.
+ *     if (canHandle(e)) {
+ *       return 499;  // The successor is completed with the value 499.
+ *     } else {
+ *       throw e;  // The successor is completed with the error e.
+ *     }
+ *   });
+ * ```
+ *
+ * If a future does not have a successor when it completes with an error,
+ * it forwards the error message to the global error-handler.
+ * This behavior makes sure that no error is silently dropped.
+ * However, it also means that error handlers should be installed early,
+ * so that they are present as soon as a future is completed with an error.
+ * The following example demonstrates this potential bug:
+ * ```
+ * var future = getFuture();
+ * new Timer(new Duration(milliseconds: 5), () {
+ *   // The error-handler is not attached until 5 ms after the future has
+ *   // been received. If the future fails before that, the error is
+ *   // forwarded to the global error-handler, even though there is code
+ *   // (just below) to eventually handle the error.
+ *   future.then((value) { useValue(value); },
+ *               onError: (e) { handleError(e); });
+ * });
+ * ```
+ *
+ * When registering callbacks, it's often more readable to register the two
+ * callbacks separately, by first using [then] with one argument
+ * (the value handler) and using a second [catchError] for handling errors.
+ * Each of these will forward the result that they don't handle
+ * to their successors, and together they handle both value and error result.
+ * It also has the additional benefit of the [catchError] handling errors in the
+ * [then] value callback too.
+ * Using sequential handlers instead of parallel ones often leads to code that
+ * is easier to reason about.
+ * It also makes asynchronous code very similar to synchronous code:
+ * ```
+ * // Synchronous code.
+ * try {
+ *   int value = foo();
+ *   return bar(value);
+ * } catch (e) {
+ *   return 499;
+ * }
+ * ```
+ *
+ * Equivalent asynchronous code, based on futures:
+ * ```
+ * Future<int> future = new Future(foo);  // Result of foo() as a future.
+ * future.then((int value) => bar(value))
+ *       .catchError((e) => 499);
+ * ```
+ *
+ * Similar to the synchronous code, the error handler (registered with
+ * [catchError]) is handling any errors thrown by either `foo` or `bar`.
+ * If the error-handler had been registered as the `onError` parameter of
+ * the `then` call, it would not catch errors from the `bar` call.
+ *
+ * Futures can have more than one callback-pair registered. Each successor is
+ * treated independently and is handled as if it was the only successor.
+ *
+ * A future may also fail to ever complete. In that case, no callbacks are
+ * called.
+ */
+abstract class Future<T> {
+  /// A `Future<Null>` completed with `null`.
+  static final _Future<Null> _nullFuture =
+      new _Future<Null>.zoneValue(null, Zone.root);
+
+  /// A `Future<bool>` completed with `false`.
+  static final _Future<bool> _falseFuture =
+      new _Future<bool>.zoneValue(false, Zone.root);
+
+  /**
+   * Creates a future containing the result of calling [computation]
+   * asynchronously with [Timer.run].
+   *
+   * If the result of executing [computation] throws, the returned future is
+   * completed with the error.
+   *
+   * If the returned value is itself a [Future], completion of
+   * the created future will wait until the returned future completes,
+   * and will then complete with the same result.
+   *
+   * If a non-future value is returned, the returned future is completed
+   * with that value.
+   */
+  factory Future(FutureOr<T> computation()) {
+    _Future<T> result = new _Future<T>();
+    Timer.run(() {
+      try {
+        result._complete(computation());
+      } catch (e, s) {
+        _completeWithErrorCallback(result, e, s);
+      }
+    });
+    return result;
+  }
+
+  /**
+   * Creates a future containing the result of calling [computation]
+   * asynchronously with [scheduleMicrotask].
+   *
+   * If executing [computation] throws,
+   * the returned future is completed with the thrown error.
+   *
+   * If calling [computation] returns a [Future], completion of
+   * the created future will wait until the returned future completes,
+   * and will then complete with the same result.
+   *
+   * If calling [computation] returns a non-future value,
+   * the returned future is completed with that value.
+   */
+  factory Future.microtask(FutureOr<T> computation()) {
+    _Future<T> result = new _Future<T>();
+    scheduleMicrotask(() {
+      try {
+        result._complete(computation());
+      } catch (e, s) {
+        _completeWithErrorCallback(result, e, s);
+      }
+    });
+    return result;
+  }
+
+  /**
+   * Returns a future containing the result of immediately calling
+   * [computation].
+   *
+   * If calling [computation] throws, the returned future is completed with the
+   * error.
+   *
+   * If calling [computation] returns a `Future<T>`, that future is returned.
+   *
+   * If calling [computation] returns a non-future value,
+   * a future is returned which has been completed with that value.
+   */
+  factory Future.sync(FutureOr<T> computation()) {
+    try {
+      var result = computation();
+      if (result is Future<T>) {
+        return result;
+      } else {
+        return new _Future<T>.value(result);
+      }
+    } catch (error, stackTrace) {
+      var future = new _Future<T>();
+      AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
+      if (replacement != null) {
+        future._asyncCompleteError(
+            _nonNullError(replacement.error), replacement.stackTrace);
+      } else {
+        future._asyncCompleteError(error, stackTrace);
+      }
+      return future;
+    }
+  }
+
+  /**
+   * Creates a future completed with [value].
+   *
+   * If [value] is a future, the created future waits for the
+   * [value] future to complete, and then completes with the same result.
+   * Since a [value] future can complete with an error, so can the future
+   * created by [Future.value], even if the name suggests otherwise.
+   *
+   * If [value] is not a [Future], the created future is completed
+   * with the [value] value,
+   * equivalently to `new Future<T>.sync(() => value)`.
+   *
+   * Use [Completer] to create a future and complete it later.
+   */
+  factory Future.value([FutureOr<T> value]) {
+    return new _Future<T>.immediate(value);
+  }
+
+  /**
+   * Creates a future that completes with an error.
+   *
+   * The created future will be completed with an error in a future microtask.
+   * This allows enough time for someone to add an error handler on the future.
+   * If an error handler isn't added before the future completes, the error
+   * will be considered unhandled.
+   *
+   * If [error] is `null`, it is replaced by a [NullThrownError].
+   *
+   * Use [Completer] to create a future and complete it later.
+   */
+  factory Future.error(Object error, [StackTrace stackTrace]) {
+    error = _nonNullError(error);
+    if (!identical(Zone.current, _rootZone)) {
+      AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
+      if (replacement != null) {
+        error = _nonNullError(replacement.error);
+        stackTrace = replacement.stackTrace;
+      }
+    }
+    return new _Future<T>.immediateError(error, stackTrace);
+  }
+
+  /**
+   * Creates a future that runs its computation after a delay.
+   *
+   * The [computation] will be executed after the given [duration] has passed,
+   * and the future is completed with the result of the computation.
+   *
+   * If [computation] returns a future,
+   * the future returned by this constructor will complete with the value or
+   * error of that future.
+   *
+   * If the duration is 0 or less,
+   * it completes no sooner than in the next event-loop iteration,
+   * after all microtasks have run.
+   *
+   * If [computation] is omitted,
+   * it will be treated as if [computation] was `() => null`,
+   * and the future will eventually complete with the `null` value.
+   *
+   * If calling [computation] throws, the created future will complete with the
+   * error.
+   *
+   * See also [Completer] for a way to create and complete a future at a
+   * later time that isn't necessarily after a known fixed duration.
+   */
+  factory Future.delayed(Duration duration, [FutureOr<T> computation()]) {
+    _Future<T> result = new _Future<T>();
+    new Timer(duration, () {
+      if (computation == null) {
+        result._complete(null);
+      } else {
+        try {
+          result._complete(computation());
+        } catch (e, s) {
+          _completeWithErrorCallback(result, e, s);
+        }
+      }
+    });
+    return result;
+  }
+
+  /**
+   * Waits for multiple futures to complete and collects their results.
+   *
+   * Returns a future which will complete once all the provided futures
+   * have completed, either with their results, or with an error if any
+   * of the provided futures fail.
+   *
+   * The value of the returned future will be a list of all the values that
+   * were produced in the order that the futures are provided by iterating
+   * [futures].
+   *
+   * If any future completes with an error,
+   * then the returned future completes with that error.
+   * If further futures also complete with errors, those errors are discarded.
+   *
+   * If `eagerError` is true, the returned future completes with an error
+   * immediately on the first error from one of the futures. Otherwise all
+   * futures must complete before the returned future is completed (still with
+   * the first error; the remaining errors are silently dropped).
+   *
+   * In the case of an error, [cleanUp] (if provided), is invoked on any
+   * non-null result of successful futures.
+   * This makes it possible to `cleanUp` resources that would otherwise be
+   * lost (since the returned future does not provide access to these values).
+   * The [cleanUp] function is unused if there is no error.
+   *
+   * The call to [cleanUp] should not throw. If it does, the error will be an
+   * uncaught asynchronous error.
+   */
+  static Future<List<T>> wait<T>(Iterable<Future<T>> futures,
+      {bool eagerError: false, void cleanUp(T successValue)}) {
+    final _Future<List<T>> result = new _Future<List<T>>();
+    List<T> values; // Collects the values. Set to null on error.
+    int remaining = 0; // How many futures are we waiting for.
+    var error; // The first error from a future.
+    StackTrace stackTrace; // The stackTrace that came with the error.
+
+    // Handle an error from any of the futures.
+    // TODO(jmesserly): use `void` return type once it can be inferred for the
+    // `then` call below.
+    handleError(theError, StackTrace theStackTrace) {
+      remaining--;
+      if (values != null) {
+        if (cleanUp != null) {
+          for (var value in values) {
+            if (value != null) {
+              // Ensure errors from cleanUp are uncaught.
+              new Future.sync(() {
+                cleanUp(value);
+              });
+            }
+          }
+        }
+        values = null;
+        if (remaining == 0 || eagerError) {
+          result._completeError(theError, theStackTrace);
+        } else {
+          error = theError;
+          stackTrace = theStackTrace;
+        }
+      } else if (remaining == 0 && !eagerError) {
+        result._completeError(error, stackTrace);
+      }
+    }
+
+    try {
+      // As each future completes, put its value into the corresponding
+      // position in the list of values.
+      for (var future in futures) {
+        int pos = remaining;
+        future.then((T value) {
+          remaining--;
+          if (values != null) {
+            values[pos] = value;
+            if (remaining == 0) {
+              result._completeWithValue(values);
+            }
+          } else {
+            if (cleanUp != null && value != null) {
+              // Ensure errors from cleanUp are uncaught.
+              new Future.sync(() {
+                cleanUp(value);
+              });
+            }
+            if (remaining == 0 && !eagerError) {
+              result._completeError(error, stackTrace);
+            }
+          }
+        }, onError: handleError);
+        // Increment the 'remaining' after the call to 'then'.
+        // If that call throws, we don't expect any future callback from
+        // the future, and we also don't increment remaining.
+        remaining++;
+      }
+      if (remaining == 0) {
+        return new Future.value(const []);
+      }
+      values = new List<T>(remaining);
+    } catch (e, st) {
+      // The error must have been thrown while iterating over the futures
+      // list, or while installing a callback handler on the future.
+      if (remaining == 0 || eagerError) {
+        // Throw a new Future.error.
+        // Don't just call `result._completeError` since that would propagate
+        // the error too eagerly, not giving the callers time to install
+        // error handlers.
+        // Also, don't use `_asyncCompleteError` since that one doesn't give
+        // zones the chance to intercept the error.
+        return new Future.error(e, st);
+      } else {
+        // Don't allocate a list for values, thus indicating that there was an
+        // error.
+        // Set error to the caught exception.
+        error = e;
+        stackTrace = st;
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Returns the result of the first future in [futures] to complete.
+   *
+   * The returned future is completed with the result of the first
+   * future in [futures] to report that it is complete,
+   * whether it's with a value or an error.
+   * The results of all the other futures are discarded.
+   *
+   * If [futures] is empty, or if none of its futures complete,
+   * the returned future never completes.
+   */
+  static Future<T> any<T>(Iterable<Future<T>> futures) {
+    var completer = new Completer<T>.sync();
+    var onValue = (T value) {
+      if (!completer.isCompleted) completer.complete(value);
+    };
+    var onError = (error, StackTrace stack) {
+      if (!completer.isCompleted) completer.completeError(error, stack);
+    };
+    for (var future in futures) {
+      future.then(onValue, onError: onError);
+    }
+    return completer.future;
+  }
+
+  /**
+   * Performs an action for each element of the iterable, in turn.
+   *
+   * The [action] may be either synchronous or asynchronous.
+   *
+   * Calls [action] with each element in [elements] in order.
+   * If the call to [action] returns a `Future<T>`, the iteration waits
+   * until the future is completed before continuing with the next element.
+   *
+   * Returns a [Future] that completes with `null` when all elements have been
+   * processed.
+   *
+   * Non-[Future] return values, and completion-values of returned [Future]s,
+   * are discarded.
+   *
+   * Any error from [action], synchronous or asynchronous,
+   * will stop the iteration and be reported in the returned [Future].
+   */
+  static Future forEach<T>(Iterable<T> elements, FutureOr action(T element)) {
+    var iterator = elements.iterator;
+    return doWhile(() {
+      if (!iterator.moveNext()) return false;
+      var result = action(iterator.current);
+      if (result is Future) return result.then(_kTrue);
+      return true;
+    });
+  }
+
+  // Constant `true` function, used as callback by [forEach].
+  static bool _kTrue(_) => true;
+
+  /**
+   * Performs an operation repeatedly until it returns `false`.
+   *
+   * The operation, [action], may be either synchronous or asynchronous.
+   *
+   * The operation is called repeatedly as long as it returns either the [bool]
+   * value `true` or a `Future<bool>` which completes with the value `true`.
+   *
+   * If a call to [action] returns `false` or a [Future] that completes to
+   * `false`, iteration ends and the future returned by [doWhile] is completed
+   * with a `null` value.
+   *
+   * If a call to [action] throws or a future returned by [action] completes
+   * with an error, iteration ends and the future returned by [doWhile]
+   * completes with the same error.
+   *
+   * Calls to [action] may happen at any time,
+   * including immediately after calling `doWhile`.
+   * The only restriction is a new call to [action] won't happen before
+   * the previous call has returned, and if it returned a `Future<bool>`, not
+   * until that future has completed.
+   */
+  static Future doWhile(FutureOr<bool> action()) {
+    _Future doneSignal = new _Future();
+    void Function(bool) nextIteration;
+    // Bind this callback explicitly so that each iteration isn't bound in the
+    // context of all the previous iterations' callbacks.
+    // This avoids, e.g., deeply nested stack traces from the stack trace
+    // package.
+    nextIteration = Zone.current.bindUnaryCallbackGuarded((bool keepGoing) {
+      while (keepGoing) {
+        FutureOr<bool> result;
+        try {
+          result = action();
+        } catch (error, stackTrace) {
+          // Cannot use _completeWithErrorCallback because it completes
+          // the future synchronously.
+          _asyncCompleteWithErrorCallback(doneSignal, error, stackTrace);
+          return;
+        }
+        if (result is Future<bool>) {
+          result.then(nextIteration, onError: doneSignal._completeError);
+          return;
+        }
+        keepGoing = result;
+      }
+      doneSignal._complete(null);
+    });
+    nextIteration(true);
+    return doneSignal;
+  }
+
+  /**
+   * Register callbacks to be called when this future completes.
+   *
+   * When this future completes with a value,
+   * the [onValue] callback will be called with that value.
+   * If this future is already completed, the callback will not be called
+   * immediately, but will be scheduled in a later microtask.
+   *
+   * If [onError] is provided, and this future completes with an error,
+   * the `onError` callback is called with that error and its stack trace.
+   * The `onError` callback must accept either one argument or two arguments
+   * where the latter is a [StackTrace].
+   * If `onError` accepts two arguments,
+   * it is called with both the error and the stack trace,
+   * otherwise it is called with just the error object.
+   * The `onError` callback must return a value or future that can be used
+   * to complete the returned future, so it must be something assignable to
+   * `FutureOr<R>`.
+   *
+   * Returns a new [Future]
+   * which is completed with the result of the call to `onValue`
+   * (if this future completes with a value)
+   * or to `onError` (if this future completes with an error).
+   *
+   * If the invoked callback throws,
+   * the returned future is completed with the thrown error
+   * and a stack trace for the error.
+   * In the case of `onError`,
+   * if the exception thrown is `identical` to the error argument to `onError`,
+   * the throw is considered a rethrow,
+   * and the original stack trace is used instead.
+   *
+   * If the callback returns a [Future],
+   * the future returned by `then` will be completed with
+   * the same result as the future returned by the callback.
+   *
+   * If [onError] is not given, and this future completes with an error,
+   * the error is forwarded directly to the returned future.
+   *
+   * In most cases, it is more readable to use [catchError] separately, possibly
+   * with a `test` parameter, instead of handling both value and error in a
+   * single [then] call.
+   *
+   * Note that futures don't delay reporting of errors until listeners are
+   * added. If the first `then` or `catchError` call happens after this future
+   * has completed with an error then the error is reported as unhandled error.
+   * See the description on [Future].
+   */
+  Future<R> then<R>(FutureOr<R> onValue(T value), {Function onError});
+
+  /**
+   * Handles errors emitted by this [Future].
+   *
+   * This is the asynchronous equivalent of a "catch" block.
+   *
+   * Returns a new [Future] that will be completed with either the result of
+   * this future or the result of calling the `onError` callback.
+   *
+   * If this future completes with a value,
+   * the returned future completes with the same value.
+   *
+   * If this future completes with an error,
+   * then [test] is first called with the error value.
+   *
+   * If `test` returns false, the exception is not handled by this `catchError`,
+   * and the returned future completes with the same error and stack trace
+   * as this future.
+   *
+   * If `test` returns `true`,
+   * [onError] is called with the error and possibly stack trace,
+   * and the returned future is completed with the result of this call
+   * in exactly the same way as for [then]'s `onError`.
+   *
+   * If `test` is omitted, it defaults to a function that always returns true.
+   * The `test` function should not throw, but if it does, it is handled as
+   * if the `onError` function had thrown.
+   *
+   * Note that futures don't delay reporting of errors until listeners are
+   * added. If the first `catchError` (or `then`) call happens after this future
+   * has completed with an error then the error is reported as unhandled error.
+   * See the description on [Future].
+   */
+  // The `Function` below stands for one of two types:
+  // - (dynamic) -> FutureOr<T>
+  // - (dynamic, StackTrace) -> FutureOr<T>
+  // Given that there is a `test` function that is usually used to do an
+  // `isCheck` we should also expect functions that take a specific argument.
+  // Note: making `catchError` return a `Future<T>` in non-strong mode could be
+  // a breaking change.
+  Future<T> catchError(Function onError, {bool test(Object error)});
+
+  /**
+   * Registers a function to be called when this future completes.
+   *
+   * The [action] function is called when this future completes, whether it
+   * does so with a value or with an error.
+   *
+   * This is the asynchronous equivalent of a "finally" block.
+   *
+   * The future returned by this call, `f`, will complete the same way
+   * as this future unless an error occurs in the [action] call, or in
+   * a [Future] returned by the [action] call. If the call to [action]
+   * does not return a future, its return value is ignored.
+   *
+   * If the call to [action] throws, then `f` is completed with the
+   * thrown error.
+   *
+   * If the call to [action] returns a [Future], `f2`, then completion of
+   * `f` is delayed until `f2` completes. If `f2` completes with
+   * an error, that will be the result of `f` too. The value of `f2` is always
+   * ignored.
+   *
+   * This method is equivalent to:
+   *
+   *     Future<T> whenComplete(action()) {
+   *       return this.then((v) {
+   *         var f2 = action();
+   *         if (f2 is Future) return f2.then((_) => v);
+   *         return v
+   *       }, onError: (e) {
+   *         var f2 = action();
+   *         if (f2 is Future) return f2.then((_) { throw e; });
+   *         throw e;
+   *       });
+   *     }
+   */
+  Future<T> whenComplete(FutureOr action());
+
+  /**
+   * Creates a [Stream] containing the result of this future.
+   *
+   * The stream will produce single data or error event containing the
+   * completion result of this future, and then it will close with a
+   * done event.
+   *
+   * If the future never completes, the stream will not produce any events.
+   */
+  Stream<T> asStream();
+
+  /**
+   * Time-out the future computation after [timeLimit] has passed.
+   *
+   * Returns a new future that completes with the same value as this future,
+   * if this future completes in time.
+   *
+   * If this future does not complete before `timeLimit` has passed,
+   * the [onTimeout] action is executed instead, and its result (whether it
+   * returns or throws) is used as the result of the returned future.
+   * The [onTimeout] function must return a [T] or a `Future<T>`.
+   *
+   * If `onTimeout` is omitted, a timeout will cause the returned future to
+   * complete with a [TimeoutException].
+   */
+  Future<T> timeout(Duration timeLimit, {FutureOr<T> onTimeout()});
+}
+
+/**
+ * Thrown when a scheduled timeout happens while waiting for an async result.
+ */
+class TimeoutException implements Exception {
+  /** Description of the cause of the timeout. */
+  final String message;
+  /** The duration that was exceeded. */
+  final Duration duration;
+
+  TimeoutException(this.message, [this.duration]);
+
+  String toString() {
+    String result = "TimeoutException";
+    if (duration != null) result = "TimeoutException after $duration";
+    if (message != null) result = "$result: $message";
+    return result;
+  }
+}
+
+/**
+ * A way to produce Future objects and to complete them later
+ * with a value or error.
+ *
+ * Most of the time, the simplest way to create a future is to just use
+ * one of the [Future] constructors to capture the result of a single
+ * asynchronous computation:
+ * ```
+ * new Future(() { doSomething(); return result; });
+ * ```
+ * or, if the future represents the result of a sequence of asynchronous
+ * computations, they can be chained using [Future.then] or similar functions
+ * on [Future]:
+ * ```
+ * Future doStuff(){
+ *   return someAsyncOperation().then((result) {
+ *     return someOtherAsyncOperation(result);
+ *   });
+ * }
+ * ```
+ * If you do need to create a Future from scratch — for example,
+ * when you're converting a callback-based API into a Future-based
+ * one — you can use a Completer as follows:
+ * ```
+ * class AsyncOperation {
+ *   Completer _completer = new Completer();
+ *
+ *   Future<T> doOperation() {
+ *     _startOperation();
+ *     return _completer.future; // Send future object back to client.
+ *   }
+ *
+ *   // Something calls this when the value is ready.
+ *   void _finishOperation(T result) {
+ *     _completer.complete(result);
+ *   }
+ *
+ *   // If something goes wrong, call this.
+ *   void _errorHappened(error) {
+ *     _completer.completeError(error);
+ *   }
+ * }
+ * ```
+ */
+abstract class Completer<T> {
+  /**
+   * Creates a new completer.
+   *
+   * The general workflow for creating a new future is to 1) create a
+   * new completer, 2) hand out its future, and, at a later point, 3) invoke
+   * either [complete] or [completeError].
+   *
+   * The completer completes the future asynchronously. That means that
+   * callbacks registered on the future are not called immediately when
+   * [complete] or [completeError] is called. Instead the callbacks are
+   * delayed until a later microtask.
+   *
+   * Example:
+   * ```
+   * var completer = new Completer();
+   * handOut(completer.future);
+   * later: {
+   *   completer.complete('completion value');
+   * }
+   * ```
+   */
+  factory Completer() => new _AsyncCompleter<T>();
+
+  /**
+   * Completes the future synchronously.
+   *
+   * This constructor should be avoided unless the completion of the future is
+   * known to be the final result of another asynchronous operation. If in doubt
+   * use the default [Completer] constructor.
+   *
+   * Using an normal, asynchronous, completer will never give the wrong
+   * behavior, but using a synchronous completer incorrectly can cause
+   * otherwise correct programs to break.
+   *
+   * A synchronous completer is only intended for optimizing event
+   * propagation when one asynchronous event immediately triggers another.
+   * It should not be used unless the calls to [complete] and [completeError]
+   * are guaranteed to occur in places where it won't break `Future` invariants.
+   *
+   * Completing synchronously means that the completer's future will be
+   * completed immediately when calling the [complete] or [completeError]
+   * method on a synchronous completer, which also calls any callbacks
+   * registered on that future.
+   *
+   * Completing synchronously must not break the rule that when you add a
+   * callback on a future, that callback must not be called until the code
+   * that added the callback has completed.
+   * For that reason, a synchronous completion must only occur at the very end
+   * (in "tail position") of another synchronous event,
+   * because at that point, completing the future immediately is be equivalent
+   * to returning to the event loop and completing the future in the next
+   * microtask.
+   *
+   * Example:
+   *
+   *     var completer = new Completer.sync();
+   *     // The completion is the result of the asynchronous onDone event.
+   *     // No other operation is performed after the completion. It is safe
+   *     // to use the Completer.sync constructor.
+   *     stream.listen(print, onDone: () { completer.complete("done"); });
+   *
+   * Bad example. Do not use this code. Only for illustrative purposes:
+   *
+   *     var completer = new Completer.sync();
+   *     completer.future.then((_) { bar(); });
+   *     // The completion is the result of the asynchronous onDone event.
+   *     // However, there is still code executed after the completion. This
+   *     // operation is *not* safe.
+   *     stream.listen(print, onDone: () {
+   *       completer.complete("done");
+   *       foo();  // In this case, foo() runs after bar().
+   *     });
+   */
+  factory Completer.sync() => new _SyncCompleter<T>();
+
+  /**
+   * The future that is completed by this completer.
+   *
+   * The future that is completed when [complete] or [completeError] is called.
+   */
+  Future<T> get future;
+
+  /**
+   * Completes [future] with the supplied values.
+   *
+   * The value must be either a value of type [T]
+   * or a future of type `Future<T>`.
+   *
+   * If the value is itself a future, the completer will wait for that future
+   * to complete, and complete with the same result, whether it is a success
+   * or an error.
+   *
+   * Calling [complete] or [completeError] must be done at most once.
+   *
+   * All listeners on the future are informed about the value.
+   */
+  void complete([FutureOr<T> value]);
+
+  /**
+   * Complete [future] with an error.
+   *
+   * Calling [complete] or [completeError] must be done at most once.
+   *
+   * Completing a future with an error indicates that an exception was thrown
+   * while trying to produce a value.
+   *
+   * If [error] is `null`, it is replaced by a [NullThrownError].
+   *
+   * If `error` is a `Future`, the future itself is used as the error value.
+   * If you want to complete with the result of the future, you can use:
+   * ```
+   * thisCompleter.complete(theFuture)
+   * ```
+   * or if you only want to handle an error from the future:
+   * ```
+   * theFuture.catchError(thisCompleter.completeError);
+   * ```
+   */
+  void completeError(Object error, [StackTrace stackTrace]);
+
+  /**
+   * Whether the [future] has been completed.
+   *
+   * Reflects whether [complete] or [completeError] has been called.
+   * A `true` value doesn't necessarily mean that listeners of this future
+   * have been invoked yet, either because the completer usually waits until
+   * a later microtask to propagate the result, or because [complete]
+   * was called with a future that hasn't completed yet.
+   *
+   * When this value is `true`, [complete] and [completeError] must not be
+   * called again.
+   */
+  bool get isCompleted;
+}
+
+// Helper function completing a _Future with error, but checking the zone
+// for error replacement first.
+void _completeWithErrorCallback(_Future result, error, StackTrace stackTrace) {
+  AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
+  if (replacement != null) {
+    error = _nonNullError(replacement.error);
+    stackTrace = replacement.stackTrace;
+  }
+  result._completeError(error, stackTrace);
+}
+
+// Like [_completeWithErrorCallback] but completes asynchronously.
+void _asyncCompleteWithErrorCallback(
+    _Future result, error, StackTrace stackTrace) {
+  AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
+  if (replacement != null) {
+    error = _nonNullError(replacement.error);
+    stackTrace = replacement.stackTrace;
+  }
+  result._asyncCompleteError(error, stackTrace);
+}
+
+/** Helper function that converts `null` to a [NullThrownError]. */
+Object _nonNullError(Object error) => error ?? new NullThrownError();
diff --git a/sdk_nnbd/lib/async/future_impl.dart b/sdk_nnbd/lib/async/future_impl.dart
new file mode 100644
index 0000000..1ec0791
--- /dev/null
+++ b/sdk_nnbd/lib/async/future_impl.dart
@@ -0,0 +1,812 @@
+// Copyright (c) 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 dart.async;
+
+/** The onValue and onError handlers return either a value or a future */
+typedef FutureOr<T> _FutureOnValue<S, T>(S value);
+/** Test used by [Future.catchError] to handle skip some errors. */
+typedef bool _FutureErrorTest(Object error);
+/** Used by [WhenFuture]. */
+typedef dynamic _FutureAction();
+
+abstract class _Completer<T> implements Completer<T> {
+  final _Future<T> future = new _Future<T>();
+
+  void complete([FutureOr<T> value]);
+
+  void completeError(Object error, [StackTrace stackTrace]) {
+    error = _nonNullError(error);
+    if (!future._mayComplete) throw new StateError("Future already completed");
+    AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
+    if (replacement != null) {
+      error = _nonNullError(replacement.error);
+      stackTrace = replacement.stackTrace;
+    }
+    _completeError(error, stackTrace);
+  }
+
+  void _completeError(Object error, StackTrace stackTrace);
+
+  // The future's _isComplete doesn't take into account pending completions.
+  // We therefore use _mayComplete.
+  bool get isCompleted => !future._mayComplete;
+}
+
+class _AsyncCompleter<T> extends _Completer<T> {
+  void complete([FutureOr<T> value]) {
+    if (!future._mayComplete) throw new StateError("Future already completed");
+    future._asyncComplete(value);
+  }
+
+  void _completeError(Object error, StackTrace stackTrace) {
+    future._asyncCompleteError(error, stackTrace);
+  }
+}
+
+class _SyncCompleter<T> extends _Completer<T> {
+  void complete([FutureOr<T> value]) {
+    if (!future._mayComplete) throw new StateError("Future already completed");
+    future._complete(value);
+  }
+
+  void _completeError(Object error, StackTrace stackTrace) {
+    future._completeError(error, stackTrace);
+  }
+}
+
+class _FutureListener<S, T> {
+  static const int maskValue = 1;
+  static const int maskError = 2;
+  static const int maskTestError = 4;
+  static const int maskWhencomplete = 8;
+  static const int stateChain = 0;
+  static const int stateThen = maskValue;
+  static const int stateThenOnerror = maskValue | maskError;
+  static const int stateCatcherror = maskError;
+  static const int stateCatcherrorTest = maskError | maskTestError;
+  static const int stateWhencomplete = maskWhencomplete;
+  static const int maskType =
+      maskValue | maskError | maskTestError | maskWhencomplete;
+  static const int stateIsAwait = 16;
+  // Listeners on the same future are linked through this link.
+  _FutureListener _nextListener;
+  // The future to complete when this listener is activated.
+  final _Future<T> result;
+  // Which fields means what.
+  final int state;
+  // Used for then/whenDone callback and error test
+  final Function callback;
+  // Used for error callbacks.
+  final Function errorCallback;
+
+  _FutureListener.then(
+      this.result, _FutureOnValue<S, T> onValue, Function errorCallback)
+      : callback = onValue,
+        errorCallback = errorCallback,
+        state = (errorCallback == null) ? stateThen : stateThenOnerror;
+
+  _FutureListener.thenAwait(
+      this.result, _FutureOnValue<S, T> onValue, Function errorCallback)
+      : callback = onValue,
+        errorCallback = errorCallback,
+        state = ((errorCallback == null) ? stateThen : stateThenOnerror)
+              | stateIsAwait ;
+
+  _FutureListener.catchError(this.result, this.errorCallback, this.callback)
+      : state = (callback == null) ? stateCatcherror : stateCatcherrorTest;
+
+  _FutureListener.whenComplete(this.result, this.callback)
+      : errorCallback = null,
+        state = stateWhencomplete;
+
+  Zone get _zone => result._zone;
+
+  bool get handlesValue => (state & maskValue != 0);
+  bool get handlesError => (state & maskError != 0);
+  bool get hasErrorTest => (state & maskType == stateCatcherrorTest);
+  bool get handlesComplete => (state & maskType == stateWhencomplete);
+  bool get isAwait => (state & stateIsAwait != 0);
+
+  _FutureOnValue<S, T> get _onValue {
+    assert(handlesValue);
+    return callback;
+  }
+
+  Function get _onError => errorCallback;
+  _FutureErrorTest get _errorTest {
+    assert(hasErrorTest);
+    return callback;
+  }
+
+  _FutureAction get _whenCompleteAction {
+    assert(handlesComplete);
+    return callback;
+  }
+
+  /// Whether this listener has an error callback.
+  ///
+  /// This function must only be called if the listener [handlesError].
+  bool get hasErrorCallback {
+    assert(handlesError);
+    return _onError != null;
+  }
+
+  FutureOr<T> handleValue(S sourceResult) {
+    return _zone.runUnary<FutureOr<T>, S>(_onValue, sourceResult);
+  }
+
+  bool matchesErrorTest(AsyncError asyncError) {
+    if (!hasErrorTest) return true;
+    return _zone.runUnary<bool, Object>(_errorTest, asyncError.error);
+  }
+
+  FutureOr<T> handleError(AsyncError asyncError) {
+    assert(handlesError && hasErrorCallback);
+    var errorCallback = this.errorCallback; // To enable promotion.
+    // If the errorCallback returns something which is not a FutureOr<T>,
+    // this return statement throws, and the caller handles the error.
+    if (errorCallback is dynamic Function(Object, StackTrace)) {
+      return _zone.runBinary<dynamic, Object, StackTrace>(
+          errorCallback, asyncError.error, asyncError.stackTrace);
+    } else {
+      assert(errorCallback is dynamic Function(Object));
+      return _zone.runUnary<dynamic, Object>(errorCallback, asyncError.error);
+    }
+  }
+
+  dynamic handleWhenComplete() {
+    assert(!handlesError);
+    return _zone.run(_whenCompleteAction);
+  }
+}
+
+class _Future<T> implements Future<T> {
+  /// Initial state, waiting for a result. In this state, the
+  /// [resultOrListeners] field holds a single-linked list of
+  /// [_FutureListener] listeners.
+  static const int _stateIncomplete = 0;
+
+  /// Pending completion. Set when completed using [_asyncComplete] or
+  /// [_asyncCompleteError]. It is an error to try to complete it again.
+  /// [resultOrListeners] holds listeners.
+  static const int _statePendingComplete = 1;
+
+  /// The future has been chained to another future. The result of that
+  /// other future becomes the result of this future as well.
+  /// [resultOrListeners] contains the source future.
+  static const int _stateChained = 2;
+
+  /// The future has been completed with a value result.
+  static const int _stateValue = 4;
+
+  /// The future has been completed with an error result.
+  static const int _stateError = 8;
+
+  /** Whether the future is complete, and as what. */
+  int _state = _stateIncomplete;
+
+  /**
+   * Zone that the future was completed from.
+   * This is the zone that an error result belongs to.
+   *
+   * Until the future is completed, the field may hold the zone that
+   * listener callbacks used to create this future should be run in.
+   */
+  final Zone _zone;
+
+  /**
+   * Either the result, a list of listeners or another future.
+   *
+   * The result of the future is either a value or an error.
+   * A result is only stored when the future has completed.
+   *
+   * The listeners is an internally linked list of [_FutureListener]s.
+   * Listeners are only remembered while the future is not yet complete,
+   * and it is not chained to another future.
+   *
+   * The future is another future that his future is chained to. This future
+   * is waiting for the other future to complete, and when it does, this future
+   * will complete with the same result.
+   * All listeners are forwarded to the other future.
+   */
+  var _resultOrListeners;
+
+  // This constructor is used by async/await.
+  _Future() : _zone = Zone.current;
+
+  _Future.immediate(FutureOr<T> result) : _zone = Zone.current {
+    _asyncComplete(result);
+  }
+
+  /** Creates a future with the value and the specified zone. */
+  _Future.zoneValue(T value, this._zone) {
+    _setValue(value);
+  }
+
+  _Future.immediateError(var error, [StackTrace stackTrace])
+      : _zone = Zone.current {
+    _asyncCompleteError(error, stackTrace);
+  }
+
+  /** Creates a future that is already completed with the value. */
+  _Future.value(T value) : this.zoneValue(value, Zone.current);
+
+  bool get _mayComplete => _state == _stateIncomplete;
+  bool get _isPendingComplete => _state == _statePendingComplete;
+  bool get _mayAddListener => _state <= _statePendingComplete;
+  bool get _isChained => _state == _stateChained;
+  bool get _isComplete => _state >= _stateValue;
+  bool get _hasError => _state == _stateError;
+
+  static List<Function> _continuationFunctions(_Future<Object> future) {
+    List<Function> result = null;
+    while (true) {
+      if (future._mayAddListener) return result;
+      assert(!future._isComplete);
+      assert(!future._isChained);
+      // So _resultOrListeners contains listeners.
+      _FutureListener<Object, Object> listener = future._resultOrListeners;
+      if (listener != null &&
+          listener._nextListener == null &&
+          listener.isAwait) {
+        (result ??= <Function>[]).add(listener.handleValue);
+        future = listener.result;
+        assert(!future._isComplete);
+      } else {
+        break;
+      }
+    }
+    return result;
+  }
+
+  void _setChained(_Future source) {
+    assert(_mayAddListener);
+    _state = _stateChained;
+    _resultOrListeners = source;
+  }
+
+  Future<R> then<R>(FutureOr<R> f(T value), {Function onError}) {
+    Zone currentZone = Zone.current;
+    if (!identical(currentZone, _rootZone)) {
+      f = currentZone.registerUnaryCallback<FutureOr<R>, T>(f);
+      if (onError != null) {
+        // In checked mode, this checks that onError is assignable to one of:
+        //   dynamic Function(Object)
+        //   dynamic Function(Object, StackTrace)
+        onError = _registerErrorHandler(onError, currentZone);
+      }
+    }
+    _Future<R> result = new _Future<R>();
+    _addListener(new _FutureListener<T, R>.then(result, f, onError));
+    return result;
+  }
+
+  /// Registers a system created result and error continuation.
+  ///
+  /// Used by the implementation of `await` to listen to a future.
+  /// The system created liseners are not registered in the zone,
+  /// and the listener is marked as being from an `await`.
+  /// This marker is used in [_continuationFunctions].
+  Future<E> _thenAwait<E>(
+      FutureOr<E> f(T value), Function onError) {
+    _Future<E> result = new _Future<E>();
+    _addListener(new _FutureListener<T, E>.thenAwait(result, f, onError));
+    return result;
+  }
+
+  Future<T> catchError(Function onError, {bool test(error)}) {
+    _Future<T> result = new _Future<T>();
+    if (!identical(result._zone, _rootZone)) {
+      onError = _registerErrorHandler(onError, result._zone);
+      if (test != null) test = result._zone.registerUnaryCallback(test);
+    }
+    _addListener(new _FutureListener<T, T>.catchError(result, onError, test));
+    return result;
+  }
+
+  Future<T> whenComplete(dynamic action()) {
+    _Future<T> result = new _Future<T>();
+    if (!identical(result._zone, _rootZone)) {
+      action = result._zone.registerCallback<dynamic>(action);
+    }
+    _addListener(new _FutureListener<T, T>.whenComplete(result, action));
+    return result;
+  }
+
+  Stream<T> asStream() => new Stream<T>.fromFuture(this);
+
+  void _setPendingComplete() {
+    assert(_mayComplete);
+    _state = _statePendingComplete;
+  }
+
+  void _clearPendingComplete() {
+    assert(_isPendingComplete);
+    _state = _stateIncomplete;
+  }
+
+  AsyncError get _error {
+    assert(_hasError);
+    return _resultOrListeners;
+  }
+
+  _Future get _chainSource {
+    assert(_isChained);
+    return _resultOrListeners;
+  }
+
+  // This method is used by async/await.
+  void _setValue(T value) {
+    assert(!_isComplete); // But may have a completion pending.
+    _state = _stateValue;
+    _resultOrListeners = value;
+  }
+
+  void _setErrorObject(AsyncError error) {
+    assert(!_isComplete); // But may have a completion pending.
+    _state = _stateError;
+    _resultOrListeners = error;
+  }
+
+  void _setError(Object error, StackTrace stackTrace) {
+    _setErrorObject(new AsyncError(error, stackTrace));
+  }
+
+  /// Copy the completion result of [source] into this future.
+  ///
+  /// Used when a chained future notices that its source is completed.
+  void _cloneResult(_Future source) {
+    assert(!_isComplete);
+    assert(source._isComplete);
+    _state = source._state;
+    _resultOrListeners = source._resultOrListeners;
+  }
+
+  void _addListener(_FutureListener listener) {
+    assert(listener._nextListener == null);
+    if (_mayAddListener) {
+      listener._nextListener = _resultOrListeners;
+      _resultOrListeners = listener;
+    } else {
+      if (_isChained) {
+        // Delegate listeners to chained source future.
+        // If the source is complete, instead copy its values and
+        // drop the chaining.
+        _Future source = _chainSource;
+        if (!source._isComplete) {
+          source._addListener(listener);
+          return;
+        }
+        _cloneResult(source);
+      }
+      assert(_isComplete);
+      // Handle late listeners asynchronously.
+      _zone.scheduleMicrotask(() {
+        _propagateToListeners(this, listener);
+      });
+    }
+  }
+
+  void _prependListeners(_FutureListener listeners) {
+    if (listeners == null) return;
+    if (_mayAddListener) {
+      _FutureListener existingListeners = _resultOrListeners;
+      _resultOrListeners = listeners;
+      if (existingListeners != null) {
+        _FutureListener cursor = listeners;
+        while (cursor._nextListener != null) {
+          cursor = cursor._nextListener;
+        }
+        cursor._nextListener = existingListeners;
+      }
+    } else {
+      if (_isChained) {
+        // Delegate listeners to chained source future.
+        // If the source is complete, instead copy its values and
+        // drop the chaining.
+        _Future source = _chainSource;
+        if (!source._isComplete) {
+          source._prependListeners(listeners);
+          return;
+        }
+        _cloneResult(source);
+      }
+      assert(_isComplete);
+      listeners = _reverseListeners(listeners);
+      _zone.scheduleMicrotask(() {
+        _propagateToListeners(this, listeners);
+      });
+    }
+  }
+
+  _FutureListener _removeListeners() {
+    // Reverse listeners before returning them, so the resulting list is in
+    // subscription order.
+    assert(!_isComplete);
+    _FutureListener current = _resultOrListeners;
+    _resultOrListeners = null;
+    return _reverseListeners(current);
+  }
+
+  _FutureListener _reverseListeners(_FutureListener listeners) {
+    _FutureListener prev;
+    _FutureListener current = listeners;
+    while (current != null) {
+      _FutureListener next = current._nextListener;
+      current._nextListener = prev;
+      prev = current;
+      current = next;
+    }
+    return prev;
+  }
+
+  // Take the value (when completed) of source and complete target with that
+  // value (or error). This function could chain all Futures, but is slower
+  // for _Future than _chainCoreFuture, so you must use _chainCoreFuture
+  // in that case.
+  static void _chainForeignFuture(Future source, _Future target) {
+    assert(!target._isComplete);
+    assert(source is! _Future);
+
+    // Mark the target as chained (and as such half-completed).
+    target._setPendingComplete();
+    try {
+      source.then((value) {
+        assert(target._isPendingComplete);
+        // The "value" may be another future if the foreign future
+        // implementation is mis-behaving,
+        // so use _complete instead of _completeWithValue.
+        target._clearPendingComplete(); // Clear this first, it's set again.
+        target._complete(value);
+      },
+          // TODO(floitsch): eventually we would like to make this non-optional
+          // and dependent on the listeners of the target future. If none of
+          // the target future's listeners want to have the stack trace we don't
+          // need a trace.
+          onError: (error, [StackTrace stackTrace]) {
+        assert(target._isPendingComplete);
+        target._completeError(error, stackTrace);
+      });
+    } catch (e, s) {
+      // This only happens if the `then` call threw synchronously when given
+      // valid arguments.
+      // That requires a non-conforming implementation of the Future interface,
+      // which should, hopefully, never happen.
+      scheduleMicrotask(() {
+        target._completeError(e, s);
+      });
+    }
+  }
+
+  // Take the value (when completed) of source and complete target with that
+  // value (or error). This function expects that source is a _Future.
+  static void _chainCoreFuture(_Future source, _Future target) {
+    assert(target._mayAddListener); // Not completed, not already chained.
+    while (source._isChained) {
+      source = source._chainSource;
+    }
+    if (source._isComplete) {
+      _FutureListener listeners = target._removeListeners();
+      target._cloneResult(source);
+      _propagateToListeners(target, listeners);
+    } else {
+      _FutureListener listeners = target._resultOrListeners;
+      target._setChained(source);
+      source._prependListeners(listeners);
+    }
+  }
+
+  void _complete(FutureOr<T> value) {
+    assert(!_isComplete);
+    if (value is Future<T>) {
+      if (value is _Future<T>) {
+        _chainCoreFuture(value, this);
+      } else {
+        _chainForeignFuture(value, this);
+      }
+    } else {
+      _FutureListener listeners = _removeListeners();
+      _setValue(value);
+      _propagateToListeners(this, listeners);
+    }
+  }
+
+  void _completeWithValue(T value) {
+    assert(!_isComplete);
+    assert(value is! Future<T>);
+
+    _FutureListener listeners = _removeListeners();
+    _setValue(value);
+    _propagateToListeners(this, listeners);
+  }
+
+  void _completeError(Object error, [StackTrace stackTrace]) {
+    assert(!_isComplete);
+
+    _FutureListener listeners = _removeListeners();
+    _setError(error, stackTrace);
+    _propagateToListeners(this, listeners);
+  }
+
+  void _asyncComplete(FutureOr<T> value) {
+    assert(!_isComplete);
+    // Two corner cases if the value is a future:
+    //   1. the future is already completed and an error.
+    //   2. the future is not yet completed but might become an error.
+    // The first case means that we must not immediately complete the Future,
+    // as our code would immediately start propagating the error without
+    // giving the time to install error-handlers.
+    // However the second case requires us to deal with the value immediately.
+    // Otherwise the value could complete with an error and report an
+    // unhandled error, even though we know we are already going to listen to
+    // it.
+
+    if (value is Future<T>) {
+      _chainFuture(value);
+      return;
+    }
+    _setPendingComplete();
+    _zone.scheduleMicrotask(() {
+      _completeWithValue(value);
+    });
+  }
+
+  void _chainFuture(Future<T> value) {
+    if (value is _Future<T>) {
+      if (value._hasError) {
+        // Delay completion to allow the user to register callbacks.
+        _setPendingComplete();
+        _zone.scheduleMicrotask(() {
+          _chainCoreFuture(value, this);
+        });
+      } else {
+        _chainCoreFuture(value, this);
+      }
+      return;
+    }
+    // Just listen on the foreign future. This guarantees an async delay.
+    _chainForeignFuture(value, this);
+  }
+
+  void _asyncCompleteError(error, StackTrace stackTrace) {
+    assert(!_isComplete);
+
+    _setPendingComplete();
+    _zone.scheduleMicrotask(() {
+      _completeError(error, stackTrace);
+    });
+  }
+
+  /**
+   * Propagates the value/error of [source] to its [listeners], executing the
+   * listeners' callbacks.
+   */
+  static void _propagateToListeners(_Future source, _FutureListener listeners) {
+    while (true) {
+      assert(source._isComplete);
+      bool hasError = source._hasError;
+      if (listeners == null) {
+        if (hasError) {
+          AsyncError asyncError = source._error;
+          source._zone
+              .handleUncaughtError(asyncError.error, asyncError.stackTrace);
+        }
+        return;
+      }
+      // Usually futures only have one listener. If they have several, we
+      // call handle them separately in recursive calls, continuing
+      // here only when there is only one listener left.
+      while (listeners._nextListener != null) {
+        _FutureListener listener = listeners;
+        listeners = listener._nextListener;
+        listener._nextListener = null;
+        _propagateToListeners(source, listener);
+      }
+      _FutureListener listener = listeners;
+      final sourceResult = source._resultOrListeners;
+      // Do the actual propagation.
+      // Set initial state of listenerHasError and listenerValueOrError. These
+      // variables are updated with the outcome of potential callbacks.
+      // Non-error results, including futures, are stored in
+      // listenerValueOrError and listenerHasError is set to false. Errors
+      // are stored in listenerValueOrError as an [AsyncError] and
+      // listenerHasError is set to true.
+      bool listenerHasError = hasError;
+      var listenerValueOrError = sourceResult;
+
+      // Only if we either have an error or callbacks, go into this, somewhat
+      // expensive, branch. Here we'll enter/leave the zone. Many futures
+      // don't have callbacks, so this is a significant optimization.
+      if (hasError || listener.handlesValue || listener.handlesComplete) {
+        Zone zone = listener._zone;
+        if (hasError && !source._zone.inSameErrorZone(zone)) {
+          // Don't cross zone boundaries with errors.
+          AsyncError asyncError = source._error;
+          source._zone
+              .handleUncaughtError(asyncError.error, asyncError.stackTrace);
+          return;
+        }
+
+        Zone oldZone;
+        if (!identical(Zone.current, zone)) {
+          // Change zone if it's not current.
+          oldZone = Zone._enter(zone);
+        }
+
+        // These callbacks are abstracted to isolate the try/catch blocks
+        // from the rest of the code to work around a V8 glass jaw.
+        void handleWhenCompleteCallback() {
+          // The whenComplete-handler is not combined with normal value/error
+          // handling. This means at most one handleX method is called per
+          // listener.
+          assert(!listener.handlesValue);
+          assert(!listener.handlesError);
+          var completeResult;
+          try {
+            completeResult = listener.handleWhenComplete();
+          } catch (e, s) {
+            if (hasError && identical(source._error.error, e)) {
+              listenerValueOrError = source._error;
+            } else {
+              listenerValueOrError = new AsyncError(e, s);
+            }
+            listenerHasError = true;
+            return;
+          }
+          if (completeResult is Future) {
+            if (completeResult is _Future && completeResult._isComplete) {
+              if (completeResult._hasError) {
+                listenerValueOrError = completeResult._error;
+                listenerHasError = true;
+              }
+              // Otherwise use the existing result of source.
+              return;
+            }
+            // We have to wait for the completeResult future to complete
+            // before knowing if it's an error or we should use the result
+            // of source.
+            var originalSource = source;
+            listenerValueOrError = completeResult.then((_) => originalSource);
+            listenerHasError = false;
+          }
+        }
+
+        void handleValueCallback() {
+          try {
+            listenerValueOrError = listener.handleValue(sourceResult);
+          } catch (e, s) {
+            listenerValueOrError = new AsyncError(e, s);
+            listenerHasError = true;
+          }
+        }
+
+        void handleError() {
+          try {
+            AsyncError asyncError = source._error;
+            if (listener.matchesErrorTest(asyncError) &&
+                listener.hasErrorCallback) {
+              listenerValueOrError = listener.handleError(asyncError);
+              listenerHasError = false;
+            }
+          } catch (e, s) {
+            if (identical(source._error.error, e)) {
+              listenerValueOrError = source._error;
+            } else {
+              listenerValueOrError = new AsyncError(e, s);
+            }
+            listenerHasError = true;
+          }
+        }
+
+        if (listener.handlesComplete) {
+          handleWhenCompleteCallback();
+        } else if (!hasError) {
+          if (listener.handlesValue) {
+            handleValueCallback();
+          }
+        } else {
+          if (listener.handlesError) {
+            handleError();
+          }
+        }
+
+        // If we changed zone, oldZone will not be null.
+        if (oldZone != null) Zone._leave(oldZone);
+
+        // If the listener's value is a future we need to chain it. Note that
+        // this can only happen if there is a callback.
+        if (listenerValueOrError is Future) {
+          Future chainSource = listenerValueOrError;
+          // Shortcut if the chain-source is already completed. Just continue
+          // the loop.
+          _Future result = listener.result;
+          if (chainSource is _Future) {
+            if (chainSource._isComplete) {
+              listeners = result._removeListeners();
+              result._cloneResult(chainSource);
+              source = chainSource;
+              continue;
+            } else {
+              _chainCoreFuture(chainSource, result);
+            }
+          } else {
+            _chainForeignFuture(chainSource, result);
+          }
+          return;
+        }
+      }
+      _Future result = listener.result;
+      listeners = result._removeListeners();
+      if (!listenerHasError) {
+        result._setValue(listenerValueOrError);
+      } else {
+        AsyncError asyncError = listenerValueOrError;
+        result._setErrorObject(asyncError);
+      }
+      // Prepare for next round.
+      source = result;
+    }
+  }
+
+  Future<T> timeout(Duration timeLimit, {FutureOr<T> onTimeout()}) {
+    if (_isComplete) return new _Future.immediate(this);
+    _Future<T> result = new _Future<T>();
+    Timer timer;
+    if (onTimeout == null) {
+      timer = new Timer(timeLimit, () {
+        result._completeError(
+            new TimeoutException("Future not completed", timeLimit));
+      });
+    } else {
+      Zone zone = Zone.current;
+      onTimeout = zone.registerCallback(onTimeout);
+      timer = new Timer(timeLimit, () {
+        try {
+          result._complete(zone.run(onTimeout));
+        } catch (e, s) {
+          result._completeError(e, s);
+        }
+      });
+    }
+    this.then((T v) {
+      if (timer.isActive) {
+        timer.cancel();
+        result._completeWithValue(v);
+      }
+    }, onError: (e, StackTrace s) {
+      if (timer.isActive) {
+        timer.cancel();
+        result._completeError(e, s);
+      }
+    });
+    return result;
+  }
+}
+
+/// Registers errorHandler in zone if it has the correct type.
+///
+/// Checks that the function accepts either an [Object] and a [StackTrace]
+/// or just one [Object]. Does not check the return type.
+/// The actually returned value must be `FutureOr<R>` where `R` is the
+/// value type of the future that the call will complete (either returned
+/// by [Future.then] or [Future.catchError]). We check the returned value
+/// dynamically because the functions are passed as arguments in positions
+/// without inference, so a function expression won't infer the return type.
+///
+/// Throws if the type is not valid.
+Function _registerErrorHandler(Function errorHandler, Zone zone) {
+  if (errorHandler is dynamic Function(Object, StackTrace)) {
+    return zone
+        .registerBinaryCallback<dynamic, Object, StackTrace>(errorHandler);
+  }
+  if (errorHandler is dynamic Function(Object)) {
+    return zone.registerUnaryCallback<dynamic, Object>(errorHandler);
+  }
+  throw new ArgumentError.value(
+      errorHandler,
+      "onError",
+      "Error handler must accept one Object or one Object and a StackTrace"
+      " as arguments, and return a a valid result");
+}
diff --git a/sdk_nnbd/lib/async/schedule_microtask.dart b/sdk_nnbd/lib/async/schedule_microtask.dart
new file mode 100644
index 0000000..801490a
--- /dev/null
+++ b/sdk_nnbd/lib/async/schedule_microtask.dart
@@ -0,0 +1,153 @@
+// 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 dart.async;
+
+typedef void _AsyncCallback();
+
+class _AsyncCallbackEntry {
+  final _AsyncCallback callback;
+  _AsyncCallbackEntry next;
+  _AsyncCallbackEntry(this.callback);
+}
+
+/** Head of single linked list of pending callbacks. */
+_AsyncCallbackEntry _nextCallback;
+/** Tail of single linked list of pending callbacks. */
+_AsyncCallbackEntry _lastCallback;
+/**
+ * Tail of priority callbacks added by the currently executing callback.
+ *
+ * Priority callbacks are put at the beginning of the
+ * callback queue, so that if one callback schedules more than one
+ * priority callback, they are still enqueued in scheduling order.
+ */
+_AsyncCallbackEntry _lastPriorityCallback;
+/**
+ * Whether we are currently inside the callback loop.
+ *
+ * If we are inside the loop, we never need to schedule the loop,
+ * even if adding a first element.
+ */
+bool _isInCallbackLoop = false;
+
+void _microtaskLoop() {
+  while (_nextCallback != null) {
+    _lastPriorityCallback = null;
+    _AsyncCallbackEntry entry = _nextCallback;
+    _nextCallback = entry.next;
+    if (_nextCallback == null) _lastCallback = null;
+    (entry.callback)();
+  }
+}
+
+void _startMicrotaskLoop() {
+  _isInCallbackLoop = true;
+  try {
+    // Moved to separate function because try-finally prevents
+    // good optimization.
+    _microtaskLoop();
+  } finally {
+    _lastPriorityCallback = null;
+    _isInCallbackLoop = false;
+    if (_nextCallback != null) {
+      _AsyncRun._scheduleImmediate(_startMicrotaskLoop);
+    }
+  }
+}
+
+/**
+ * Schedules a callback to be called as a microtask.
+ *
+ * The microtask is called after all other currently scheduled
+ * microtasks, but as part of the current system event.
+ */
+void _scheduleAsyncCallback(_AsyncCallback callback) {
+  _AsyncCallbackEntry newEntry = new _AsyncCallbackEntry(callback);
+  if (_nextCallback == null) {
+    _nextCallback = _lastCallback = newEntry;
+    if (!_isInCallbackLoop) {
+      _AsyncRun._scheduleImmediate(_startMicrotaskLoop);
+    }
+  } else {
+    _lastCallback.next = newEntry;
+    _lastCallback = newEntry;
+  }
+}
+
+/**
+ * Schedules a callback to be called before all other currently scheduled ones.
+ *
+ * This callback takes priority over existing scheduled callbacks.
+ * It is only used internally to give higher priority to error reporting.
+ *
+ * Is always run in the root zone.
+ */
+void _schedulePriorityAsyncCallback(_AsyncCallback callback) {
+  if (_nextCallback == null) {
+    _scheduleAsyncCallback(callback);
+    _lastPriorityCallback = _lastCallback;
+    return;
+  }
+  _AsyncCallbackEntry entry = new _AsyncCallbackEntry(callback);
+  if (_lastPriorityCallback == null) {
+    entry.next = _nextCallback;
+    _nextCallback = _lastPriorityCallback = entry;
+  } else {
+    entry.next = _lastPriorityCallback.next;
+    _lastPriorityCallback.next = entry;
+    _lastPriorityCallback = entry;
+    if (entry.next == null) {
+      _lastCallback = entry;
+    }
+  }
+}
+
+/**
+ * Runs a function asynchronously.
+ *
+ * Callbacks registered through this function are always executed in order and
+ * are guaranteed to run before other asynchronous events (like [Timer] events,
+ * or DOM events).
+ *
+ * **Warning:** it is possible to starve the DOM by registering asynchronous
+ * callbacks through this method. For example the following program runs
+ * the callbacks without ever giving the Timer callback a chance to execute:
+ *
+ *     main() {
+ *       Timer.run(() { print("executed"); });  // Will never be executed.
+ *       foo() {
+ *         scheduleMicrotask(foo);  // Schedules [foo] in front of other events.
+ *       }
+ *       foo();
+ *     }
+ *
+ * ## Other resources
+ *
+ * * [The Event Loop and Dart](https://www.dartlang.org/articles/event-loop/):
+ * Learn how Dart handles the event queue and microtask queue, so you can write
+ * better asynchronous code with fewer surprises.
+ */
+void scheduleMicrotask(void callback()) {
+  _Zone currentZone = Zone.current;
+  if (identical(_rootZone, currentZone)) {
+    // No need to bind the callback. We know that the root's scheduleMicrotask
+    // will be invoked in the root zone.
+    _rootScheduleMicrotask(null, null, _rootZone, callback);
+    return;
+  }
+  _ZoneFunction implementation = currentZone._scheduleMicrotask;
+  if (identical(_rootZone, implementation.zone) &&
+      _rootZone.inSameErrorZone(currentZone)) {
+    _rootScheduleMicrotask(
+        null, null, currentZone, currentZone.registerCallback(callback));
+    return;
+  }
+  Zone.current.scheduleMicrotask(Zone.current.bindCallbackGuarded(callback));
+}
+
+class _AsyncRun {
+  /** Schedule the given callback before any other event in the event-loop. */
+  external static void _scheduleImmediate(void callback());
+}
diff --git a/sdk_nnbd/lib/async/stream.dart b/sdk_nnbd/lib/async/stream.dart
new file mode 100644
index 0000000..95a8b97
--- /dev/null
+++ b/sdk_nnbd/lib/async/stream.dart
@@ -0,0 +1,2267 @@
+// 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 dart.async;
+
+// -------------------------------------------------------------------
+// Core Stream types
+// -------------------------------------------------------------------
+
+typedef void _TimerCallback();
+
+/**
+ * A source of asynchronous data events.
+ *
+ * A Stream provides a way to receive a sequence of events.
+ * Each event is either a data event, also called an *element* of the stream,
+ * or an error event, which is a notification that something has failed.
+ * When a stream has emitted all its event,
+ * a single "done" event will notify the listener that the end has been reached.
+ *
+ * You [listen] on a stream to make it start generating events,
+ * and to set up listeners that receive the events.
+ * When you listen, you receive a [StreamSubscription] object
+ * which is the active object providing the events,
+ * and which can be used to stop listening again,
+ * or to temporarily pause events from the subscription.
+ *
+ * There are two kinds of streams: "Single-subscription" streams and
+ * "broadcast" streams.
+ *
+ * *A single-subscription stream* allows only a single listener during the whole
+ * lifetime of the stream.
+ * It doesn't start generating events until it has a listener,
+ * and it stops sending events when the listener is unsubscribed,
+ * even if the source of events could still provide more.
+ *
+ * Listening twice on a single-subscription stream is not allowed, even after
+ * the first subscription has been canceled.
+ *
+ * Single-subscription streams are generally used for streaming chunks of
+ * larger contiguous data like file I/O.
+ *
+ * *A broadcast stream* allows any number of listeners, and it fires
+ * its events when they are ready, whether there are listeners or not.
+ *
+ * Broadcast streams are used for independent events/observers.
+ *
+ * If several listeners want to listen to a single subscription stream,
+ * use [asBroadcastStream] to create a broadcast stream on top of the
+ * non-broadcast stream.
+ *
+ * On either kind of stream, stream transformations, such as [where] and
+ * [skip], return the same type of stream as the one the method was called on,
+ * unless otherwise noted.
+ *
+ * When an event is fired, the listener(s) at that time will receive the event.
+ * If a listener is added to a broadcast stream while an event is being fired,
+ * that listener will not receive the event currently being fired.
+ * If a listener is canceled, it immediately stops receiving events.
+ * Listening on a broadcast stream can be treated as listening on a new stream
+ * containing only the events that have not yet been emitted when the [listen]
+ * call occurs.
+ * For example, the [first] getter listens to the stream, then returns the first
+ * event that listener receives.
+ * This is not necessarily the first even emitted by the stream, but the first
+ * of the *remaining* events of the broadcast stream.
+ *
+ * When the "done" event is fired, subscribers are unsubscribed before
+ * receiving the event. After the event has been sent, the stream has no
+ * subscribers. Adding new subscribers to a broadcast stream after this point
+ * is allowed, but they will just receive a new "done" event as soon
+ * as possible.
+ *
+ * Stream subscriptions always respect "pause" requests. If necessary they need
+ * to buffer their input, but often, and preferably, they can simply request
+ * their input to pause too.
+ *
+ * The default implementation of [isBroadcast] returns false.
+ * A broadcast stream inheriting from [Stream] must override [isBroadcast]
+ * to return `true`.
+ */
+abstract class Stream<T> {
+  Stream();
+
+  /**
+   * Internal use only. We do not want to promise that Stream stays const.
+   *
+   * If mixins become compatible with const constructors, we may use a
+   * stream mixin instead of extending Stream from a const class.
+   */
+  const Stream._internal();
+
+  /**
+   * Creates an empty broadcast stream.
+   *
+   * This is a stream which does nothing except sending a done event
+   * when it's listened to.
+   */
+  const factory Stream.empty() = _EmptyStream<T>;
+
+  /**
+   * Creates a stream which emits a single data event before completing.
+   *
+   * This stream emits a single data event of [value]
+   * and then completes with a done event.
+   *
+   * Example:
+   * ```dart
+   * Future<void> printThings(Stream<String> data) async {
+   *   await for (var x in data) {
+   *     print(x);
+   *   }
+   * }
+   * printThings(Stream<String>.value("ok")); // prints "ok".
+   * ```
+   *
+   * The returned stream is effectively equivalent to one created by
+   * `(() async* { yield value; } ())` or `Future<T>.value(value).asStream()`.
+   */
+  @Since("2.5")
+  factory Stream.value(T value) =>
+      (_AsyncStreamController<T>(null, null, null, null)
+            .._add(value)
+            .._closeUnchecked())
+          .stream;
+
+  /**
+   * Creates a stream which emits a single error event before completing.
+   *
+   * This stream emits a single error event of [error] and [stackTrace]
+   * and then completes with a done event.
+   *
+   * Example:
+   * ```dart
+   * Future<void> tryThings(Stream<int> data) async {
+   *   try {
+   *     await for (var x in data) {
+   *       print("Data: $x");
+   *     }
+   *   } catch (e) {
+   *     print(e);
+   *   }
+   * }
+   * tryThings(Stream<int>.error("Error")); // prints "Error".
+   * ```
+   * The returned stream is effectively equivalent to one created by
+   * `Future<T>.error(error, stackTrace).asStream()`, by or
+   * `(() async* { throw error; } ())`, except that you can control the
+   * stack trace as well.
+   */
+  @Since("2.5")
+  factory Stream.error(Object error, [StackTrace stackTrace]) =>
+      (_AsyncStreamController<T>(null, null, null, null)
+            .._addError(error, stackTrace)
+            .._closeUnchecked())
+          .stream;
+
+  /**
+   * Creates a new single-subscription stream from the future.
+   *
+   * When the future completes, the stream will fire one event, either
+   * data or error, and then close with a done-event.
+   */
+  factory Stream.fromFuture(Future<T> future) {
+    // Use the controller's buffering to fill in the value even before
+    // the stream has a listener. For a single value, it's not worth it
+    // to wait for a listener before doing the `then` on the future.
+    _StreamController<T> controller =
+        new _SyncStreamController<T>(null, null, null, null);
+    future.then((value) {
+      controller._add(value);
+      controller._closeUnchecked();
+    }, onError: (error, stackTrace) {
+      controller._addError(error, stackTrace);
+      controller._closeUnchecked();
+    });
+    return controller.stream;
+  }
+
+  /**
+   * Create a stream from a group of futures.
+   *
+   * The stream reports the results of the futures on the stream in the order
+   * in which the futures complete.
+   * Each future provides either a data event or an error event,
+   * depending on how the future completes.
+   *
+   * If some futures have already completed when `Stream.fromFutures` is called,
+   * their results will be emitted in some unspecified order.
+   *
+   * When all futures have completed, the stream is closed.
+   *
+   * If [futures] is empty, the stream closes as soon as possible.
+   */
+  factory Stream.fromFutures(Iterable<Future<T>> futures) {
+    _StreamController<T> controller =
+        new _SyncStreamController<T>(null, null, null, null);
+    int count = 0;
+    // Declare these as variables holding closures instead of as
+    // function declarations.
+    // This avoids creating a new closure from the functions for each future.
+    var onValue = (T value) {
+      if (!controller.isClosed) {
+        controller._add(value);
+        if (--count == 0) controller._closeUnchecked();
+      }
+    };
+    var onError = (error, StackTrace stack) {
+      if (!controller.isClosed) {
+        controller._addError(error, stack);
+        if (--count == 0) controller._closeUnchecked();
+      }
+    };
+    // The futures are already running, so start listening to them immediately
+    // (instead of waiting for the stream to be listened on).
+    // If we wait, we might not catch errors in the futures in time.
+    for (var future in futures) {
+      count++;
+      future.then(onValue, onError: onError);
+    }
+    // Use schedule microtask since controller is sync.
+    if (count == 0) scheduleMicrotask(controller.close);
+    return controller.stream;
+  }
+
+  /**
+   * Creates a single-subscription stream that gets its data from [elements].
+   *
+   * The iterable is iterated when the stream receives a listener, and stops
+   * iterating if the listener cancels the subscription, or if the
+   * [Iterator.moveNext] method returns `false` or throws.
+   * Iteration is suspended while the stream subscription is paused.
+   *
+   * If calling [Iterator.moveNext] on `elements.iterator` throws,
+   * the stream emits that error and then it closes.
+   * If reading [Iterator.current] on `elements.iterator` throws,
+   * the stream emits that error, but keeps iterating.
+   */
+  factory Stream.fromIterable(Iterable<T> elements) {
+    return new _GeneratedStreamImpl<T>(
+        () => new _IterablePendingEvents<T>(elements));
+  }
+
+  /**
+   * Creates a stream that repeatedly emits events at [period] intervals.
+   *
+   * The event values are computed by invoking [computation]. The argument to
+   * this callback is an integer that starts with 0 and is incremented for
+   * every event.
+   *
+   * If [computation] is omitted the event values will all be `null`.
+   */
+  factory Stream.periodic(Duration period,
+      [T computation(int computationCount)]) {
+    Timer timer;
+    int computationCount = 0;
+    StreamController<T> controller;
+    // Counts the time that the Stream was running (and not paused).
+    Stopwatch watch = new Stopwatch();
+
+    void sendEvent() {
+      watch.reset();
+      T data;
+      if (computation != null) {
+        try {
+          data = computation(computationCount++);
+        } catch (e, s) {
+          controller.addError(e, s);
+          return;
+        }
+      }
+      controller.add(data);
+    }
+
+    void startPeriodicTimer() {
+      assert(timer == null);
+      timer = new Timer.periodic(period, (Timer timer) {
+        sendEvent();
+      });
+    }
+
+    controller = new StreamController<T>(
+        sync: true,
+        onListen: () {
+          watch.start();
+          startPeriodicTimer();
+        },
+        onPause: () {
+          timer.cancel();
+          timer = null;
+          watch.stop();
+        },
+        onResume: () {
+          assert(timer == null);
+          Duration elapsed = watch.elapsed;
+          watch.start();
+          timer = new Timer(period - elapsed, () {
+            timer = null;
+            startPeriodicTimer();
+            sendEvent();
+          });
+        },
+        onCancel: () {
+          if (timer != null) timer.cancel();
+          timer = null;
+          return Future._nullFuture;
+        });
+    return controller.stream;
+  }
+
+  /**
+   * Creates a stream where all events of an existing stream are piped through
+   * a sink-transformation.
+   *
+   * The given [mapSink] closure is invoked when the returned stream is
+   * listened to. All events from the [source] are added into the event sink
+   * that is returned from the invocation. The transformation puts all
+   * transformed events into the sink the [mapSink] closure received during
+   * its invocation. Conceptually the [mapSink] creates a transformation pipe
+   * with the input sink being the returned [EventSink] and the output sink
+   * being the sink it received.
+   *
+   * This constructor is frequently used to build transformers.
+   *
+   * Example use for a duplicating transformer:
+   *
+   *     class DuplicationSink implements EventSink<String> {
+   *       final EventSink<String> _outputSink;
+   *       DuplicationSink(this._outputSink);
+   *
+   *       void add(String data) {
+   *         _outputSink.add(data);
+   *         _outputSink.add(data);
+   *       }
+   *
+   *       void addError(e, [st]) { _outputSink.addError(e, st); }
+   *       void close() { _outputSink.close(); }
+   *     }
+   *
+   *     class DuplicationTransformer extends StreamTransformerBase<String, String> {
+   *       // Some generic types omitted for brevity.
+   *       Stream bind(Stream stream) => new Stream<String>.eventTransformed(
+   *           stream,
+   *           (EventSink sink) => new DuplicationSink(sink));
+   *     }
+   *
+   *     stringStream.transform(new DuplicationTransformer());
+   *
+   * The resulting stream is a broadcast stream if [source] is.
+   */
+  factory Stream.eventTransformed(
+      Stream source, EventSink mapSink(EventSink<T> sink)) {
+    return new _BoundSinkStream(source, mapSink);
+  }
+
+  /**
+   * Adapts [source] to be a `Stream<T>`.
+   *
+   * This allows [source] to be used at the new type, but at run-time it
+   * must satisfy the requirements of both the new type and its original type.
+   *
+   * Data events created by the source stream must also be instances of [T].
+   */
+  static Stream<T> castFrom<S, T>(Stream<S> source) =>
+      new CastStream<S, T>(source);
+
+  /**
+   * Whether this stream is a broadcast stream.
+   */
+  bool get isBroadcast => false;
+
+  /**
+   * Returns a multi-subscription stream that produces the same events as this.
+   *
+   * The returned stream will subscribe to this stream when its first
+   * subscriber is added, and will stay subscribed until this stream ends,
+   * or a callback cancels the subscription.
+   *
+   * If [onListen] is provided, it is called with a subscription-like object
+   * that represents the underlying subscription to this stream. It is
+   * possible to pause, resume or cancel the subscription during the call
+   * to [onListen]. It is not possible to change the event handlers, including
+   * using [StreamSubscription.asFuture].
+   *
+   * If [onCancel] is provided, it is called in a similar way to [onListen]
+   * when the returned stream stops having listener. If it later gets
+   * a new listener, the [onListen] function is called again.
+   *
+   * Use the callbacks, for example, for pausing the underlying subscription
+   * while having no subscribers to prevent losing events, or canceling the
+   * subscription when there are no listeners.
+   */
+  Stream<T> asBroadcastStream(
+      {void onListen(StreamSubscription<T> subscription),
+      void onCancel(StreamSubscription<T> subscription)}) {
+    return new _AsBroadcastStream<T>(this, onListen, onCancel);
+  }
+
+  /**
+   * Adds a subscription to this stream.
+   *
+   * Returns a [StreamSubscription] which handles events from this stream using
+   * the provided [onData], [onError] and [onDone] handlers.
+   * The handlers can be changed on the subscription, but they start out
+   * as the provided functions.
+   *
+   * On each data event from this stream, the subscriber's [onData] handler
+   * is called. If [onData] is `null`, nothing happens.
+   *
+   * On errors from this stream, the [onError] handler is called with the
+   * error object and possibly a stack trace.
+   *
+   * The [onError] callback must be of type `void onError(error)` or
+   * `void onError(error, StackTrace stackTrace)`. If [onError] accepts
+   * two arguments it is called with the error object and the stack trace
+   * (which could be `null` if this stream itself received an error without
+   * stack trace).
+   * Otherwise it is called with just the error object.
+   * If [onError] is omitted, any errors on this stream are considered unhandled,
+   * and will be passed to the current [Zone]'s error handler.
+   * By default unhandled async errors are treated
+   * as if they were uncaught top-level errors.
+   *
+   * If this stream closes and sends a done event, the [onDone] handler is
+   * called. If [onDone] is `null`, nothing happens.
+   *
+   * If [cancelOnError] is true, the subscription is automatically canceled
+   * when the first error event is delivered. The default is `false`.
+   *
+   * While a subscription is paused, or when it has been canceled,
+   * the subscription doesn't receive events and none of the
+   * event handler functions are called.
+   */
+  StreamSubscription<T> listen(void onData(T event),
+      {Function onError, void onDone(), bool cancelOnError});
+
+  /**
+   * Creates a new stream from this stream that discards some elements.
+   *
+   * The new stream sends the same error and done events as this stream,
+   * but it only sends the data events that satisfy the [test].
+   *
+   * If the [test] function throws, the data event is dropped and the
+   * error is emitted on the returned stream instead.
+   *
+   * The returned stream is a broadcast stream if this stream is.
+   * If a broadcast stream is listened to more than once, each subscription
+   * will individually perform the `test`.
+   */
+  Stream<T> where(bool test(T event)) {
+    return new _WhereStream<T>(this, test);
+  }
+
+  /**
+   * Transforms each element of this stream into a new stream event.
+   *
+   * Creates a new stream that converts each element of this stream
+   * to a new value using the [convert] function, and emits the result.
+   *
+   * For each data event, `o`, in this stream, the returned stream
+   * provides a data event with the value `convert(o)`.
+   * If [convert] throws, the returned stream reports it as an error
+   * event instead.
+   *
+   * Error and done events are passed through unchanged to the returned stream.
+   *
+   * The returned stream is a broadcast stream if this stream is.
+   * The [convert] function is called once per data event per listener.
+   * If a broadcast stream is listened to more than once, each subscription
+   * will individually call [convert] on each data event.
+   *
+   * Unlike [transform], this method does not treat the stream as
+   * chunks of a single value. Instead each event is converted independently
+   * of the previous and following events, which may not always be correct.
+   * For example, UTF-8 encoding, or decoding, will give wrong results
+   * if a surrogate pair, or a multibyte UTF-8 encoding, is split into
+   * separate events, and those events are attempted encoded or decoded
+   * independently.
+   */
+  Stream<S> map<S>(S convert(T event)) {
+    return new _MapStream<T, S>(this, convert);
+  }
+
+  /**
+   * Creates a new stream with each data event of this stream asynchronously
+   * mapped to a new event.
+   *
+   * This acts like [map], except that [convert] may return a [Future],
+   * and in that case, this stream waits for that future to complete before
+   * continuing with its result.
+   *
+   * The returned stream is a broadcast stream if this stream is.
+   */
+  Stream<E> asyncMap<E>(FutureOr<E> convert(T event)) {
+    _StreamControllerBase<E> controller;
+    StreamSubscription<T> subscription;
+
+    void onListen() {
+      final add = controller.add;
+      assert(controller is _StreamController<E> ||
+          controller is _BroadcastStreamController);
+      final addError = controller._addError;
+      subscription = this.listen((T event) {
+        FutureOr<E> newValue;
+        try {
+          newValue = convert(event);
+        } catch (e, s) {
+          controller.addError(e, s);
+          return;
+        }
+        if (newValue is Future<E>) {
+          subscription.pause();
+          newValue
+              .then(add, onError: addError)
+              .whenComplete(subscription.resume);
+        } else {
+          controller.add(newValue);
+        }
+      }, onError: addError, onDone: controller.close);
+    }
+
+    if (this.isBroadcast) {
+      controller = new StreamController<E>.broadcast(
+          onListen: onListen,
+          onCancel: () {
+            subscription.cancel();
+          },
+          sync: true);
+    } else {
+      controller = new StreamController<E>(
+          onListen: onListen,
+          onPause: () {
+            subscription.pause();
+          },
+          onResume: () {
+            subscription.resume();
+          },
+          onCancel: () => subscription.cancel(),
+          sync: true);
+    }
+    return controller.stream;
+  }
+
+  /**
+   * Transforms each element into a sequence of asynchronous events.
+   *
+   * Returns a new stream and for each event of this stream, do the following:
+   *
+   * * If the event is an error event or a done event, it is emitted directly
+   * by the returned stream.
+   * * Otherwise it is an element. Then the [convert] function is called
+   * with the element as argument to produce a convert-stream for the element.
+   * * If that call throws, the error is emitted on the returned stream.
+   * * If the call returns `null`, no further action is taken for the elements.
+   * * Otherwise, this stream is paused and convert-stream is listened to.
+   * Every data and error event of the convert-stream is emitted on the returned
+   * stream in the order it is produced.
+   * When the convert-stream ends, this stream is resumed.
+   *
+   * The returned stream is a broadcast stream if this stream is.
+   */
+  Stream<E> asyncExpand<E>(Stream<E> convert(T event)) {
+    _StreamControllerBase<E> controller;
+    StreamSubscription<T> subscription;
+    void onListen() {
+      assert(controller is _StreamController ||
+          controller is _BroadcastStreamController);
+      subscription = this.listen((T event) {
+        Stream<E> newStream;
+        try {
+          newStream = convert(event);
+        } catch (e, s) {
+          controller.addError(e, s);
+          return;
+        }
+        if (newStream != null) {
+          subscription.pause();
+          controller.addStream(newStream).whenComplete(subscription.resume);
+        }
+      },
+          onError: controller._addError, // Avoid Zone error replacement.
+          onDone: controller.close);
+    }
+
+    if (this.isBroadcast) {
+      controller = new StreamController<E>.broadcast(
+          onListen: onListen,
+          onCancel: () {
+            subscription.cancel();
+          },
+          sync: true);
+    } else {
+      controller = new StreamController<E>(
+          onListen: onListen,
+          onPause: () {
+            subscription.pause();
+          },
+          onResume: () {
+            subscription.resume();
+          },
+          onCancel: () => subscription.cancel(),
+          sync: true);
+    }
+    return controller.stream;
+  }
+
+  /**
+   * Creates a wrapper Stream that intercepts some errors from this stream.
+   *
+   * If this stream sends an error that matches [test], then it is intercepted
+   * by the [onError] function.
+   *
+   * The [onError] callback must be of type `void onError(error)` or
+   * `void onError(error, StackTrace stackTrace)`.
+   * The function type determines whether [onError] is invoked with a stack
+   * trace argument.
+   * The stack trace argument may be `null` if this stream received an error
+   * without a stack trace.
+   *
+   * An asynchronous error `error` is matched by a test function if
+   *`test(error)` returns true. If [test] is omitted, every error is considered
+   * matching.
+   *
+   * If the error is intercepted, the [onError] function can decide what to do
+   * with it. It can throw if it wants to raise a new (or the same) error,
+   * or simply return to make this stream forget the error.
+   * If the received `error` value is thrown again by the [onError] function,
+   * it acts like a `rethrow` and it is emitted along with its original
+   * stack trace, not the stack trace of the `throw` inside [onError].
+   *
+   * If you need to transform an error into a data event, use the more generic
+   * [Stream.transform] to handle the event by writing a data event to
+   * the output sink.
+   *
+   * The returned stream is a broadcast stream if this stream is.
+   * If a broadcast stream is listened to more than once, each subscription
+   * will individually perform the `test` and handle the error.
+   */
+  Stream<T> handleError(Function onError, {bool test(error)}) {
+    return new _HandleErrorStream<T>(this, onError, test);
+  }
+
+  /**
+   * Transforms each element of this stream into a sequence of elements.
+   *
+   * Returns a new stream where each element of this stream is replaced
+   * by zero or more data events.
+   * The event values are provided as an [Iterable] by a call to [convert]
+   * with the element as argument, and the elements of that iterable is
+   * emitted in iteration order.
+   * If calling [convert] throws, or if the iteration of the returned values
+   * throws, the error is emitted on the returned stream and iteration ends
+   * for that element of this stream.
+   *
+   * Error events and the done event of this stream are forwarded directly
+   * to the returned stream.
+   *
+   * The returned stream is a broadcast stream if this stream is.
+   * If a broadcast stream is listened to more than once, each subscription
+   * will individually call `convert` and expand the events.
+   */
+  Stream<S> expand<S>(Iterable<S> convert(T element)) {
+    return new _ExpandStream<T, S>(this, convert);
+  }
+
+  /**
+   * Pipes the events of this stream into [streamConsumer].
+   *
+   * All events of this stream are added to `streamConsumer` using
+   * [StreamConsumer.addStream].
+   * The `streamConsumer` is closed when this stream has been successfully added
+   * to it - when the future returned by `addStream` completes without an error.
+   *
+   * Returns a future which completes when this stream has been consumed
+   * and the consumer has been closed.
+   *
+   * The returned future completes with the same result as the future returned
+   * by [StreamConsumer.close].
+   * If the call to [StreamConsumer.addStream] fails in some way, this
+   * method fails in the same way.
+   */
+  Future pipe(StreamConsumer<T> streamConsumer) {
+    return streamConsumer.addStream(this).then((_) => streamConsumer.close());
+  }
+
+  /**
+   * Applies  [streamTransformer] to this stream.
+   *
+   * Returns the transformed stream,
+   * that is, the result of `streamTransformer.bind(this)`.
+   * This method simply allows writing the call to `streamTransformer.bind`
+   * in a chained fashion, like
+   * ```
+   * stream.map(mapping).transform(transformation).toList()
+   * ```
+   * which can be more convenient than calling `bind` directly.
+   *
+   * The [streamTransformer] can return any stream.
+   * Whether the returned stream is a broadcast stream or not,
+   * and which elements it will contain,
+   * is entirely up to the transformation.
+   *
+   * This method should always be used for transformations which treat
+   * the entire stream as representing a single value
+   * which has perhaps been split into several parts for transport,
+   * like a file being read from disk or being fetched over a network.
+   * The transformation will then produce a new stream which
+   * transforms the stream's value incrementally (perhaps using
+   * [Converter.startChunkedConversion]). The resulting stream
+   * may again be chunks of the result, but does not have to
+   * correspond to specific events from the source string.
+   */
+  Stream<S> transform<S>(StreamTransformer<T, S> streamTransformer) {
+    return streamTransformer.bind(this);
+  }
+
+  /**
+   * Combines a sequence of values by repeatedly applying [combine].
+   *
+   * Similar to [Iterable.reduce], this function maintains a value,
+   * starting with the first element of this stream
+   * and updated for each further element of this stream.
+   * For each element after the first,
+   * the value is updated to the result of calling [combine]
+   * with the previous value and the element.
+   *
+   * When this stream is done, the returned future is completed with
+   * the value at that time.
+   *
+   * If this stream is empty, the returned future is completed with
+   * an error.
+   * If this stream emits an error, or the call to [combine] throws,
+   * the returned future is completed with that error,
+   * and processing is stopped.
+   */
+  Future<T> reduce(T combine(T previous, T element)) {
+    _Future<T> result = new _Future<T>();
+    bool seenFirst = false;
+    T value;
+    StreamSubscription subscription;
+    subscription = this.listen(
+        (T element) {
+          if (seenFirst) {
+            _runUserCode(() => combine(value, element), (T newValue) {
+              value = newValue;
+            }, _cancelAndErrorClosure(subscription, result));
+          } else {
+            value = element;
+            seenFirst = true;
+          }
+        },
+        onError: result._completeError,
+        onDone: () {
+          if (!seenFirst) {
+            try {
+              // Throw and recatch, instead of just doing
+              //  _completeWithErrorCallback, e, theError, StackTrace.current),
+              // to ensure that the stackTrace is set on the error.
+              throw IterableElementError.noElement();
+            } catch (e, s) {
+              _completeWithErrorCallback(result, e, s);
+            }
+          } else {
+            result._complete(value);
+          }
+        },
+        cancelOnError: true);
+    return result;
+  }
+
+  /**
+   * Combines a sequence of values by repeatedly applying [combine].
+   *
+   * Similar to [Iterable.fold], this function maintains a value,
+   * starting with [initialValue] and updated for each element of
+   * this stream.
+   * For each element, the value is updated to the result of calling
+   * [combine] with the previous value and the element.
+   *
+   * When this stream is done, the returned future is completed with
+   * the value at that time.
+   * For an empty stream, the future is completed with [initialValue].
+   *
+   * If this stream emits an error, or the call to [combine] throws,
+   * the returned future is completed with that error,
+   * and processing is stopped.
+   */
+  Future<S> fold<S>(S initialValue, S combine(S previous, T element)) {
+    _Future<S> result = new _Future<S>();
+    S value = initialValue;
+    StreamSubscription subscription;
+    subscription = this.listen(
+        (T element) {
+          _runUserCode(() => combine(value, element), (S newValue) {
+            value = newValue;
+          }, _cancelAndErrorClosure(subscription, result));
+        },
+        onError: result._completeError,
+        onDone: () {
+          result._complete(value);
+        },
+        cancelOnError: true);
+    return result;
+  }
+
+  /**
+   * Combines the string representation of elements into a single string.
+   *
+   * Each element is converted to a string using its [Object.toString] method.
+   * If [separator] is provided, it is inserted between element string
+   * representations.
+   *
+   * The returned future is completed with the combined string when this stream
+   * is done.
+   *
+   * If this stream emits an error, or the call to [Object.toString] throws,
+   * the returned future is completed with that error,
+   * and processing stops.
+   */
+  Future<String> join([String separator = ""]) {
+    _Future<String> result = new _Future<String>();
+    StringBuffer buffer = new StringBuffer();
+    StreamSubscription subscription;
+    bool first = true;
+    subscription = this.listen(
+        (T element) {
+          if (!first) {
+            buffer.write(separator);
+          }
+          first = false;
+          try {
+            buffer.write(element);
+          } catch (e, s) {
+            _cancelAndErrorWithReplacement(subscription, result, e, s);
+          }
+        },
+        onError: result._completeError,
+        onDone: () {
+          result._complete(buffer.toString());
+        },
+        cancelOnError: true);
+    return result;
+  }
+
+  /**
+   * Returns whether [needle] occurs in the elements provided by this stream.
+   *
+   * Compares each element of this stream to [needle] using [Object.==].
+   * If an equal element is found, the returned future is completed with `true`.
+   * If this stream ends without finding a match, the future is completed with
+   * `false`.
+   *
+   * If this stream emits an error, or the call to [Object.==] throws,
+   * the returned future is completed with that error,
+   * and processing stops.
+   */
+  Future<bool> contains(Object needle) {
+    _Future<bool> future = new _Future<bool>();
+    StreamSubscription subscription;
+    subscription = this.listen(
+        (T element) {
+          _runUserCode(() => (element == needle), (bool isMatch) {
+            if (isMatch) {
+              _cancelAndValue(subscription, future, true);
+            }
+          }, _cancelAndErrorClosure(subscription, future));
+        },
+        onError: future._completeError,
+        onDone: () {
+          future._complete(false);
+        },
+        cancelOnError: true);
+    return future;
+  }
+
+  /**
+   * Executes [action] on each element of this stream.
+   *
+   * Completes the returned [Future] when all elements of this stream
+   * have been processed.
+   *
+   * If this stream emits an error, or if the call to [action] throws,
+   * the returned future completes with that error,
+   * and processing stops.
+   */
+  Future forEach(void action(T element)) {
+    _Future future = new _Future();
+    StreamSubscription subscription;
+    subscription = this.listen(
+        (T element) {
+          // TODO(floitsch): the type should be 'void' and inferred.
+          _runUserCode<dynamic>(() => action(element), (_) {},
+              _cancelAndErrorClosure(subscription, future));
+        },
+        onError: future._completeError,
+        onDone: () {
+          future._complete(null);
+        },
+        cancelOnError: true);
+    return future;
+  }
+
+  /**
+   * Checks whether [test] accepts all elements provided by this stream.
+   *
+   * Calls [test] on each element of this stream.
+   * If the call returns `false`, the returned future is completed with `false`
+   * and processing stops.
+   *
+   * If this stream ends without finding an element that [test] rejects,
+   * the returned future is completed with `true`.
+   *
+   * If this stream emits an error, or if the call to [test] throws,
+   * the returned future is completed with that error,
+   * and processing stops.
+   */
+  Future<bool> every(bool test(T element)) {
+    _Future<bool> future = new _Future<bool>();
+    StreamSubscription subscription;
+    subscription = this.listen(
+        (T element) {
+          _runUserCode(() => test(element), (bool isMatch) {
+            if (!isMatch) {
+              _cancelAndValue(subscription, future, false);
+            }
+          }, _cancelAndErrorClosure(subscription, future));
+        },
+        onError: future._completeError,
+        onDone: () {
+          future._complete(true);
+        },
+        cancelOnError: true);
+    return future;
+  }
+
+  /**
+   * Checks whether [test] accepts any element provided by this stream.
+   *
+   * Calls [test] on each element of this stream.
+   * If the call returns `true`, the returned future is completed with `true`
+   * and processing stops.
+   *
+   * If this stream ends without finding an element that [test] accepts,
+   * the returned future is completed with `false`.
+   *
+   * If this stream emits an error, or if the call to [test] throws,
+   * the returned future is completed with that error,
+   * and processing stops.
+   */
+  Future<bool> any(bool test(T element)) {
+    _Future<bool> future = new _Future<bool>();
+    StreamSubscription subscription;
+    subscription = this.listen(
+        (T element) {
+          _runUserCode(() => test(element), (bool isMatch) {
+            if (isMatch) {
+              _cancelAndValue(subscription, future, true);
+            }
+          }, _cancelAndErrorClosure(subscription, future));
+        },
+        onError: future._completeError,
+        onDone: () {
+          future._complete(false);
+        },
+        cancelOnError: true);
+    return future;
+  }
+
+  /**
+   * The number of elements in this stream.
+   *
+   * Waits for all elements of this stream. When this stream ends,
+   * the returned future is completed with the number of elements.
+   *
+   * If this stream emits an error,
+   * the returned future is completed with that error,
+   * and processing stops.
+   *
+   * This operation listens to this stream, and a non-broadcast stream cannot
+   * be reused after finding its length.
+   */
+  Future<int> get length {
+    _Future<int> future = new _Future<int>();
+    int count = 0;
+    this.listen(
+        (_) {
+          count++;
+        },
+        onError: future._completeError,
+        onDone: () {
+          future._complete(count);
+        },
+        cancelOnError: true);
+    return future;
+  }
+
+  /**
+   * Whether this stream contains any elements.
+   *
+   * Waits for the first element of this stream, then completes the returned
+   * future with `true`.
+   * If this stream ends without emitting any elements, the returned future is
+   * completed with `false`.
+   *
+   * If the first event is an error, the returned future is completed with that
+   * error.
+   *
+   * This operation listens to this stream, and a non-broadcast stream cannot
+   * be reused after checking whether it is empty.
+   */
+  Future<bool> get isEmpty {
+    _Future<bool> future = new _Future<bool>();
+    StreamSubscription subscription;
+    subscription = this.listen(
+        (_) {
+          _cancelAndValue(subscription, future, false);
+        },
+        onError: future._completeError,
+        onDone: () {
+          future._complete(true);
+        },
+        cancelOnError: true);
+    return future;
+  }
+
+  /**
+   * Adapt this stream to be a `Stream<R>`.
+   *
+   * This stream is wrapped as a `Stream<R>` which checks at run-time that
+   * each data event emitted by this stream is also an instance of [R].
+   */
+  Stream<R> cast<R>() => Stream.castFrom<T, R>(this);
+  /**
+   * Collects all elements of this stream in a [List].
+   *
+   * Creates a `List<T>` and adds all elements of this stream to the list
+   * in the order they arrive.
+   * When this stream ends, the returned future is completed with that list.
+   *
+   * If this stream emits an error,
+   * the returned future is completed with that error,
+   * and processing stops.
+   */
+  Future<List<T>> toList() {
+    List<T> result = <T>[];
+    _Future<List<T>> future = new _Future<List<T>>();
+    this.listen(
+        (T data) {
+          result.add(data);
+        },
+        onError: future._completeError,
+        onDone: () {
+          future._complete(result);
+        },
+        cancelOnError: true);
+    return future;
+  }
+
+  /**
+   * Collects the data of this stream in a [Set].
+   *
+   * Creates a `Set<T>` and adds all elements of this stream to the set.
+   * in the order they arrive.
+   * When this stream ends, the returned future is completed with that set.
+   *
+   * The returned set is the same type as returned by `new Set<T>()`.
+   * If another type of set is needed, either use [forEach] to add each
+   * element to the set, or use
+   * `toList().then((list) => new SomeOtherSet.from(list))`
+   * to create the set.
+   *
+   * If this stream emits an error,
+   * the returned future is completed with that error,
+   * and processing stops.
+   */
+  Future<Set<T>> toSet() {
+    Set<T> result = new Set<T>();
+    _Future<Set<T>> future = new _Future<Set<T>>();
+    this.listen(
+        (T data) {
+          result.add(data);
+        },
+        onError: future._completeError,
+        onDone: () {
+          future._complete(result);
+        },
+        cancelOnError: true);
+    return future;
+  }
+
+  /**
+   * Discards all data on this stream, but signals when it is done or an error
+   * occurred.
+   *
+   * When subscribing using [drain], cancelOnError will be true. This means
+   * that the future will complete with the first error on this stream and then
+   * cancel the subscription.
+   * If this stream emits an error, or the call to [combine] throws,
+   * the returned future is completed with that error,
+   * and processing is stopped.
+   *
+   * In case of a `done` event the future completes with the given
+   * [futureValue].
+   */
+  Future<E> drain<E>([E futureValue]) =>
+      listen(null, cancelOnError: true).asFuture<E>(futureValue);
+
+  /**
+   * Provides at most the first [count] data events of this stream.
+   *
+   * Returns a stream that emits the same events that this stream would
+   * if listened to at the same time,
+   * until either this stream ends or it has emitted [count] data events,
+   * at which point the returned stream is done.
+   *
+   * If this stream produces fewer than [count] data events before it's done,
+   * so will the returned stream.
+   *
+   * Starts listening to this stream when the returned stream is listened to
+   * and stops listening when the first [count] data events have been received.
+   *
+   * This means that if this is a single-subscription (non-broadcast) streams
+   * it cannot be reused after the returned stream has been listened to.
+   *
+   * If this is a broadcast stream, the returned stream is a broadcast stream.
+   * In that case, the events are only counted from the time
+   * the returned stream is listened to.
+   */
+  Stream<T> take(int count) {
+    return new _TakeStream<T>(this, count);
+  }
+
+  /**
+   * Forwards data events while [test] is successful.
+   *
+   * Returns a stream that provides the same events as this stream
+   * until [test] fails for a data event.
+   * The returned stream is done when either this stream is done,
+   * or when this stream first emits a data event that fails [test].
+   *
+   * The `test` call is considered failing if it returns a non-`true` value
+   * or if it throws. If the `test` call throws, the error is emitted as the
+   * last event on the returned streams.
+   *
+   * Stops listening to this stream after the accepted elements.
+   *
+   * Internally the method cancels its subscription after these elements. This
+   * means that single-subscription (non-broadcast) streams are closed and
+   * cannot be reused after a call to this method.
+   *
+   * The returned stream is a broadcast stream if this stream is.
+   * For a broadcast stream, the events are only tested from the time
+   * the returned stream is listened to.
+   */
+  Stream<T> takeWhile(bool test(T element)) {
+    return new _TakeWhileStream<T>(this, test);
+  }
+
+  /**
+   * Skips the first [count] data events from this stream.
+   *
+   * Returns a stream that emits the same events as this stream would
+   * if listened to at the same time, except that the first [count]
+   * data events are not emitted.
+   * The returned stream is done when this stream is.
+   *
+   * If this stream emits fewer than [count] data events
+   * before being done, the returned stream emits no data events.
+   *
+   * The returned stream is a broadcast stream if this stream is.
+   * For a broadcast stream, the events are only counted from the time
+   * the returned stream is listened to.
+   */
+  Stream<T> skip(int count) {
+    return new _SkipStream<T>(this, count);
+  }
+
+  /**
+   * Skip data events from this stream while they are matched by [test].
+   *
+   * Returns a stream that emits the same events as this stream,
+   * except that data events are not emitted until a data event fails `test`.
+   * The test fails when called with a data event
+   * if it returns a non-`true` value or if the call to `test` throws.
+   * If the call throws, the error is emitted as an error event
+   * on the returned stream instead of the data event,
+   * otherwise the event that made `test` return non-true is emitted as the
+   * first data event.
+   *
+   * Error and done events are provided by the returned stream unmodified.
+   *
+   * The returned stream is a broadcast stream if this stream is.
+   * For a broadcast stream, the events are only tested from the time
+   * the returned stream is listened to.
+   */
+  Stream<T> skipWhile(bool test(T element)) {
+    return new _SkipWhileStream<T>(this, test);
+  }
+
+  /**
+   * Skips data events if they are equal to the previous data event.
+   *
+   * The returned stream provides the same events as this stream, except
+   * that it never provides two consecutive data events that are equal.
+   * That is, errors are passed through to the returned stream, and
+   * data events are passed through if they are distinct from the most
+   * recently emitted data event.
+   *
+   * Equality is determined by the provided [equals] method. If that is
+   * omitted, the '==' operator on the last provided data element is used.
+   *
+   * If [equals] throws, the data event is replaced by an error event
+   * containing the thrown error. The behavior is equivalent to the
+   * original stream emitting the error event, and it doesn't change
+   * the what the most recently emitted data event is.
+   *
+   * The returned stream is a broadcast stream if this stream is.
+   * If a broadcast stream is listened to more than once, each subscription
+   * will individually perform the `equals` test.
+   */
+  Stream<T> distinct([bool equals(T previous, T next)]) {
+    return new _DistinctStream<T>(this, equals);
+  }
+
+  /**
+   * The first element of this stream.
+   *
+   * Stops listening to this stream after the first element has been received.
+   *
+   * Internally the method cancels its subscription after the first element.
+   * This means that single-subscription (non-broadcast) streams are closed
+   * and cannot be reused after a call to this getter.
+   *
+   * If an error event occurs before the first data event, the returned future
+   * is completed with that error.
+   *
+   * If this stream is empty (a done event occurs before the first data event),
+   * the returned future completes with an error.
+   *
+   * Except for the type of the error, this method is equivalent to
+   * `this.elementAt(0)`.
+   */
+  Future<T> get first {
+    _Future<T> future = new _Future<T>();
+    StreamSubscription subscription;
+    subscription = this.listen(
+        (T value) {
+          _cancelAndValue(subscription, future, value);
+        },
+        onError: future._completeError,
+        onDone: () {
+          try {
+            throw IterableElementError.noElement();
+          } catch (e, s) {
+            _completeWithErrorCallback(future, e, s);
+          }
+        },
+        cancelOnError: true);
+    return future;
+  }
+
+  /**
+   * The last element of this stream.
+   *
+   * If this stream emits an error event,
+   * the returned future is completed with that error
+   * and processing stops.
+   *
+   * If this stream is empty (the done event is the first event),
+   * the returned future completes with an error.
+   */
+  Future<T> get last {
+    _Future<T> future = new _Future<T>();
+    T result;
+    bool foundResult = false;
+    listen(
+        (T value) {
+          foundResult = true;
+          result = value;
+        },
+        onError: future._completeError,
+        onDone: () {
+          if (foundResult) {
+            future._complete(result);
+            return;
+          }
+          try {
+            throw IterableElementError.noElement();
+          } catch (e, s) {
+            _completeWithErrorCallback(future, e, s);
+          }
+        },
+        cancelOnError: true);
+    return future;
+  }
+
+  /**
+   * The single element of this stream.
+   *
+   * If this stream emits an error event,
+   * the returned future is completed with that error
+   * and processing stops.
+   *
+   * If [this] is empty or has more than one element,
+   * the returned future completes with an error.
+   */
+  Future<T> get single {
+    _Future<T> future = new _Future<T>();
+    T result;
+    bool foundResult = false;
+    StreamSubscription subscription;
+    subscription = this.listen(
+        (T value) {
+          if (foundResult) {
+            // This is the second element we get.
+            try {
+              throw IterableElementError.tooMany();
+            } catch (e, s) {
+              _cancelAndErrorWithReplacement(subscription, future, e, s);
+            }
+            return;
+          }
+          foundResult = true;
+          result = value;
+        },
+        onError: future._completeError,
+        onDone: () {
+          if (foundResult) {
+            future._complete(result);
+            return;
+          }
+          try {
+            throw IterableElementError.noElement();
+          } catch (e, s) {
+            _completeWithErrorCallback(future, e, s);
+          }
+        },
+        cancelOnError: true);
+    return future;
+  }
+
+  /**
+   * Finds the first element of this stream matching [test].
+   *
+   * Returns a future that is completed with the first element of this stream
+   * that [test] returns `true` for.
+   *
+   * If no such element is found before this stream is done, and a
+   * [orElse] function is provided, the result of calling [orElse]
+   * becomes the value of the future. If [orElse] throws, the returned
+   * future is completed with that error.
+   *
+   * If this stream emits an error before the first matching element,
+   * the returned future is completed with that error, and processing stops.
+   *
+   * Stops listening to this stream after the first matching element or error
+   * has been received.
+   *
+   * Internally the method cancels its subscription after the first element that
+   * matches the predicate. This means that single-subscription (non-broadcast)
+   * streams are closed and cannot be reused after a call to this method.
+   *
+   * If an error occurs, or if this stream ends without finding a match and
+   * with no [orElse] function provided,
+   * the returned future is completed with an error.
+   */
+  Future<T> firstWhere(bool test(T element), {T orElse()}) {
+    _Future<T> future = new _Future();
+    StreamSubscription subscription;
+    subscription = this.listen(
+        (T value) {
+          _runUserCode(() => test(value), (bool isMatch) {
+            if (isMatch) {
+              _cancelAndValue(subscription, future, value);
+            }
+          }, _cancelAndErrorClosure(subscription, future));
+        },
+        onError: future._completeError,
+        onDone: () {
+          if (orElse != null) {
+            _runUserCode(orElse, future._complete, future._completeError);
+            return;
+          }
+          try {
+            throw IterableElementError.noElement();
+          } catch (e, s) {
+            _completeWithErrorCallback(future, e, s);
+          }
+        },
+        cancelOnError: true);
+    return future;
+  }
+
+  /**
+   * Finds the last element in this stream matching [test].
+   *
+   * If this stream emits an error, the returned future is completed with that
+   * error, and processing stops.
+   *
+   * Otherwise as [firstWhere], except that the last matching element is found
+   * instead of the first.
+   * That means that a non-error result cannot be provided before this stream
+   * is done.
+   */
+  Future<T> lastWhere(bool test(T element), {T orElse()}) {
+    _Future<T> future = new _Future();
+    T result;
+    bool foundResult = false;
+    StreamSubscription subscription;
+    subscription = this.listen(
+        (T value) {
+          _runUserCode(() => true == test(value), (bool isMatch) {
+            if (isMatch) {
+              foundResult = true;
+              result = value;
+            }
+          }, _cancelAndErrorClosure(subscription, future));
+        },
+        onError: future._completeError,
+        onDone: () {
+          if (foundResult) {
+            future._complete(result);
+            return;
+          }
+          if (orElse != null) {
+            _runUserCode(orElse, future._complete, future._completeError);
+            return;
+          }
+          try {
+            throw IterableElementError.noElement();
+          } catch (e, s) {
+            _completeWithErrorCallback(future, e, s);
+          }
+        },
+        cancelOnError: true);
+    return future;
+  }
+
+  /**
+   * Finds the single element in this stream matching [test].
+   *
+   * Like [lastWhere], except that it is an error if more than one
+   * matching element occurs in this stream.
+   */
+  Future<T> singleWhere(bool test(T element), {T orElse()}) {
+    _Future<T> future = new _Future<T>();
+    T result;
+    bool foundResult = false;
+    StreamSubscription subscription;
+    subscription = this.listen(
+        (T value) {
+          _runUserCode(() => true == test(value), (bool isMatch) {
+            if (isMatch) {
+              if (foundResult) {
+                try {
+                  throw IterableElementError.tooMany();
+                } catch (e, s) {
+                  _cancelAndErrorWithReplacement(subscription, future, e, s);
+                }
+                return;
+              }
+              foundResult = true;
+              result = value;
+            }
+          }, _cancelAndErrorClosure(subscription, future));
+        },
+        onError: future._completeError,
+        onDone: () {
+          if (foundResult) {
+            future._complete(result);
+            return;
+          }
+          try {
+            if (orElse != null) {
+              _runUserCode(orElse, future._complete, future._completeError);
+              return;
+            }
+            throw IterableElementError.noElement();
+          } catch (e, s) {
+            _completeWithErrorCallback(future, e, s);
+          }
+        },
+        cancelOnError: true);
+    return future;
+  }
+
+  /**
+   * Returns the value of the [index]th data event of this stream.
+   *
+   * Stops listening to this stream after the [index]th data event has been
+   * received.
+   *
+   * Internally the method cancels its subscription after these elements. This
+   * means that single-subscription (non-broadcast) streams are closed and
+   * cannot be reused after a call to this method.
+   *
+   * If an error event occurs before the value is found, the future completes
+   * with this error.
+   *
+   * If a done event occurs before the value is found, the future completes
+   * with a [RangeError].
+   */
+  Future<T> elementAt(int index) {
+    ArgumentError.checkNotNull(index, "index");
+    RangeError.checkNotNegative(index, "index");
+    _Future<T> future = new _Future<T>();
+    StreamSubscription subscription;
+    int elementIndex = 0;
+    subscription = this.listen(
+        (T value) {
+          if (index == elementIndex) {
+            _cancelAndValue(subscription, future, value);
+            return;
+          }
+          elementIndex += 1;
+        },
+        onError: future._completeError,
+        onDone: () {
+          future._completeError(
+              new RangeError.index(index, this, "index", null, elementIndex));
+        },
+        cancelOnError: true);
+    return future;
+  }
+
+  /**
+   * Creates a new stream with the same events as this stream.
+   *
+   * Whenever more than [timeLimit] passes between two events from this stream,
+   * the [onTimeout] function is called, which can emit further events on
+   * the returned stream.
+   *
+   * The countdown doesn't start until the returned stream is listened to.
+   * The countdown is reset every time an event is forwarded from this stream,
+   * or when this stream is paused and resumed.
+   *
+   * The [onTimeout] function is called with one argument: an
+   * [EventSink] that allows putting events into the returned stream.
+   * This `EventSink` is only valid during the call to [onTimeout].
+   * Calling [EventSink.close] on the sink passed to [onTimeout] closes the
+   * returned stream, and no further events are processed.
+   *
+   * If [onTimeout] is omitted, a timeout will just put a [TimeoutException]
+   * into the error channel of the returned stream.
+   * If the call to [onTimeout] throws, the error is emitted on the returned
+   * stream.
+   *
+   * The returned stream is a broadcast stream if this stream is.
+   * If a broadcast stream is listened to more than once, each subscription
+   * will have its individually timer that starts counting on listen,
+   * and the subscriptions' timers can be paused individually.
+   */
+  Stream<T> timeout(Duration timeLimit, {void onTimeout(EventSink<T> sink)}) {
+    _StreamControllerBase<T> controller;
+    // The following variables are set on listen.
+    StreamSubscription<T> subscription;
+    Timer timer;
+    Zone zone;
+    _TimerCallback timeout;
+
+    void onData(T event) {
+      timer.cancel();
+      timer = zone.createTimer(timeLimit, timeout);
+      // It might close the stream and cancel timer, so create recuring Timer
+      // before calling into add();
+      // issue: https://github.com/dart-lang/sdk/issues/37565
+      controller.add(event);
+    }
+
+    void onError(error, StackTrace stackTrace) {
+      timer.cancel();
+      assert(controller is _StreamController ||
+          controller is _BroadcastStreamController);
+      controller._addError(error, stackTrace); // Avoid Zone error replacement.
+      timer = zone.createTimer(timeLimit, timeout);
+    }
+
+    void onDone() {
+      timer.cancel();
+      controller.close();
+    }
+
+    void onListen() {
+      // This is the onListen callback for of controller.
+      // It runs in the same zone that the subscription was created in.
+      // Use that zone for creating timers and running the onTimeout
+      // callback.
+      zone = Zone.current;
+      if (onTimeout == null) {
+        timeout = () {
+          controller.addError(
+              new TimeoutException("No stream event", timeLimit), null);
+        };
+      } else {
+        // TODO(floitsch): the return type should be 'void', and the type
+        // should be inferred.
+        var registeredOnTimeout =
+            zone.registerUnaryCallback<dynamic, EventSink<T>>(onTimeout);
+        var wrapper = new _ControllerEventSinkWrapper<T>(null);
+        timeout = () {
+          wrapper._sink = controller; // Only valid during call.
+          zone.runUnaryGuarded(registeredOnTimeout, wrapper);
+          wrapper._sink = null;
+        };
+      }
+
+      subscription = this.listen(onData, onError: onError, onDone: onDone);
+      timer = zone.createTimer(timeLimit, timeout);
+    }
+
+    Future onCancel() {
+      timer.cancel();
+      Future result = subscription.cancel();
+      subscription = null;
+      return result;
+    }
+
+    controller = isBroadcast
+        ? new _SyncBroadcastStreamController<T>(onListen, onCancel)
+        : new _SyncStreamController<T>(onListen, () {
+            // Don't null the timer, onCancel may call cancel again.
+            timer.cancel();
+            subscription.pause();
+          }, () {
+            subscription.resume();
+            timer = zone.createTimer(timeLimit, timeout);
+          }, onCancel);
+    return controller.stream;
+  }
+}
+
+/**
+ * A subscription on events from a [Stream].
+ *
+ * When you listen on a [Stream] using [Stream.listen],
+ * a [StreamSubscription] object is returned.
+ *
+ * The subscription provides events to the listener,
+ * and holds the callbacks used to handle the events.
+ * The subscription can also be used to unsubscribe from the events,
+ * or to temporarily pause the events from the stream.
+ */
+abstract class StreamSubscription<T> {
+  /**
+   * Cancels this subscription.
+   *
+   * After this call, the subscription no longer receives events.
+   *
+   * The stream may need to shut down the source of events and clean up after
+   * the subscription is canceled.
+   *
+   * Returns a future that is completed once the stream has finished
+   * its cleanup.
+   *
+   * For historical reasons, may also return `null` if no cleanup was necessary.
+   * Returning `null` is deprecated and should be avoided.
+   *
+   * Typically, futures are returned when the stream needs to release resources.
+   * For example, a stream might need to close an open file (as an asynchronous
+   * operation). If the listener wants to delete the file after having
+   * canceled the subscription, it must wait for the cleanup future to complete.
+   *
+   * A returned future completes with a `null` value.
+   * If the cleanup throws, which it really shouldn't, the returned future
+   * completes with that error.
+   */
+  Future cancel();
+
+  /**
+   * Replaces the data event handler of this subscription.
+   *
+   * The [handleData] function is called for each element of the stream
+   * after this function is called.
+   * If [handleData] is `null`, further elements are ignored.
+   *
+   * This method replaces the current handler set by the invocation of
+   * [Stream.listen] or by a previous call to [onData].
+   */
+  void onData(void handleData(T data));
+
+  /**
+   * Replaces the error event handler of this subscription.
+   *
+   * The [handleError] function must be able to be called with either
+   * one positional argument, or with two positional arguments
+   * where the seconds is always a [StackTrace].
+   *
+   * The [handleError] argument may be `null`, in which case further
+   * error events are considered unhandled, and will be reported to
+   * [Zone.handleUncaughtError].
+   *
+   * The provided function is called for all error events from the
+   * stream subscription.
+   *
+   * This method replaces the current handler set by the invocation of
+   * [Stream.listen], by calling [asFuture], or by a previous call to [onError].
+   */
+  void onError(Function handleError);
+
+  /**
+   * Replaces the done event handler of this subscription.
+   *
+   * The [handleDone] function is called when the stream closes.
+   * The value may be `null`, in which case no function is called.
+   *
+   * This method replaces the current handler set by the invocation of
+   * [Stream.listen], by calling [asFuture], or by a previous call to [onDone].
+   */
+  void onDone(void handleDone());
+
+  /**
+   * Request that the stream pauses events until further notice.
+   *
+   * While paused, the subscription will not fire any events.
+   * If it receives events from its source, they will be buffered until
+   * the subscription is resumed.
+   * For non-broadcast streams, the underlying source is usually informed
+   * about the pause,
+   * so it can stop generating events until the subscription is resumed.
+   *
+   * To avoid buffering events on a broadcast stream, it is better to
+   * cancel this subscription, and start to listen again when events
+   * are needed, if the intermediate events are not important.
+   *
+   * If [resumeSignal] is provided, the stream subscription will undo the pause
+   * when the future completes, as if by a call to [resume].
+   * If the future completes with an error,
+   * the stream will still resume, but the error will be considered unhandled
+   * and is passed to [Zone.handleUncaughtError].
+   *
+   * A call to [resume] will also undo a pause.
+   *
+   * If the subscription is paused more than once, an equal number
+   * of resumes must be performed to resume the stream.
+   * Calls to [resume] and the completion of a [resumeSignal] are
+   * interchangeable - the [pause] which was passed a [resumeSignal] may be
+   * ended by a call to [resume], and completing the [resumeSignal] may end a
+   * different [pause].
+   *
+   * It is safe to [resume] or complete a [resumeSignal] even when the
+   * subscription is not paused, and the resume will have no effect.
+   *
+   * Currently DOM streams silently drop events when the stream is paused. This
+   * is a bug and will be fixed.
+   */
+  void pause([Future resumeSignal]);
+
+  /**
+   * Resume after a pause.
+   *
+   * This undoes one previous call to [pause].
+   * When all previously calls to [pause] have been matched by a calls to
+   * [resume], possibly through a `resumeSignal` passed to [pause],
+   * the stream subscription may emit events again.
+   *
+   * It is safe to [resume] even when the subscription is not paused, and the
+   * resume will have no effect.
+   */
+  void resume();
+
+  /**
+   * Whether the [StreamSubscription] is currently paused.
+   *
+   * If there have been more calls to [pause] than to [resume] on this
+   * stream subscription, the subscription is paused, and this getter
+   * returns `true`.
+   *
+   * Returns `false` if the stream can currently emit events, or if
+   * the subscription has completed or been cancelled.
+   */
+  bool get isPaused;
+
+  /**
+   * Returns a future that handles the [onDone] and [onError] callbacks.
+   *
+   * This method *overwrites* the existing [onDone] and [onError] callbacks
+   * with new ones that complete the returned future.
+   *
+   * In case of an error the subscription will automatically cancel (even
+   * when it was listening with `cancelOnError` set to `false`).
+   *
+   * In case of a `done` event the future completes with the given
+   * [futureValue].
+   */
+  Future<E> asFuture<E>([E futureValue]);
+}
+
+/**
+ * A [Sink] that supports adding errors.
+ *
+ * This makes it suitable for capturing the results of asynchronous
+ * computations, which can complete with a value or an error.
+ *
+ * The [EventSink] has been designed to handle asynchronous events from
+ * [Stream]s. See, for example, [Stream.eventTransformed] which uses
+ * `EventSink`s to transform events.
+ */
+abstract class EventSink<T> implements Sink<T> {
+  /**
+   * Adds a data [event] to the sink.
+   *
+   * Must not be called on a closed sink.
+   */
+  void add(T event);
+
+  /**
+   * Adds an [error] to the sink.
+   *
+   * Must not be called on a closed sink.
+   */
+  void addError(Object error, [StackTrace stackTrace]);
+
+  /**
+   * Closes the sink.
+   *
+   * Calling this method more than once is allowed, but does nothing.
+   *
+   * Neither [add] nor [addError] must be called after this method.
+   */
+  void close();
+}
+
+/** [Stream] wrapper that only exposes the [Stream] interface. */
+class StreamView<T> extends Stream<T> {
+  final Stream<T> _stream;
+
+  const StreamView(Stream<T> stream)
+      : _stream = stream,
+        super._internal();
+
+  bool get isBroadcast => _stream.isBroadcast;
+
+  Stream<T> asBroadcastStream(
+          {void onListen(StreamSubscription<T> subscription),
+          void onCancel(StreamSubscription<T> subscription)}) =>
+      _stream.asBroadcastStream(onListen: onListen, onCancel: onCancel);
+
+  StreamSubscription<T> listen(void onData(T value),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    return _stream.listen(onData,
+        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+  }
+}
+
+/**
+ * Abstract interface for a "sink" accepting multiple entire streams.
+ *
+ * A consumer can accept a number of consecutive streams using [addStream],
+ * and when no further data need to be added, the [close] method tells the
+ * consumer to complete its work and shut down.
+ *
+ * The [Stream.pipe] accepts a `StreamConsumer` and will pass the stream
+ * to the consumer's [addStream] method. When that completes, it will
+ * call [close] and then complete its own returned future.
+ */
+abstract class StreamConsumer<S> {
+  /**
+   * Consumes the elements of [stream].
+   *
+   * Listens on [stream] and does something for each event.
+   *
+   * Returns a future which is completed when the stream is done being added,
+   * and the consumer is ready to accept a new stream.
+   * No further calls to [addStream] or [close] should happen before the
+   * returned future has completed.
+   *
+   * The consumer may stop listening to the stream after an error,
+   * it may consume all the errors and only stop at a done event,
+   * or it may be canceled early if the receiver don't want any further events.
+   *
+   * If the consumer stops listening because of some error preventing it
+   * from continuing, it may report this error in the returned future,
+   * otherwise it will just complete the future with `null`.
+   */
+  Future addStream(Stream<S> stream);
+
+  /**
+   * Tells the consumer that no further streams will be added.
+   *
+   * This allows the consumer to complete any remaining work and release
+   * resources that are no longer needed
+   *
+   * Returns a future which is completed when the consumer has shut down.
+   * If cleaning up can fail, the error may be reported in the returned future,
+   * otherwise it completes with `null`.
+   */
+  Future close();
+}
+
+/**
+ * A object that accepts stream events both synchronously and asynchronously.
+ *
+ * A [StreamSink] combines the methods from [StreamConsumer] and [EventSink].
+ *
+ * The [EventSink] methods can't be used while the [addStream] is called.
+ * As soon as the [addStream]'s [Future] completes with a value, the
+ * [EventSink] methods can be used again.
+ *
+ * If [addStream] is called after any of the [EventSink] methods, it'll
+ * be delayed until the underlying system has consumed the data added by the
+ * [EventSink] methods.
+ *
+ * When [EventSink] methods are used, the [done] [Future] can be used to
+ * catch any errors.
+ *
+ * When [close] is called, it will return the [done] [Future].
+ */
+abstract class StreamSink<S> implements EventSink<S>, StreamConsumer<S> {
+  /**
+   * Tells the stream sink that no further streams will be added.
+   *
+   * This allows the stream sink to complete any remaining work and release
+   * resources that are no longer needed
+   *
+   * Returns a future which is completed when the stream sink has shut down.
+   * If cleaning up can fail, the error may be reported in the returned future,
+   * otherwise it completes with `null`.
+   *
+   * Returns the same future as [done].
+   *
+   * The stream sink may close before the [close] method is called, either due
+   * to an error or because it is itself providing events to someone who has
+   * stopped listening. In that case, the [done] future is completed first,
+   * and the `close` method will return the `done` future when called.
+   *
+   * Unifies [StreamConsumer.close] and [EventSink.close] which both mark their
+   * object as not expecting any further events.
+   */
+  Future close();
+
+  /**
+   * Return a future which is completed when the [StreamSink] is finished.
+   *
+   * If the `StreamSink` fails with an error,
+   * perhaps in response to adding events using [add], [addError] or [close],
+   * the [done] future will complete with that error.
+   *
+   * Otherwise, the returned future will complete when either:
+   *
+   * * all events have been processed and the sink has been closed, or
+   * * the sink has otherwise been stopped from handling more events
+   *   (for example by canceling a stream subscription).
+   */
+  Future get done;
+}
+
+/**
+ * Transforms a Stream.
+ *
+ * When a stream's [Stream.transform] method is invoked with a
+ * [StreamTransformer], the stream calls the [bind] method on the provided
+ * transformer. The resulting stream is then returned from the
+ * [Stream.transform] method.
+ *
+ * Conceptually, a transformer is simply a function from [Stream] to [Stream]
+ * that is encapsulated into a class.
+ *
+ * It is good practice to write transformers that can be used multiple times.
+ *
+ * All other transforming methods on [Stream], such as [Stream.map],
+ * [Stream.where] or [Stream.expand] can be implemented using
+ * [Stream.transform]. A [StreamTransformer] is thus very powerful but often
+ * also a bit more complicated to use.
+ */
+abstract class StreamTransformer<S, T> {
+  /**
+   * Creates a [StreamTransformer] based on the given [onListen] callback.
+   *
+   * The returned stream transformer uses the provided [onListen] callback
+   * when a transformed stream is listened to. At that time, the callback
+   * receives the input stream (the one passed to [bind]) and a
+   * boolean flag `cancelOnError` to create a [StreamSubscription].
+   *
+   * If the transformed stream is a broadcast stream, so is the stream
+   * returned by the [StreamTransformer.bind] method by this transformer.
+   *
+   * If the transformed stream is listened to multiple times, the [onListen]
+   * callback is called again for each new [Stream.listen] call.
+   * This happens whether the stream is a broadcast stream or not,
+   * but the call will usually fail for non-broadcast streams.
+   *
+   * The [onListen] callback does *not* receive the handlers that were passed
+   * to [Stream.listen]. These are automatically set after the call to the
+   * [onListen] callback (using [StreamSubscription.onData],
+   * [StreamSubscription.onError] and [StreamSubscription.onDone]).
+   *
+   * Most commonly, an [onListen] callback will first call [Stream.listen] on
+   * the provided stream (with the corresponding `cancelOnError` flag), and then
+   * return a new [StreamSubscription].
+   *
+   * There are two common ways to create a StreamSubscription:
+   *
+   * 1. by allocating a [StreamController] and to return the result of
+   *    listening to its stream. It's important to forward pause, resume and
+   *    cancel events (unless the transformer intentionally wants to change
+   *    this behavior).
+   * 2. by creating a new class that implements [StreamSubscription].
+   *    Note that the subscription should run callbacks in the [Zone] the
+   *    stream was listened to (see [Zone] and [Zone.bindCallback]).
+   *
+   * Example:
+   *
+   * ```
+   * /// Starts listening to [input] and duplicates all non-error events.
+   * StreamSubscription<int> _onListen(Stream<int> input, bool cancelOnError) {
+   *   StreamSubscription<String> subscription;
+   *   // Create controller that forwards pause, resume and cancel events.
+   *   var controller = new StreamController<String>(
+   *       onPause: () {
+   *         subscription.pause();
+   *       },
+   *       onResume: () {
+   *         subscription.resume();
+   *       },
+   *       onCancel: () => subscription.cancel(),
+   *       sync: true); // "sync" is correct here, since events are forwarded.
+   *
+   *   // Listen to the provided stream using `cancelOnError`.
+   *   subscription = input.listen((data) {
+   *     // Duplicate the data.
+   *     controller.add(data);
+   *     controller.add(data);
+   *   },
+   *       onError: controller.addError,
+   *       onDone: controller.close,
+   *       cancelOnError: cancelOnError);
+   *
+   *   // Return a new [StreamSubscription] by listening to the controller's
+   *   // stream.
+   *   return controller.stream.listen(null);
+   * }
+   *
+   * // Instantiate a transformer:
+   * var duplicator = const StreamTransformer<int, int>(_onListen);
+   *
+   * // Use as follows:
+   * intStream.transform(duplicator);
+   * ```
+   */
+  const factory StreamTransformer(
+          StreamSubscription<T> onListen(
+              Stream<S> stream, bool cancelOnError)) =
+      _StreamSubscriptionTransformer<S, T>;
+
+  /**
+   * Creates a [StreamTransformer] that delegates events to the given functions.
+   *
+   * Example use of a duplicating transformer:
+   *
+   * ```
+   * stringStream.transform(new StreamTransformer<String, String>.fromHandlers(
+   *     handleData: (String value, EventSink<String> sink) {
+   *       sink.add(value);
+   *       sink.add(value);  // Duplicate the incoming events.
+   *     }));
+   * ```
+   *
+   * Transformers that are constructed this way cannot use captured state if
+   * they are used in streams that can be listened to multiple times.
+   * ```
+   * StreamController<String> controller;
+   * controller = new StreamController.broadcast(onListen: () {
+   *   scheduleMicrotask(() {
+   *     controller.addError("Bad");
+   *     controller.addError("Worse");
+   *     controller.addError("Worst");
+   *   });
+   * });
+   * var sharedState = 0;
+   * var transformedStream = controller.stream.transform(
+   *     new StreamTransformer<String>.fromHandlers(
+   *         handleError: (error, stackTrace, sink) {
+   *   sharedState++; // Increment shared error-counter.
+   *   sink.add("Error $sharedState: $error");
+   * }));
+   *
+   * transformedStream.listen(print);
+   * transformedStream.listen(print); // Listen twice.
+   * // Listening twice to the same stream makes the transformer share the same
+   * // state. Instead of having "Error 1: Bad", "Error 2: Worse",
+   * // "Error 3: Worst" as output (each twice for the separate subscriptions),
+   * // this program emits:
+   * // Error 1: Bad
+   * // Error 2: Bad
+   * // Error 3: Worse
+   * // Error 4: Worse
+   * // Error 5: Worst
+   * // Error 6: Worst
+   * ```
+   */
+  factory StreamTransformer.fromHandlers(
+      {void handleData(S data, EventSink<T> sink),
+      void handleError(Object error, StackTrace stackTrace, EventSink<T> sink),
+      void handleDone(EventSink<T> sink)}) = _StreamHandlerTransformer<S, T>;
+
+  /**
+   * Creates a [StreamTransformer] based on a [bind] callback.
+   *
+   * The returned stream transformer uses the [bind] argument to implement the
+   * [StreamTransformer.bind] API and can be used when the transformation is
+   * available as a stream-to-stream function.
+   *
+   * ```dart
+   * final splitDecoded = StreamTransformer<List<int>, String>.fromBind(
+   *     (stream) => stream.transform(utf8.decoder).transform(LineSplitter()));
+   * ```
+   */
+  @Since("2.1")
+  factory StreamTransformer.fromBind(Stream<T> Function(Stream<S>) bind) =
+      _StreamBindTransformer<S, T>;
+
+  /**
+   * Adapts [source] to be a `StreamTransformer<TS, TT>`.
+   *
+   * This allows [source] to be used at the new type, but at run-time it
+   * must satisfy the requirements of both the new type and its original type.
+   *
+   * Data events passed into the returned transformer must also be instances
+   * of [SS], and data events produced by [source] for those events must
+   * also be instances of [TT].
+   */
+  static StreamTransformer<TS, TT> castFrom<SS, ST, TS, TT>(
+      StreamTransformer<SS, ST> source) {
+    return new CastStreamTransformer<SS, ST, TS, TT>(source);
+  }
+
+  /**
+   * Transforms the provided [stream].
+   *
+   * Returns a new stream with events that are computed from events of the
+   * provided [stream].
+   *
+   * The [StreamTransformer] interface is completely generic,
+   * so it cannot say what subclasses do.
+   * Each [StreamTransformer] should document clearly how it transforms the
+   * stream (on the class or variable used to access the transformer),
+   * as well as any differences from the following typical behavior:
+   *
+   * * When the returned stream is listened to, it starts listening to the
+   *   input [stream].
+   * * Subscriptions of the returned stream forward (in a reasonable time)
+   *   a [StreamSubscription.pause] call to the subscription of the input
+   *   [stream].
+   * * Similarly, canceling a subscription of the returned stream eventually
+   *   (in reasonable time) cancels the subscription of the input [stream].
+   *
+   * "Reasonable time" depends on the transformer and stream. Some transformers,
+   * like a "timeout" transformer, might make these operations depend on a
+   * duration. Others might not delay them at all, or just by a microtask.
+   *
+   * Transformers are free to handle errors in any way.
+   * A transformer implementation may choose to propagate errors,
+   * or convert them to other events, or ignore them completely,
+   * but if errors are ignored, it should be documented explicitly.
+   */
+  Stream<T> bind(Stream<S> stream);
+
+  /**
+   * Provides a `StreamTransformer<RS, RT>` view of this stream transformer.
+   *
+   * The resulting transformer will check at run-time that all data events
+   * of the stream it transforms are actually instances of [S],
+   * and it will check that all data events produced by this transformer
+   * are actually instances of [RT].
+   */
+  StreamTransformer<RS, RT> cast<RS, RT>();
+}
+
+/**
+ * Base class for implementing [StreamTransformer].
+ *
+ * Contains default implementations of every method except [bind].
+ */
+abstract class StreamTransformerBase<S, T> implements StreamTransformer<S, T> {
+  const StreamTransformerBase();
+
+  StreamTransformer<RS, RT> cast<RS, RT>() =>
+      StreamTransformer.castFrom<S, T, RS, RT>(this);
+}
+
+/**
+ * An [Iterator] like interface for the values of a [Stream].
+ *
+ * This wraps a [Stream] and a subscription on the stream. It listens
+ * on the stream, and completes the future returned by [moveNext] when the
+ * next value becomes available.
+ *
+ * The stream may be paused between calls to [moveNext].
+ */
+abstract class StreamIterator<T> {
+  /** Create a [StreamIterator] on [stream]. */
+  factory StreamIterator(Stream<T> stream)
+      // TODO(lrn): use redirecting factory constructor when type
+      // arguments are supported.
+      =>
+      new _StreamIterator<T>(stream);
+
+  /**
+   * Wait for the next stream value to be available.
+   *
+   * Returns a future which will complete with either `true` or `false`.
+   * Completing with `true` means that another event has been received and
+   * can be read as [current].
+   * Completing with `false` means that the stream iteration is done and
+   * no further events will ever be available.
+   * The future may complete with an error, if the stream produces an error,
+   * which also ends iteration.
+   *
+   * The function must not be called again until the future returned by a
+   * previous call is completed.
+   */
+  Future<bool> moveNext();
+
+  /**
+   * The current value of the stream.
+   *
+   * Is `null` before the first call to [moveNext] and after a call to
+   * `moveNext` completes with a `false` result or an error.
+   *
+   * When a `moveNext` call completes with `true`, the `current` field holds
+   * the most recent event of the stream, and it stays like that until the next
+   * call to `moveNext`.
+   * Between a call to `moveNext` and when its returned future completes,
+   * the value is unspecified.
+   */
+  T get current;
+
+  /**
+   * Cancels the stream iterator (and the underlying stream subscription) early.
+   *
+   * The stream iterator is automatically canceled if the [moveNext] future
+   * completes with either `false` or an error.
+   *
+   * If you need to stop listening for values before the stream iterator is
+   * automatically closed, you must call [cancel] to ensure that the stream
+   * is properly closed.
+   *
+   * If [moveNext] has been called when the iterator is canceled,
+   * its returned future will complete with `false` as value,
+   * as will all further calls to [moveNext].
+   *
+   * Returns a future if the cancel-operation is not completed synchronously.
+   * Otherwise returns `null`.
+   */
+  Future cancel();
+}
+
+/**
+ * Wraps an [_EventSink] so it exposes only the [EventSink] interface.
+ */
+class _ControllerEventSinkWrapper<T> implements EventSink<T> {
+  EventSink _sink;
+  _ControllerEventSinkWrapper(this._sink);
+
+  void add(T data) {
+    _sink.add(data);
+  }
+
+  void addError(error, [StackTrace stackTrace]) {
+    _sink.addError(error, stackTrace);
+  }
+
+  void close() {
+    _sink.close();
+  }
+}
diff --git a/sdk_nnbd/lib/async/stream_controller.dart b/sdk_nnbd/lib/async/stream_controller.dart
new file mode 100644
index 0000000..34c6adf
--- /dev/null
+++ b/sdk_nnbd/lib/async/stream_controller.dart
@@ -0,0 +1,942 @@
+// Copyright (c) 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 dart.async;
+
+// -------------------------------------------------------------------
+// Controller for creating and adding events to a stream.
+// -------------------------------------------------------------------
+
+/**
+ * Type of a stream controller's `onListen`, `onPause` and `onResume` callbacks.
+ */
+typedef void ControllerCallback();
+
+/**
+ * Type of stream controller `onCancel` callbacks.
+ *
+ * The callback may return either `void` or a future.
+ */
+typedef ControllerCancelCallback();
+
+/**
+ * A controller with the stream it controls.
+ *
+ * This controller allows sending data, error and done events on
+ * its [stream].
+ * This class can be used to create a simple stream that others
+ * can listen on, and to push events to that stream.
+ *
+ * It's possible to check whether the stream is paused or not, and whether
+ * it has subscribers or not, as well as getting a callback when either of
+ * these change.
+ */
+abstract class StreamController<T> implements StreamSink<T> {
+  /** The stream that this controller is controlling. */
+  Stream<T> get stream;
+
+  /**
+   * A controller with a [stream] that supports only one single subscriber.
+   *
+   * If [sync] is true, the returned stream controller is a
+   * [SynchronousStreamController], and must be used with the care
+   * and attention necessary to not break the [Stream] contract. If in doubt,
+   * use the non-sync version.
+   *
+   * Using an asynchronous controller will never give the wrong
+   * behavior, but using a synchronous controller incorrectly can cause
+   * otherwise correct programs to break.
+   *
+   * A synchronous controller is only intended for optimizing event
+   * propagation when one asynchronous event immediately triggers another.
+   * It should not be used unless the calls to [add] or [addError]
+   * are guaranteed to occur in places where it won't break `Stream` invariants.
+   *
+   * Use synchronous controllers only to forward (potentially transformed)
+   * events from another stream or a future.
+   *
+   * A Stream should be inert until a subscriber starts listening on it (using
+   * the [onListen] callback to start producing events). Streams should not
+   * leak resources (like websockets) when no user ever listens on the stream.
+   *
+   * The controller buffers all incoming events until a subscriber is
+   * registered, but this feature should only be used in rare circumstances.
+   *
+   * The [onPause] function is called when the stream becomes
+   * paused. [onResume] is called when the stream resumed.
+   *
+   * The [onListen] callback is called when the stream
+   * receives its listener and [onCancel] when the listener ends
+   * its subscription. If [onCancel] needs to perform an asynchronous operation,
+   * [onCancel] should return a future that completes when the cancel operation
+   * is done.
+   *
+   * If the stream is canceled before the controller needs new data the
+   * [onResume] call might not be executed.
+   */
+  factory StreamController(
+      {void onListen(),
+      void onPause(),
+      void onResume(),
+      onCancel(),
+      bool sync: false}) {
+    return sync
+        ? new _SyncStreamController<T>(onListen, onPause, onResume, onCancel)
+        : new _AsyncStreamController<T>(onListen, onPause, onResume, onCancel);
+  }
+
+  /**
+   * A controller where [stream] can be listened to more than once.
+   *
+   * The [Stream] returned by [stream] is a broadcast stream.
+   * It can be listened to more than once.
+   *
+   * A Stream should be inert until a subscriber starts listening on it (using
+   * the [onListen] callback to start producing events). Streams should not
+   * leak resources (like websockets) when no user ever listens on the stream.
+   *
+   * Broadcast streams do not buffer events when there is no listener.
+   *
+   * The controller distributes any events to all currently subscribed
+   * listeners at the time when [add], [addError] or [close] is called.
+   * It is not allowed to call `add`, `addError`, or `close` before a previous
+   * call has returned. The controller does not have any internal queue of
+   * events, and if there are no listeners at the time the event is added,
+   * it will just be dropped, or, if it is an error, be reported as uncaught.
+   *
+   * Each listener subscription is handled independently,
+   * and if one pauses, only the pausing listener is affected.
+   * A paused listener will buffer events internally until unpaused or canceled.
+   *
+   * If [sync] is true, events may be fired directly by the stream's
+   * subscriptions during an [add], [addError] or [close] call.
+   * The returned stream controller is a [SynchronousStreamController],
+   * and must be used with the care and attention necessary to not break
+   * the [Stream] contract.
+   * See [Completer.sync] for some explanations on when a synchronous
+   * dispatching can be used.
+   * If in doubt, keep the controller non-sync.
+   *
+   * If [sync] is false, the event will always be fired at a later time,
+   * after the code adding the event has completed.
+   * In that case, no guarantees are given with regard to when
+   * multiple listeners get the events, except that each listener will get
+   * all events in the correct order. Each subscription handles the events
+   * individually.
+   * If two events are sent on an async controller with two listeners,
+   * one of the listeners may get both events
+   * before the other listener gets any.
+   * A listener must be subscribed both when the event is initiated
+   * (that is, when [add] is called)
+   * and when the event is later delivered,
+   * in order to receive the event.
+   *
+   * The [onListen] callback is called when the first listener is subscribed,
+   * and the [onCancel] is called when there are no longer any active listeners.
+   * If a listener is added again later, after the [onCancel] was called,
+   * the [onListen] will be called again.
+   */
+  factory StreamController.broadcast(
+      {void onListen(), void onCancel(), bool sync: false}) {
+    return sync
+        ? new _SyncBroadcastStreamController<T>(onListen, onCancel)
+        : new _AsyncBroadcastStreamController<T>(onListen, onCancel);
+  }
+
+  /**
+   * The callback which is called when the stream is listened to.
+   *
+   * May be set to `null`, in which case no callback will happen.
+   */
+  ControllerCallback get onListen;
+
+  void set onListen(void onListenHandler());
+
+  /**
+   * The callback which is called when the stream is paused.
+   *
+   * May be set to `null`, in which case no callback will happen.
+   *
+   * Pause related callbacks are not supported on broadcast stream controllers.
+   */
+  ControllerCallback get onPause;
+
+  void set onPause(void onPauseHandler());
+
+  /**
+   * The callback which is called when the stream is resumed.
+   *
+   * May be set to `null`, in which case no callback will happen.
+   *
+   * Pause related callbacks are not supported on broadcast stream controllers.
+   */
+  ControllerCallback get onResume;
+
+  void set onResume(void onResumeHandler());
+
+  /**
+   * The callback which is called when the stream is canceled.
+   *
+   * May be set to `null`, in which case no callback will happen.
+   */
+  ControllerCancelCallback get onCancel;
+
+  void set onCancel(onCancelHandler());
+
+  /**
+   * Returns a view of this object that only exposes the [StreamSink] interface.
+   */
+  StreamSink<T> get sink;
+
+  /**
+   * Whether the stream controller is closed for adding more events.
+   *
+   * The controller becomes closed by calling the [close] method.
+   * New events cannot be added, by calling [add] or [addError],
+   * to a closed controller.
+   *
+   * If the controller is closed,
+   * the "done" event might not have been delivered yet,
+   * but it has been scheduled, and it is too late to add more events.
+   */
+  bool get isClosed;
+
+  /**
+   * Whether the subscription would need to buffer events.
+   *
+   * This is the case if the controller's stream has a listener and it is
+   * paused, or if it has not received a listener yet. In that case, the
+   * controller is considered paused as well.
+   *
+   * A broadcast stream controller is never considered paused. It always
+   * forwards its events to all uncanceled subscriptions, if any,
+   * and let the subscriptions handle their own pausing and buffering.
+   */
+  bool get isPaused;
+
+  /** Whether there is a subscriber on the [Stream]. */
+  bool get hasListener;
+
+  /**
+   * Sends a data [event].
+   *
+   * Listeners receive this event in a later microtask.
+   *
+   * Note that a synchronous controller (created by passing true to the `sync`
+   * parameter of the `StreamController` constructor) delivers events
+   * immediately. Since this behavior violates the contract mentioned here,
+   * synchronous controllers should only be used as described in the
+   * documentation to ensure that the delivered events always *appear* as if
+   * they were delivered in a separate microtask.
+   */
+  void add(T event);
+
+  /**
+   * Sends or enqueues an error event.
+   *
+   * If [error] is `null`, it is replaced by a [NullThrownError].
+   *
+   * Listeners receive this event at a later microtask. This behavior can be
+   * overridden by using `sync` controllers. Note, however, that sync
+   * controllers have to satisfy the preconditions mentioned in the
+   * documentation of the constructors.
+   */
+  void addError(Object error, [StackTrace stackTrace]);
+
+  /**
+   * Closes the stream.
+   *
+   * Listeners receive the done event at a later microtask. This behavior can be
+   * overridden by using `sync` controllers. Note, however, that sync
+   * controllers have to satisfy the preconditions mentioned in the
+   * documentation of the constructors.
+   */
+  Future close();
+
+  /**
+   * Receives events from [source] and puts them into this controller's stream.
+   *
+   * Returns a future which completes when the source stream is done.
+   *
+   * Events must not be added directly to this controller using [add],
+   * [addError], [close] or [addStream], until the returned future
+   * is complete.
+   *
+   * Data and error events are forwarded to this controller's stream. A done
+   * event on the source will end the `addStream` operation and complete the
+   * returned future.
+   *
+   * If [cancelOnError] is true, only the first error on [source] is
+   * forwarded to the controller's stream, and the `addStream` ends
+   * after this. If [cancelOnError] is false, all errors are forwarded
+   * and only a done event will end the `addStream`.
+   * If [cancelOnError] is omitted, it defaults to false.
+   */
+  Future addStream(Stream<T> source, {bool cancelOnError});
+}
+
+/**
+ * A stream controller that delivers its events synchronously.
+ *
+ * A synchronous stream controller is intended for cases where
+ * an already asynchronous event triggers an event on a stream.
+ *
+ * Instead of adding the event to the stream in a later microtask,
+ * causing extra latency, the event is instead fired immediately by the
+ * synchronous stream controller, as if the stream event was
+ * the current event or microtask.
+ *
+ * The synchronous stream controller can be used to break the contract
+ * on [Stream], and it must be used carefully to avoid doing so.
+ *
+ * The only advantage to using a [SynchronousStreamController] over a
+ * normal [StreamController] is the improved latency.
+ * Only use the synchronous version if the improvement is significant,
+ * and if its use is safe. Otherwise just use a normal stream controller,
+ * which will always have the correct behavior for a [Stream], and won't
+ * accidentally break other code.
+ *
+ * Adding events to a synchronous controller should only happen as the
+ * very last part of the handling of the original event.
+ * At that point, adding an event to the stream is equivalent to
+ * returning to the event loop and adding the event in the next microtask.
+ *
+ * Each listener callback will be run as if it was a top-level event
+ * or microtask. This means that if it throws, the error will be reported as
+ * uncaught as soon as possible.
+ * This is one reason to add the event as the last thing in the original event
+ * handler - any action done after adding the event will delay the report of
+ * errors in the event listener callbacks.
+ *
+ * If an event is added in a setting that isn't known to be another event,
+ * it may cause the stream's listener to get that event before the listener
+ * is ready to handle it. We promise that after calling [Stream.listen],
+ * you won't get any events until the code doing the listen has completed.
+ * Calling [add] in response to a function call of unknown origin may break
+ * that promise.
+ *
+ * An [onListen] callback from the controller is *not* an asynchronous event,
+ * and adding events to the controller in the `onListen` callback is always
+ * wrong. The events will be delivered before the listener has even received
+ * the subscription yet.
+ *
+ * The synchronous broadcast stream controller also has a restrictions that a
+ * normal stream controller does not:
+ * The [add], [addError], [close] and [addStream] methods *must not* be
+ * called while an event is being delivered.
+ * That is, if a callback on a subscription on the controller's stream causes
+ * a call to any of the functions above, the call will fail.
+ * A broadcast stream may have more than one listener, and if an
+ * event is added synchronously while another is being also in the process
+ * of being added, the latter event might reach some listeners before
+ * the former. To prevent that, an event cannot be added while a previous
+ * event is being fired.
+ * This guarantees that an event is fully delivered when the
+ * first [add], [addError] or [close] returns,
+ * and further events will be delivered in the correct order.
+ *
+ * This still only guarantees that the event is delivered to the subscription.
+ * If the subscription is paused, the actual callback may still happen later,
+ * and the event will instead be buffered by the subscription.
+ * Barring pausing, and the following buffered events that haven't been
+ * delivered yet, callbacks will be called synchronously when an event is added.
+ *
+ * Adding an event to a synchronous non-broadcast stream controller while
+ * another event is in progress may cause the second event to be delayed
+ * and not be delivered synchronously, and until that event is delivered,
+ * the controller will not act synchronously.
+ */
+abstract class SynchronousStreamController<T> implements StreamController<T> {
+  /**
+   * Adds event to the controller's stream.
+   *
+   * As [StreamController.add], but must not be called while an event is
+   * being added by [add], [addError] or [close].
+   */
+  void add(T data);
+
+  /**
+   * Adds error to the controller's stream.
+   *
+   * As [StreamController.addError], but must not be called while an event is
+   * being added by [add], [addError] or [close].
+   */
+  void addError(Object error, [StackTrace stackTrace]);
+
+  /**
+   * Closes the controller's stream.
+   *
+   * As [StreamController.close], but must not be called while an event is
+   * being added by [add], [addError] or [close].
+   */
+  Future close();
+}
+
+abstract class _StreamControllerLifecycle<T> {
+  StreamSubscription<T> _subscribe(
+      void onData(T data), Function onError, void onDone(), bool cancelOnError);
+  void _recordPause(StreamSubscription<T> subscription) {}
+  void _recordResume(StreamSubscription<T> subscription) {}
+  Future _recordCancel(StreamSubscription<T> subscription) => null;
+}
+
+// Base type for implementations of stream controllers.
+abstract class _StreamControllerBase<T>
+    implements
+        StreamController<T>,
+        _StreamControllerLifecycle<T>,
+        _EventSink<T>,
+        _EventDispatch<T> {}
+
+/**
+ * Default implementation of [StreamController].
+ *
+ * Controls a stream that only supports a single controller.
+ */
+abstract class _StreamController<T> implements _StreamControllerBase<T> {
+  // The states are bit-flags. More than one can be set at a time.
+  //
+  // The "subscription state" goes through the states:
+  //   initial -> subscribed -> canceled.
+  // These are mutually exclusive.
+  // The "closed" state records whether the [close] method has been called
+  // on the controller. This can be done at any time. If done before
+  // subscription, the done event is queued. If done after cancel, the done
+  // event is ignored (just as any other event after a cancel).
+
+  /** The controller is in its initial state with no subscription. */
+  static const int _STATE_INITIAL = 0;
+  /** The controller has a subscription, but hasn't been closed or canceled. */
+  static const int _STATE_SUBSCRIBED = 1;
+  /** The subscription is canceled. */
+  static const int _STATE_CANCELED = 2;
+  /** Mask for the subscription state. */
+  static const int _STATE_SUBSCRIPTION_MASK = 3;
+
+  // The following state relate to the controller, not the subscription.
+  // If closed, adding more events is not allowed.
+  // If executing an [addStream], new events are not allowed either, but will
+  // be added by the stream.
+
+  /**
+   * The controller is closed due to calling [close].
+   *
+   * When the stream is closed, you can neither add new events nor add new
+   * listeners.
+   */
+  static const int _STATE_CLOSED = 4;
+  /**
+   * The controller is in the middle of an [addStream] operation.
+   *
+   * While adding events from a stream, no new events can be added directly
+   * on the controller.
+   */
+  static const int _STATE_ADDSTREAM = 8;
+
+  /**
+   * Field containing different data depending on the current subscription
+   * state.
+   *
+   * If [_state] is [_STATE_INITIAL], the field may contain a [_PendingEvents]
+   * for events added to the controller before a subscription.
+   *
+   * While [_state] is [_STATE_SUBSCRIBED], the field contains the subscription.
+   *
+   * When [_state] is [_STATE_CANCELED] the field is currently not used.
+   */
+  var _varData;
+
+  /** Current state of the controller. */
+  int _state = _STATE_INITIAL;
+
+  /**
+   * Future completed when the stream sends its last event.
+   *
+   * This is also the future returned by [close].
+   */
+  // TODO(lrn): Could this be stored in the varData field too, if it's not
+  // accessed until the call to "close"? Then we need to special case if it's
+  // accessed earlier, or if close is called before subscribing.
+  _Future _doneFuture;
+
+  ControllerCallback onListen;
+  ControllerCallback onPause;
+  ControllerCallback onResume;
+  ControllerCancelCallback onCancel;
+
+  _StreamController(this.onListen, this.onPause, this.onResume, this.onCancel);
+
+  // Return a new stream every time. The streams are equal, but not identical.
+  Stream<T> get stream => new _ControllerStream<T>(this);
+
+  /**
+   * Returns a view of this object that only exposes the [StreamSink] interface.
+   */
+  StreamSink<T> get sink => new _StreamSinkWrapper<T>(this);
+
+  /**
+   * Whether a listener has existed and been canceled.
+   *
+   * After this, adding more events will be ignored.
+   */
+  bool get _isCanceled => (_state & _STATE_CANCELED) != 0;
+
+  /** Whether there is an active listener. */
+  bool get hasListener => (_state & _STATE_SUBSCRIBED) != 0;
+
+  /** Whether there has not been a listener yet. */
+  bool get _isInitialState =>
+      (_state & _STATE_SUBSCRIPTION_MASK) == _STATE_INITIAL;
+
+  bool get isClosed => (_state & _STATE_CLOSED) != 0;
+
+  bool get isPaused =>
+      hasListener ? _subscription._isInputPaused : !_isCanceled;
+
+  bool get _isAddingStream => (_state & _STATE_ADDSTREAM) != 0;
+
+  /** New events may not be added after close, or during addStream. */
+  bool get _mayAddEvent => (_state < _STATE_CLOSED);
+
+  // Returns the pending events.
+  // Pending events are events added before a subscription exists.
+  // They are added to the subscription when it is created.
+  // Pending events, if any, are kept in the _varData field until the
+  // stream is listened to.
+  // While adding a stream, pending events are moved into the
+  // state object to allow the state object to use the _varData field.
+  _PendingEvents<T> get _pendingEvents {
+    assert(_isInitialState);
+    if (!_isAddingStream) {
+      return _varData;
+    }
+    _StreamControllerAddStreamState<T> state = _varData;
+    return state.varData;
+  }
+
+  // Returns the pending events, and creates the object if necessary.
+  _StreamImplEvents<T> _ensurePendingEvents() {
+    assert(_isInitialState);
+    if (!_isAddingStream) {
+      _varData ??= new _StreamImplEvents<T>();
+      return _varData;
+    }
+    _StreamControllerAddStreamState<T> state = _varData;
+    if (state.varData == null) state.varData = new _StreamImplEvents<T>();
+    return state.varData;
+  }
+
+  // Get the current subscription.
+  // If we are adding a stream, the subscription is moved into the state
+  // object to allow the state object to use the _varData field.
+  _ControllerSubscription<T> get _subscription {
+    assert(hasListener);
+    if (_isAddingStream) {
+      _StreamControllerAddStreamState<T> addState = _varData;
+      return addState.varData;
+    }
+    return _varData;
+  }
+
+  /**
+   * Creates an error describing why an event cannot be added.
+   *
+   * The reason, and therefore the error message, depends on the current state.
+   */
+  Error _badEventState() {
+    if (isClosed) {
+      return new StateError("Cannot add event after closing");
+    }
+    assert(_isAddingStream);
+    return new StateError("Cannot add event while adding a stream");
+  }
+
+  // StreamSink interface.
+  Future addStream(Stream<T> source, {bool cancelOnError}) {
+    if (!_mayAddEvent) throw _badEventState();
+    if (_isCanceled) return new _Future.immediate(null);
+    _StreamControllerAddStreamState<T> addState =
+        new _StreamControllerAddStreamState<T>(
+            this, _varData, source, cancelOnError ?? false);
+    _varData = addState;
+    _state |= _STATE_ADDSTREAM;
+    return addState.addStreamFuture;
+  }
+
+  /**
+   * Returns a future that is completed when the stream is done
+   * processing events.
+   *
+   * This happens either when the done event has been sent, or if the
+   * subscriber of a single-subscription stream is cancelled.
+   */
+  Future get done => _ensureDoneFuture();
+
+  Future _ensureDoneFuture() {
+    _doneFuture ??= _isCanceled ? Future._nullFuture : new _Future();
+    return _doneFuture;
+  }
+
+  /**
+   * Send or enqueue a data event.
+   */
+  void add(T value) {
+    if (!_mayAddEvent) throw _badEventState();
+    _add(value);
+  }
+
+  /**
+   * Send or enqueue an error event.
+   */
+  void addError(Object error, [StackTrace stackTrace]) {
+    if (!_mayAddEvent) throw _badEventState();
+    error = _nonNullError(error);
+    AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
+    if (replacement != null) {
+      error = _nonNullError(replacement.error);
+      stackTrace = replacement.stackTrace;
+    }
+    _addError(error, stackTrace);
+  }
+
+  /**
+   * Closes this controller and sends a done event on the stream.
+   *
+   * The first time a controller is closed, a "done" event is added to its
+   * stream.
+   *
+   * You are allowed to close the controller more than once, but only the first
+   * call has any effect.
+   *
+   * After closing, no further events may be added using [add], [addError]
+   * or [addStream].
+   *
+   * The returned future is completed when the done event has been delivered.
+   */
+  Future close() {
+    if (isClosed) {
+      return _ensureDoneFuture();
+    }
+    if (!_mayAddEvent) throw _badEventState();
+    _closeUnchecked();
+    return _ensureDoneFuture();
+  }
+
+  void _closeUnchecked() {
+    _state |= _STATE_CLOSED;
+    if (hasListener) {
+      _sendDone();
+    } else if (_isInitialState) {
+      _ensurePendingEvents().add(const _DelayedDone());
+    }
+  }
+
+  // EventSink interface. Used by the [addStream] events.
+
+  // Add data event, used both by the [addStream] events and by [add].
+  void _add(T value) {
+    if (hasListener) {
+      _sendData(value);
+    } else if (_isInitialState) {
+      _ensurePendingEvents().add(new _DelayedData<T>(value));
+    }
+  }
+
+  void _addError(Object error, StackTrace stackTrace) {
+    if (hasListener) {
+      _sendError(error, stackTrace);
+    } else if (_isInitialState) {
+      _ensurePendingEvents().add(new _DelayedError(error, stackTrace));
+    }
+  }
+
+  void _close() {
+    // End of addStream stream.
+    assert(_isAddingStream);
+    _StreamControllerAddStreamState<T> addState = _varData;
+    _varData = addState.varData;
+    _state &= ~_STATE_ADDSTREAM;
+    addState.complete();
+  }
+
+  // _StreamControllerLifeCycle interface
+
+  StreamSubscription<T> _subscribe(void onData(T data), Function onError,
+      void onDone(), bool cancelOnError) {
+    if (!_isInitialState) {
+      throw new StateError("Stream has already been listened to.");
+    }
+    _ControllerSubscription<T> subscription = new _ControllerSubscription<T>(
+        this, onData, onError, onDone, cancelOnError);
+
+    _PendingEvents<T> pendingEvents = _pendingEvents;
+    _state |= _STATE_SUBSCRIBED;
+    if (_isAddingStream) {
+      _StreamControllerAddStreamState<T> addState = _varData;
+      addState.varData = subscription;
+      addState.resume();
+    } else {
+      _varData = subscription;
+    }
+    subscription._setPendingEvents(pendingEvents);
+    subscription._guardCallback(() {
+      _runGuarded(onListen);
+    });
+
+    return subscription;
+  }
+
+  Future _recordCancel(StreamSubscription<T> subscription) {
+    // When we cancel, we first cancel any stream being added,
+    // Then we call `onCancel`, and finally the _doneFuture is completed.
+    // If either of addStream's cancel or `onCancel` returns a future,
+    // we wait for it before continuing.
+    // Any error during this process ends up in the returned future.
+    // If more errors happen, we act as if it happens inside nested try/finallys
+    // or whenComplete calls, and only the last error ends up in the
+    // returned future.
+    Future result;
+    if (_isAddingStream) {
+      _StreamControllerAddStreamState<T> addState = _varData;
+      result = addState.cancel();
+    }
+    _varData = null;
+    _state =
+        (_state & ~(_STATE_SUBSCRIBED | _STATE_ADDSTREAM)) | _STATE_CANCELED;
+
+    if (onCancel != null) {
+      if (result == null) {
+        // Only introduce a future if one is needed.
+        // If _onCancel returns null, no future is needed.
+        try {
+          result = onCancel();
+        } catch (e, s) {
+          // Return the error in the returned future.
+          // Complete it asynchronously, so there is time for a listener
+          // to handle the error.
+          result = new _Future().._asyncCompleteError(e, s);
+        }
+      } else {
+        // Simpler case when we already know that we will return a future.
+        result = result.whenComplete(onCancel);
+      }
+    }
+
+    void complete() {
+      if (_doneFuture != null && _doneFuture._mayComplete) {
+        _doneFuture._asyncComplete(null);
+      }
+    }
+
+    if (result != null) {
+      result = result.whenComplete(complete);
+    } else {
+      complete();
+    }
+
+    return result;
+  }
+
+  void _recordPause(StreamSubscription<T> subscription) {
+    if (_isAddingStream) {
+      _StreamControllerAddStreamState<T> addState = _varData;
+      addState.pause();
+    }
+    _runGuarded(onPause);
+  }
+
+  void _recordResume(StreamSubscription<T> subscription) {
+    if (_isAddingStream) {
+      _StreamControllerAddStreamState<T> addState = _varData;
+      addState.resume();
+    }
+    _runGuarded(onResume);
+  }
+}
+
+abstract class _SyncStreamControllerDispatch<T>
+    implements _StreamController<T>, SynchronousStreamController<T> {
+  int get _state;
+  void set _state(int state);
+
+  void _sendData(T data) {
+    _subscription._add(data);
+  }
+
+  void _sendError(Object error, StackTrace stackTrace) {
+    _subscription._addError(error, stackTrace);
+  }
+
+  void _sendDone() {
+    _subscription._close();
+  }
+}
+
+abstract class _AsyncStreamControllerDispatch<T>
+    implements _StreamController<T> {
+  void _sendData(T data) {
+    _subscription._addPending(new _DelayedData<T>(data));
+  }
+
+  void _sendError(Object error, StackTrace stackTrace) {
+    _subscription._addPending(new _DelayedError(error, stackTrace));
+  }
+
+  void _sendDone() {
+    _subscription._addPending(const _DelayedDone());
+  }
+}
+
+// TODO(lrn): Use common superclass for callback-controllers when VM supports
+// constructors in mixin superclasses.
+
+class _AsyncStreamController<T> = _StreamController<T>
+    with _AsyncStreamControllerDispatch<T>;
+
+class _SyncStreamController<T> = _StreamController<T>
+    with _SyncStreamControllerDispatch<T>;
+
+typedef _NotificationHandler();
+
+void _runGuarded(_NotificationHandler notificationHandler) {
+  if (notificationHandler == null) return;
+  try {
+    notificationHandler();
+  } catch (e, s) {
+    Zone.current.handleUncaughtError(e, s);
+  }
+}
+
+class _ControllerStream<T> extends _StreamImpl<T> {
+  _StreamControllerLifecycle<T> _controller;
+
+  _ControllerStream(this._controller);
+
+  StreamSubscription<T> _createSubscription(void onData(T data),
+          Function onError, void onDone(), bool cancelOnError) =>
+      _controller._subscribe(onData, onError, onDone, cancelOnError);
+
+  // Override == and hashCode so that new streams returned by the same
+  // controller are considered equal. The controller returns a new stream
+  // each time it's queried, but doesn't have to cache the result.
+
+  int get hashCode => _controller.hashCode ^ 0x35323532;
+
+  bool operator ==(Object other) {
+    if (identical(this, other)) return true;
+    return other is _ControllerStream &&
+        identical(other._controller, this._controller);
+  }
+}
+
+class _ControllerSubscription<T> extends _BufferingStreamSubscription<T> {
+  final _StreamControllerLifecycle<T> _controller;
+
+  _ControllerSubscription(this._controller, void onData(T data),
+      Function onError, void onDone(), bool cancelOnError)
+      : super(onData, onError, onDone, cancelOnError);
+
+  Future _onCancel() {
+    return _controller._recordCancel(this);
+  }
+
+  void _onPause() {
+    _controller._recordPause(this);
+  }
+
+  void _onResume() {
+    _controller._recordResume(this);
+  }
+}
+
+/** A class that exposes only the [StreamSink] interface of an object. */
+class _StreamSinkWrapper<T> implements StreamSink<T> {
+  final StreamController _target;
+  _StreamSinkWrapper(this._target);
+  void add(T data) {
+    _target.add(data);
+  }
+
+  void addError(Object error, [StackTrace stackTrace]) {
+    _target.addError(error, stackTrace);
+  }
+
+  Future close() => _target.close();
+
+  Future addStream(Stream<T> source) => _target.addStream(source);
+
+  Future get done => _target.done;
+}
+
+/**
+ * Object containing the state used to handle [StreamController.addStream].
+ */
+class _AddStreamState<T> {
+  // [_Future] returned by call to addStream.
+  final _Future addStreamFuture;
+
+  // Subscription on stream argument to addStream.
+  final StreamSubscription addSubscription;
+
+  _AddStreamState(
+      _EventSink<T> controller, Stream<T> source, bool cancelOnError)
+      : addStreamFuture = new _Future(),
+        addSubscription = source.listen(controller._add,
+            onError: cancelOnError
+                ? makeErrorHandler(controller)
+                : controller._addError,
+            onDone: controller._close,
+            cancelOnError: cancelOnError);
+
+  static makeErrorHandler(_EventSink controller) => (e, StackTrace s) {
+        controller._addError(e, s);
+        controller._close();
+      };
+
+  void pause() {
+    addSubscription.pause();
+  }
+
+  void resume() {
+    addSubscription.resume();
+  }
+
+  /**
+   * Stop adding the stream.
+   *
+   * Complete the future returned by `StreamController.addStream` when
+   * the cancel is complete.
+   *
+   * Return a future if the cancel takes time, otherwise return `null`.
+   */
+  Future cancel() {
+    var cancel = addSubscription.cancel();
+    if (cancel == null) {
+      addStreamFuture._asyncComplete(null);
+      return null;
+    }
+    return cancel.whenComplete(() {
+      addStreamFuture._asyncComplete(null);
+    });
+  }
+
+  void complete() {
+    addStreamFuture._asyncComplete(null);
+  }
+}
+
+class _StreamControllerAddStreamState<T> extends _AddStreamState<T> {
+  // The subscription or pending data of a _StreamController.
+  // Stored here because we reuse the `_varData` field  in the _StreamController
+  // to store this state object.
+  var varData;
+
+  _StreamControllerAddStreamState(_StreamController<T> controller, this.varData,
+      Stream<T> source, bool cancelOnError)
+      : super(controller, source, cancelOnError) {
+    if (controller.isPaused) {
+      addSubscription.pause();
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/async/stream_impl.dart b/sdk_nnbd/lib/async/stream_impl.dart
new file mode 100644
index 0000000..14c84a5
--- /dev/null
+++ b/sdk_nnbd/lib/async/stream_impl.dart
@@ -0,0 +1,1062 @@
+// Copyright (c) 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 dart.async;
+
+/** Abstract and private interface for a place to put events. */
+abstract class _EventSink<T> {
+  void _add(T data);
+  void _addError(Object error, StackTrace stackTrace);
+  void _close();
+}
+
+/**
+ * Abstract and private interface for a place to send events.
+ *
+ * Used by event buffering to finally dispatch the pending event, where
+ * [_EventSink] is where the event first enters the stream subscription,
+ * and may yet be buffered.
+ */
+abstract class _EventDispatch<T> {
+  void _sendData(T data);
+  void _sendError(Object error, StackTrace stackTrace);
+  void _sendDone();
+}
+
+/**
+ * Default implementation of stream subscription of buffering events.
+ *
+ * The only public methods are those of [StreamSubscription], so instances of
+ * [_BufferingStreamSubscription] can be returned directly as a
+ * [StreamSubscription] without exposing internal functionality.
+ *
+ * The [StreamController] is a public facing version of [Stream] and this class,
+ * with some methods made public.
+ *
+ * The user interface of [_BufferingStreamSubscription] are the following
+ * methods:
+ *
+ * * [_add]: Add a data event to the stream.
+ * * [_addError]: Add an error event to the stream.
+ * * [_close]: Request to close the stream.
+ * * [_onCancel]: Called when the subscription will provide no more events,
+ *     either due to being actively canceled, or after sending a done event.
+ * * [_onPause]: Called when the subscription wants the event source to pause.
+ * * [_onResume]: Called when allowing new events after a pause.
+ *
+ * The user should not add new events when the subscription requests a paused,
+ * but if it happens anyway, the subscription will enqueue the events just as
+ * when new events arrive while still firing an old event.
+ */
+class _BufferingStreamSubscription<T>
+    implements StreamSubscription<T>, _EventSink<T>, _EventDispatch<T> {
+  /** The `cancelOnError` flag from the `listen` call. */
+  static const int _STATE_CANCEL_ON_ERROR = 1;
+  /**
+   * Whether the "done" event has been received.
+   * No further events are accepted after this.
+   */
+  static const int _STATE_CLOSED = 2;
+  /**
+   * Set if the input has been asked not to send events.
+   *
+   * This is not the same as being paused, since the input will remain paused
+   * after a call to [resume] if there are pending events.
+   */
+  static const int _STATE_INPUT_PAUSED = 4;
+  /**
+   * Whether the subscription has been canceled.
+   *
+   * Set by calling [cancel], or by handling a "done" event, or an "error" event
+   * when `cancelOnError` is true.
+   */
+  static const int _STATE_CANCELED = 8;
+  /**
+   * Set when either:
+   *
+   *   * an error is sent, and [cancelOnError] is true, or
+   *   * a done event is sent.
+   *
+   * If the subscription is canceled while _STATE_WAIT_FOR_CANCEL is set, the
+   * state is unset, and no further events must be delivered.
+   */
+  static const int _STATE_WAIT_FOR_CANCEL = 16;
+  static const int _STATE_IN_CALLBACK = 32;
+  static const int _STATE_HAS_PENDING = 64;
+  static const int _STATE_PAUSE_COUNT = 128;
+
+  /* Event handlers provided in constructor. */
+  _DataHandler<T> _onData;
+  Function _onError;
+  _DoneHandler _onDone;
+  final Zone _zone = Zone.current;
+
+  /** Bit vector based on state-constants above. */
+  int _state;
+
+  // TODO(floitsch): reuse another field
+  /** The future [_onCancel] may return. */
+  Future _cancelFuture;
+
+  /**
+   * Queue of pending events.
+   *
+   * Is created when necessary, or set in constructor for preconfigured events.
+   */
+  _PendingEvents<T> _pending;
+
+  _BufferingStreamSubscription(
+      void onData(T data), Function onError, void onDone(), bool cancelOnError)
+      : _state = (cancelOnError ? _STATE_CANCEL_ON_ERROR : 0) {
+    this.onData(onData);
+    this.onError(onError);
+    this.onDone(onDone);
+  }
+
+  /**
+   * Sets the subscription's pending events object.
+   *
+   * This can only be done once. The pending events object is used for the
+   * rest of the subscription's life cycle.
+   */
+  void _setPendingEvents(_PendingEvents<T> pendingEvents) {
+    assert(_pending == null);
+    if (pendingEvents == null) return;
+    _pending = pendingEvents;
+    if (!pendingEvents.isEmpty) {
+      _state |= _STATE_HAS_PENDING;
+      _pending.schedule(this);
+    }
+  }
+
+  // StreamSubscription interface.
+
+  void onData(void handleData(T event)) {
+    handleData ??= _nullDataHandler;
+    // TODO(floitsch): the return type should be 'void', and the type
+    // should be inferred.
+    _onData = _zone.registerUnaryCallback<dynamic, T>(handleData);
+  }
+
+  void onError(Function handleError) {
+    handleError ??= _nullErrorHandler;
+    if (handleError is void Function(Object, StackTrace)) {
+      _onError = _zone
+          .registerBinaryCallback<dynamic, Object, StackTrace>(handleError);
+    } else if (handleError is void Function(Object)) {
+      _onError = _zone.registerUnaryCallback<dynamic, Object>(handleError);
+    } else {
+      throw new ArgumentError("handleError callback must take either an Object "
+          "(the error), or both an Object (the error) and a StackTrace.");
+    }
+  }
+
+  void onDone(void handleDone()) {
+    handleDone ??= _nullDoneHandler;
+    _onDone = _zone.registerCallback(handleDone);
+  }
+
+  void pause([Future resumeSignal]) {
+    if (_isCanceled) return;
+    bool wasPaused = _isPaused;
+    bool wasInputPaused = _isInputPaused;
+    // Increment pause count and mark input paused (if it isn't already).
+    _state = (_state + _STATE_PAUSE_COUNT) | _STATE_INPUT_PAUSED;
+    if (resumeSignal != null) resumeSignal.whenComplete(resume);
+    if (!wasPaused && _pending != null) _pending.cancelSchedule();
+    if (!wasInputPaused && !_inCallback) _guardCallback(_onPause);
+  }
+
+  void resume() {
+    if (_isCanceled) return;
+    if (_isPaused) {
+      _decrementPauseCount();
+      if (!_isPaused) {
+        if (_hasPending && !_pending.isEmpty) {
+          // Input is still paused.
+          _pending.schedule(this);
+        } else {
+          assert(_mayResumeInput);
+          _state &= ~_STATE_INPUT_PAUSED;
+          if (!_inCallback) _guardCallback(_onResume);
+        }
+      }
+    }
+  }
+
+  Future cancel() {
+    // The user doesn't want to receive any further events. If there is an
+    // error or done event pending (waiting for the cancel to be done) discard
+    // that event.
+    _state &= ~_STATE_WAIT_FOR_CANCEL;
+    if (!_isCanceled) {
+      _cancel();
+    }
+    return _cancelFuture ?? Future._nullFuture;
+  }
+
+  Future<E> asFuture<E>([E futureValue]) {
+    _Future<E> result = new _Future<E>();
+
+    // Overwrite the onDone and onError handlers.
+    _onDone = () {
+      result._complete(futureValue);
+    };
+    _onError = (error, StackTrace stackTrace) {
+      Future cancelFuture = cancel();
+      if (!identical(cancelFuture, Future._nullFuture)) {
+        cancelFuture.whenComplete(() {
+          result._completeError(error, stackTrace);
+        });
+      } else {
+        result._completeError(error, stackTrace);
+      }
+    };
+
+    return result;
+  }
+
+  // State management.
+
+  bool get _isInputPaused => (_state & _STATE_INPUT_PAUSED) != 0;
+  bool get _isClosed => (_state & _STATE_CLOSED) != 0;
+  bool get _isCanceled => (_state & _STATE_CANCELED) != 0;
+  bool get _waitsForCancel => (_state & _STATE_WAIT_FOR_CANCEL) != 0;
+  bool get _inCallback => (_state & _STATE_IN_CALLBACK) != 0;
+  bool get _hasPending => (_state & _STATE_HAS_PENDING) != 0;
+  bool get _isPaused => _state >= _STATE_PAUSE_COUNT;
+  bool get _canFire => _state < _STATE_IN_CALLBACK;
+  bool get _mayResumeInput =>
+      !_isPaused && (_pending == null || _pending.isEmpty);
+  bool get _cancelOnError => (_state & _STATE_CANCEL_ON_ERROR) != 0;
+
+  bool get isPaused => _isPaused;
+
+  void _cancel() {
+    _state |= _STATE_CANCELED;
+    if (_hasPending) {
+      _pending.cancelSchedule();
+    }
+    if (!_inCallback) _pending = null;
+    _cancelFuture = _onCancel();
+  }
+
+  /**
+   * Decrements the pause count.
+   *
+   * Does not automatically unpause the input (call [_onResume]) when
+   * the pause count reaches zero. This is handled elsewhere, and only
+   * if there are no pending events buffered.
+   */
+  void _decrementPauseCount() {
+    assert(_isPaused);
+    _state -= _STATE_PAUSE_COUNT;
+  }
+
+  // _EventSink interface.
+
+  void _add(T data) {
+    assert(!_isClosed);
+    if (_isCanceled) return;
+    if (_canFire) {
+      _sendData(data);
+    } else {
+      _addPending(new _DelayedData<T>(data));
+    }
+  }
+
+  void _addError(Object error, StackTrace stackTrace) {
+    if (_isCanceled) return;
+    if (_canFire) {
+      _sendError(error, stackTrace); // Reports cancel after sending.
+    } else {
+      _addPending(new _DelayedError(error, stackTrace));
+    }
+  }
+
+  void _close() {
+    assert(!_isClosed);
+    if (_isCanceled) return;
+    _state |= _STATE_CLOSED;
+    if (_canFire) {
+      _sendDone();
+    } else {
+      _addPending(const _DelayedDone());
+    }
+  }
+
+  // Hooks called when the input is paused, unpaused or canceled.
+  // These must not throw. If overwritten to call user code, include suitable
+  // try/catch wrapping and send any errors to
+  // [_Zone.current.handleUncaughtError].
+  void _onPause() {
+    assert(_isInputPaused);
+  }
+
+  void _onResume() {
+    assert(!_isInputPaused);
+  }
+
+  Future _onCancel() {
+    assert(_isCanceled);
+    return null;
+  }
+
+  // Handle pending events.
+
+  /**
+   * Add a pending event.
+   *
+   * If the subscription is not paused, this also schedules a firing
+   * of pending events later (if necessary).
+   */
+  void _addPending(_DelayedEvent event) {
+    _StreamImplEvents<T> pending = _pending;
+    if (_pending == null) {
+      pending = _pending = new _StreamImplEvents<T>();
+    }
+    pending.add(event);
+    if (!_hasPending) {
+      _state |= _STATE_HAS_PENDING;
+      if (!_isPaused) {
+        _pending.schedule(this);
+      }
+    }
+  }
+
+  /* _EventDispatch interface. */
+
+  void _sendData(T data) {
+    assert(!_isCanceled);
+    assert(!_isPaused);
+    assert(!_inCallback);
+    bool wasInputPaused = _isInputPaused;
+    _state |= _STATE_IN_CALLBACK;
+    _zone.runUnaryGuarded(_onData, data);
+    _state &= ~_STATE_IN_CALLBACK;
+    _checkState(wasInputPaused);
+  }
+
+  void _sendError(Object error, StackTrace stackTrace) {
+    assert(!_isCanceled);
+    assert(!_isPaused);
+    assert(!_inCallback);
+    bool wasInputPaused = _isInputPaused;
+
+    void sendError() {
+      // If the subscription has been canceled while waiting for the cancel
+      // future to finish we must not report the error.
+      if (_isCanceled && !_waitsForCancel) return;
+      _state |= _STATE_IN_CALLBACK;
+      // TODO(floitsch): this dynamic should be 'void'.
+      var onError = _onError;
+      if (onError is void Function(Object, StackTrace)) {
+        _zone.runBinaryGuarded<Object, StackTrace>(onError, error, stackTrace);
+      } else {
+        assert(_onError is void Function(Object));
+        _zone.runUnaryGuarded<Object>(_onError, error);
+      }
+      _state &= ~_STATE_IN_CALLBACK;
+    }
+
+    if (_cancelOnError) {
+      _state |= _STATE_WAIT_FOR_CANCEL;
+      _cancel();
+      if (_cancelFuture != null &&
+          !identical(_cancelFuture, Future._nullFuture)) {
+        _cancelFuture.whenComplete(sendError);
+      } else {
+        sendError();
+      }
+    } else {
+      sendError();
+      // Only check state if not cancelOnError.
+      _checkState(wasInputPaused);
+    }
+  }
+
+  void _sendDone() {
+    assert(!_isCanceled);
+    assert(!_isPaused);
+    assert(!_inCallback);
+
+    void sendDone() {
+      // If the subscription has been canceled while waiting for the cancel
+      // future to finish we must not report the done event.
+      if (!_waitsForCancel) return;
+      _state |= (_STATE_CANCELED | _STATE_CLOSED | _STATE_IN_CALLBACK);
+      _zone.runGuarded(_onDone);
+      _state &= ~_STATE_IN_CALLBACK;
+    }
+
+    _cancel();
+    _state |= _STATE_WAIT_FOR_CANCEL;
+    if (_cancelFuture != null &&
+        !identical(_cancelFuture, Future._nullFuture)) {
+      _cancelFuture.whenComplete(sendDone);
+    } else {
+      sendDone();
+    }
+  }
+
+  /**
+   * Call a hook function.
+   *
+   * The call is properly wrapped in code to avoid other callbacks
+   * during the call, and it checks for state changes after the call
+   * that should cause further callbacks.
+   */
+  void _guardCallback(void callback()) {
+    assert(!_inCallback);
+    bool wasInputPaused = _isInputPaused;
+    _state |= _STATE_IN_CALLBACK;
+    callback();
+    _state &= ~_STATE_IN_CALLBACK;
+    _checkState(wasInputPaused);
+  }
+
+  /**
+   * Check if the input needs to be informed of state changes.
+   *
+   * State changes are pausing, resuming and canceling.
+   *
+   * After canceling, no further callbacks will happen.
+   *
+   * The cancel callback is called after a user cancel, or after
+   * the final done event is sent.
+   */
+  void _checkState(bool wasInputPaused) {
+    assert(!_inCallback);
+    if (_hasPending && _pending.isEmpty) {
+      _state &= ~_STATE_HAS_PENDING;
+      if (_isInputPaused && _mayResumeInput) {
+        _state &= ~_STATE_INPUT_PAUSED;
+      }
+    }
+    // If the state changes during a callback, we immediately
+    // make a new state-change callback. Loop until the state didn't change.
+    while (true) {
+      if (_isCanceled) {
+        _pending = null;
+        return;
+      }
+      bool isInputPaused = _isInputPaused;
+      if (wasInputPaused == isInputPaused) break;
+      _state ^= _STATE_IN_CALLBACK;
+      if (isInputPaused) {
+        _onPause();
+      } else {
+        _onResume();
+      }
+      _state &= ~_STATE_IN_CALLBACK;
+      wasInputPaused = isInputPaused;
+    }
+    if (_hasPending && !_isPaused) {
+      _pending.schedule(this);
+    }
+  }
+}
+
+// -------------------------------------------------------------------
+// Common base class for single and multi-subscription streams.
+// -------------------------------------------------------------------
+abstract class _StreamImpl<T> extends Stream<T> {
+  // ------------------------------------------------------------------
+  // Stream interface.
+
+  StreamSubscription<T> listen(void onData(T data),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    cancelOnError = identical(true, cancelOnError);
+    StreamSubscription<T> subscription =
+        _createSubscription(onData, onError, onDone, cancelOnError);
+    _onListen(subscription);
+    return subscription;
+  }
+
+  // -------------------------------------------------------------------
+  /** Create a subscription object. Called by [subcribe]. */
+  StreamSubscription<T> _createSubscription(void onData(T data),
+      Function onError, void onDone(), bool cancelOnError) {
+    return new _BufferingStreamSubscription<T>(
+        onData, onError, onDone, cancelOnError);
+  }
+
+  /** Hook called when the subscription has been created. */
+  void _onListen(StreamSubscription subscription) {}
+}
+
+typedef _PendingEvents<T> _EventGenerator<T>();
+
+/** Stream that generates its own events. */
+class _GeneratedStreamImpl<T> extends _StreamImpl<T> {
+  final _EventGenerator<T> _pending;
+  bool _isUsed = false;
+  /**
+   * Initializes the stream to have only the events provided by a
+   * [_PendingEvents].
+   *
+   * A new [_PendingEvents] must be generated for each listen.
+   */
+  _GeneratedStreamImpl(this._pending);
+
+  StreamSubscription<T> _createSubscription(void onData(T data),
+      Function onError, void onDone(), bool cancelOnError) {
+    if (_isUsed) throw new StateError("Stream has already been listened to.");
+    _isUsed = true;
+    return new _BufferingStreamSubscription<T>(
+        onData, onError, onDone, cancelOnError)
+      .._setPendingEvents(_pending());
+  }
+}
+
+/** Pending events object that gets its events from an [Iterable]. */
+class _IterablePendingEvents<T> extends _PendingEvents<T> {
+  // The iterator providing data for data events.
+  // Set to null when iteration has completed.
+  Iterator<T> _iterator;
+
+  _IterablePendingEvents(Iterable<T> data) : _iterator = data.iterator;
+
+  bool get isEmpty => _iterator == null;
+
+  void handleNext(_EventDispatch<T> dispatch) {
+    if (_iterator == null) {
+      throw new StateError("No events pending.");
+    }
+    // Send one event per call to moveNext.
+    // If moveNext returns true, send the current element as data.
+    // If current throws, send that error, but keep iterating.
+    // If moveNext returns false, send a done event and clear the _iterator.
+    // If moveNext throws an error, send an error and prepare to send a done
+    // event afterwards.
+    bool hasMore;
+    try {
+      hasMore = _iterator.moveNext();
+      if (hasMore) {
+        dispatch._sendData(_iterator.current);
+      } else {
+        _iterator = null;
+        dispatch._sendDone();
+      }
+    } catch (e, s) {
+      if (hasMore == null) {
+        // Threw in .moveNext().
+        // Ensure that we send a done afterwards.
+        _iterator = const EmptyIterator<Null>();
+        dispatch._sendError(e, s);
+      } else {
+        // Threw in .current.
+        dispatch._sendError(e, s);
+      }
+    }
+  }
+
+  void clear() {
+    if (isScheduled) cancelSchedule();
+    _iterator = null;
+  }
+}
+
+// Internal helpers.
+
+// Types of the different handlers on a stream. Types used to type fields.
+typedef void _DataHandler<T>(T value);
+typedef void _DoneHandler();
+
+/** Default data handler, does nothing. */
+void _nullDataHandler(Object value) {}
+
+/** Default error handler, reports the error to the current zone's handler. */
+void _nullErrorHandler(Object error, [StackTrace stackTrace]) {
+  Zone.current.handleUncaughtError(error, stackTrace);
+}
+
+/** Default done handler, does nothing. */
+void _nullDoneHandler() {}
+
+/** A delayed event on a buffering stream subscription. */
+abstract class _DelayedEvent<T> {
+  /** Added as a linked list on the [StreamController]. */
+  _DelayedEvent next;
+  /** Execute the delayed event on the [StreamController]. */
+  void perform(_EventDispatch<T> dispatch);
+}
+
+/** A delayed data event. */
+class _DelayedData<T> extends _DelayedEvent<T> {
+  final T value;
+  _DelayedData(this.value);
+  void perform(_EventDispatch<T> dispatch) {
+    dispatch._sendData(value);
+  }
+}
+
+/** A delayed error event. */
+class _DelayedError extends _DelayedEvent {
+  final error;
+  final StackTrace stackTrace;
+
+  _DelayedError(this.error, this.stackTrace);
+  void perform(_EventDispatch dispatch) {
+    dispatch._sendError(error, stackTrace);
+  }
+}
+
+/** A delayed done event. */
+class _DelayedDone implements _DelayedEvent {
+  const _DelayedDone();
+  void perform(_EventDispatch dispatch) {
+    dispatch._sendDone();
+  }
+
+  _DelayedEvent get next => null;
+
+  void set next(_DelayedEvent _) {
+    throw new StateError("No events after a done.");
+  }
+}
+
+/** Superclass for provider of pending events. */
+abstract class _PendingEvents<T> {
+  // No async event has been scheduled.
+  static const int _STATE_UNSCHEDULED = 0;
+  // An async event has been scheduled to run a function.
+  static const int _STATE_SCHEDULED = 1;
+  // An async event has been scheduled, but it will do nothing when it runs.
+  // Async events can't be preempted.
+  static const int _STATE_CANCELED = 3;
+
+  /**
+   * State of being scheduled.
+   *
+   * Set to [_STATE_SCHEDULED] when pending events are scheduled for
+   * async dispatch. Since we can't cancel a [scheduleMicrotask] call, if
+   * scheduling is "canceled", the _state is simply set to [_STATE_CANCELED]
+   * which will make the async code do nothing except resetting [_state].
+   *
+   * If events are scheduled while the state is [_STATE_CANCELED], it is
+   * merely switched back to [_STATE_SCHEDULED], but no new call to
+   * [scheduleMicrotask] is performed.
+   */
+  int _state = _STATE_UNSCHEDULED;
+
+  bool get isEmpty;
+
+  bool get isScheduled => _state == _STATE_SCHEDULED;
+  bool get _eventScheduled => _state >= _STATE_SCHEDULED;
+
+  /**
+   * Schedule an event to run later.
+   *
+   * If called more than once, it should be called with the same dispatch as
+   * argument each time. It may reuse an earlier argument in some cases.
+   */
+  void schedule(_EventDispatch<T> dispatch) {
+    if (isScheduled) return;
+    assert(!isEmpty);
+    if (_eventScheduled) {
+      assert(_state == _STATE_CANCELED);
+      _state = _STATE_SCHEDULED;
+      return;
+    }
+    scheduleMicrotask(() {
+      int oldState = _state;
+      _state = _STATE_UNSCHEDULED;
+      if (oldState == _STATE_CANCELED) return;
+      handleNext(dispatch);
+    });
+    _state = _STATE_SCHEDULED;
+  }
+
+  void cancelSchedule() {
+    if (isScheduled) _state = _STATE_CANCELED;
+  }
+
+  void handleNext(_EventDispatch<T> dispatch);
+
+  /** Throw away any pending events and cancel scheduled events. */
+  void clear();
+}
+
+/** Class holding pending events for a [_StreamImpl]. */
+class _StreamImplEvents<T> extends _PendingEvents<T> {
+  /// Single linked list of [_DelayedEvent] objects.
+  _DelayedEvent firstPendingEvent;
+
+  /// Last element in the list of pending events. New events are added after it.
+  _DelayedEvent lastPendingEvent;
+
+  bool get isEmpty => lastPendingEvent == null;
+
+  void add(_DelayedEvent event) {
+    if (lastPendingEvent == null) {
+      firstPendingEvent = lastPendingEvent = event;
+    } else {
+      lastPendingEvent = lastPendingEvent.next = event;
+    }
+  }
+
+  void handleNext(_EventDispatch<T> dispatch) {
+    assert(!isScheduled);
+    _DelayedEvent event = firstPendingEvent;
+    firstPendingEvent = event.next;
+    if (firstPendingEvent == null) {
+      lastPendingEvent = null;
+    }
+    event.perform(dispatch);
+  }
+
+  void clear() {
+    if (isScheduled) cancelSchedule();
+    firstPendingEvent = lastPendingEvent = null;
+  }
+}
+
+typedef void _BroadcastCallback<T>(StreamSubscription<T> subscription);
+
+/**
+ * Done subscription that will send one done event as soon as possible.
+ */
+class _DoneStreamSubscription<T> implements StreamSubscription<T> {
+  static const int _DONE_SENT = 1;
+  static const int _SCHEDULED = 2;
+  static const int _PAUSED = 4;
+
+  final Zone _zone;
+  int _state = 0;
+  _DoneHandler _onDone;
+
+  _DoneStreamSubscription(this._onDone) : _zone = Zone.current {
+    _schedule();
+  }
+
+  bool get _isSent => (_state & _DONE_SENT) != 0;
+  bool get _isScheduled => (_state & _SCHEDULED) != 0;
+  bool get isPaused => _state >= _PAUSED;
+
+  void _schedule() {
+    if (_isScheduled) return;
+    _zone.scheduleMicrotask(_sendDone);
+    _state |= _SCHEDULED;
+  }
+
+  void onData(void handleData(T data)) {}
+  void onError(Function handleError) {}
+  void onDone(void handleDone()) {
+    _onDone = handleDone;
+  }
+
+  void pause([Future resumeSignal]) {
+    _state += _PAUSED;
+    if (resumeSignal != null) resumeSignal.whenComplete(resume);
+  }
+
+  void resume() {
+    if (isPaused) {
+      _state -= _PAUSED;
+      if (!isPaused && !_isSent) {
+        _schedule();
+      }
+    }
+  }
+
+  Future cancel() => Future._nullFuture;
+
+  Future<E> asFuture<E>([E futureValue]) {
+    _Future<E> result = new _Future<E>();
+    _onDone = () {
+      result._completeWithValue(futureValue);
+    };
+    return result;
+  }
+
+  void _sendDone() {
+    _state &= ~_SCHEDULED;
+    if (isPaused) return;
+    _state |= _DONE_SENT;
+    if (_onDone != null) _zone.runGuarded(_onDone);
+  }
+}
+
+class _AsBroadcastStream<T> extends Stream<T> {
+  final Stream<T> _source;
+  final _BroadcastCallback<T> _onListenHandler;
+  final _BroadcastCallback<T> _onCancelHandler;
+  final Zone _zone;
+
+  _AsBroadcastStreamController<T> _controller;
+  StreamSubscription<T> _subscription;
+
+  _AsBroadcastStream(
+      this._source,
+      void onListenHandler(StreamSubscription<T> subscription),
+      void onCancelHandler(StreamSubscription<T> subscription))
+      // TODO(floitsch): the return type should be void and should be
+      // inferred.
+      : _onListenHandler = Zone.current
+            .registerUnaryCallback<dynamic, StreamSubscription<T>>(
+                onListenHandler),
+        _onCancelHandler = Zone.current
+            .registerUnaryCallback<dynamic, StreamSubscription<T>>(
+                onCancelHandler),
+        _zone = Zone.current {
+    _controller = new _AsBroadcastStreamController<T>(_onListen, _onCancel);
+  }
+
+  bool get isBroadcast => true;
+
+  StreamSubscription<T> listen(void onData(T data),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    if (_controller == null || _controller.isClosed) {
+      // Return a dummy subscription backed by nothing, since
+      // it will only ever send one done event.
+      return new _DoneStreamSubscription<T>(onDone);
+    }
+    _subscription ??= _source.listen(_controller.add,
+        onError: _controller.addError, onDone: _controller.close);
+    cancelOnError = identical(true, cancelOnError);
+    return _controller._subscribe(onData, onError, onDone, cancelOnError);
+  }
+
+  void _onCancel() {
+    bool shutdown = (_controller == null) || _controller.isClosed;
+    if (_onCancelHandler != null) {
+      _zone.runUnary(
+          _onCancelHandler, new _BroadcastSubscriptionWrapper<T>(this));
+    }
+    if (shutdown) {
+      if (_subscription != null) {
+        _subscription.cancel();
+        _subscription = null;
+      }
+    }
+  }
+
+  void _onListen() {
+    if (_onListenHandler != null) {
+      _zone.runUnary(
+          _onListenHandler, new _BroadcastSubscriptionWrapper<T>(this));
+    }
+  }
+
+  // Methods called from _BroadcastSubscriptionWrapper.
+  void _cancelSubscription() {
+    if (_subscription == null) return;
+    // Called by [_controller] when it has no subscribers left.
+    StreamSubscription subscription = _subscription;
+    _subscription = null;
+    _controller = null; // Marks the stream as no longer listenable.
+    subscription.cancel();
+  }
+
+  void _pauseSubscription(Future resumeSignal) {
+    if (_subscription == null) return;
+    _subscription.pause(resumeSignal);
+  }
+
+  void _resumeSubscription() {
+    if (_subscription == null) return;
+    _subscription.resume();
+  }
+
+  bool get _isSubscriptionPaused {
+    if (_subscription == null) return false;
+    return _subscription.isPaused;
+  }
+}
+
+/**
+ * Wrapper for subscription that disallows changing handlers.
+ */
+class _BroadcastSubscriptionWrapper<T> implements StreamSubscription<T> {
+  final _AsBroadcastStream _stream;
+
+  _BroadcastSubscriptionWrapper(this._stream);
+
+  void onData(void handleData(T data)) {
+    throw new UnsupportedError(
+        "Cannot change handlers of asBroadcastStream source subscription.");
+  }
+
+  void onError(Function handleError) {
+    throw new UnsupportedError(
+        "Cannot change handlers of asBroadcastStream source subscription.");
+  }
+
+  void onDone(void handleDone()) {
+    throw new UnsupportedError(
+        "Cannot change handlers of asBroadcastStream source subscription.");
+  }
+
+  void pause([Future resumeSignal]) {
+    _stream._pauseSubscription(resumeSignal);
+  }
+
+  void resume() {
+    _stream._resumeSubscription();
+  }
+
+  Future cancel() {
+    _stream._cancelSubscription();
+    return Future._nullFuture;
+  }
+
+  bool get isPaused {
+    return _stream._isSubscriptionPaused;
+  }
+
+  Future<E> asFuture<E>([E futureValue]) {
+    throw new UnsupportedError(
+        "Cannot change handlers of asBroadcastStream source subscription.");
+  }
+}
+
+/**
+ * Simple implementation of [StreamIterator].
+ *
+ * Pauses the stream between calls to [moveNext].
+ */
+class _StreamIterator<T> implements StreamIterator<T> {
+  // The stream iterator is always in one of four states.
+  // The value of the [_stateData] field depends on the state.
+  //
+  // When `_subscription == null` and `_stateData != null`:
+  // The stream iterator has been created, but [moveNext] has not been called
+  // yet. The [_stateData] field contains the stream to listen to on the first
+  // call to [moveNext] and [current] returns `null`.
+  //
+  // When `_subscription != null` and `!_isPaused`:
+  // The user has called [moveNext] and the iterator is waiting for the next
+  // event. The [_stateData] field contains the [_Future] returned by the
+  // [_moveNext] call and [current] returns `null.`
+  //
+  // When `_subscription != null` and `_isPaused`:
+  // The most recent call to [moveNext] has completed with a `true` value
+  // and [current] provides the value of the data event.
+  // The [_stateData] field contains the [current] value.
+  //
+  // When `_subscription == null` and `_stateData == null`:
+  // The stream has completed or been canceled using [cancel].
+  // The stream completes on either a done event or an error event.
+  // The last call to [moveNext] has completed with `false` and [current]
+  // returns `null`.
+
+  /// Subscription being listened to.
+  ///
+  /// Set to `null` when the stream subscription is done or canceled.
+  StreamSubscription _subscription;
+
+  /// Data value depending on the current state.
+  ///
+  /// Before first call to [moveNext]: The stream to listen to.
+  ///
+  /// After calling [moveNext] but before the returned future completes:
+  /// The returned future.
+  ///
+  /// After calling [moveNext] and the returned future has completed
+  /// with `true`: The value of [current].
+  ///
+  /// After calling [moveNext] and the returned future has completed
+  /// with `false`, or after calling [cancel]: `null`.
+  Object _stateData;
+
+  /// Whether the iterator is between calls to `moveNext`.
+  /// This will usually cause the [_subscription] to be paused, but as an
+  /// optimization, we only pause after the [moveNext] future has been
+  /// completed.
+  bool _isPaused = false;
+
+  _StreamIterator(final Stream<T> stream)
+      : _stateData = stream ?? (throw ArgumentError.notNull("stream"));
+
+  T get current {
+    if (_subscription != null && _isPaused) {
+      return _stateData;
+    }
+    return null;
+  }
+
+  Future<bool> moveNext() {
+    if (_subscription != null) {
+      if (_isPaused) {
+        var future = new _Future<bool>();
+        _stateData = future;
+        _isPaused = false;
+        _subscription.resume();
+        return future;
+      }
+      throw new StateError("Already waiting for next.");
+    }
+    return _initializeOrDone();
+  }
+
+  /// Called if there is no active subscription when [moveNext] is called.
+  ///
+  /// Either starts listening on the stream if this is the first call to
+  /// [moveNext], or returns a `false` future because the stream has already
+  /// ended.
+  Future<bool> _initializeOrDone() {
+    assert(_subscription == null);
+    var stateData = _stateData;
+    if (stateData != null) {
+      Stream<T> stream = stateData;
+      _subscription = stream.listen(_onData,
+          onError: _onError, onDone: _onDone, cancelOnError: true);
+      var future = new _Future<bool>();
+      _stateData = future;
+      return future;
+    }
+    return Future._falseFuture;
+  }
+
+  Future cancel() {
+    StreamSubscription<T> subscription = _subscription;
+    Object stateData = _stateData;
+    _stateData = null;
+    if (subscription != null) {
+      _subscription = null;
+      if (!_isPaused) {
+        _Future<bool> future = stateData;
+        future._asyncComplete(false);
+      }
+      return subscription.cancel();
+    }
+    return Future._nullFuture;
+  }
+
+  void _onData(T data) {
+    assert(_subscription != null && !_isPaused);
+    _Future<bool> moveNextFuture = _stateData;
+    _stateData = data;
+    _isPaused = true;
+    moveNextFuture._complete(true);
+    if (_subscription != null && _isPaused) _subscription.pause();
+  }
+
+  void _onError(Object error, [StackTrace stackTrace]) {
+    assert(_subscription != null && !_isPaused);
+    _Future<bool> moveNextFuture = _stateData;
+    _subscription = null;
+    _stateData = null;
+    moveNextFuture._completeError(error, stackTrace);
+  }
+
+  void _onDone() {
+    assert(_subscription != null && !_isPaused);
+    _Future<bool> moveNextFuture = _stateData;
+    _subscription = null;
+    _stateData = null;
+    moveNextFuture._complete(false);
+  }
+}
+
+/** An empty broadcast stream, sending a done event as soon as possible. */
+class _EmptyStream<T> extends Stream<T> {
+  const _EmptyStream() : super._internal();
+  bool get isBroadcast => true;
+  StreamSubscription<T> listen(void onData(T data),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    return new _DoneStreamSubscription<T>(onDone);
+  }
+}
diff --git a/sdk_nnbd/lib/async/stream_pipe.dart b/sdk_nnbd/lib/async/stream_pipe.dart
new file mode 100644
index 0000000..e526179
--- /dev/null
+++ b/sdk_nnbd/lib/async/stream_pipe.dart
@@ -0,0 +1,500 @@
+// Copyright (c) 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 dart.async;
+
+/** Runs user code and takes actions depending on success or failure. */
+_runUserCode<T>(
+    T userCode(), onSuccess(T value), onError(error, StackTrace stackTrace)) {
+  try {
+    onSuccess(userCode());
+  } catch (e, s) {
+    AsyncError replacement = Zone.current.errorCallback(e, s);
+    if (replacement == null) {
+      onError(e, s);
+    } else {
+      var error = _nonNullError(replacement.error);
+      var stackTrace = replacement.stackTrace;
+      onError(error, stackTrace);
+    }
+  }
+}
+
+/** Helper function to cancel a subscription and wait for the potential future,
+  before completing with an error. */
+void _cancelAndError(StreamSubscription subscription, _Future future, error,
+    StackTrace stackTrace) {
+  var cancelFuture = subscription.cancel();
+  if (cancelFuture != null && !identical(cancelFuture, Future._nullFuture)) {
+    cancelFuture.whenComplete(() => future._completeError(error, stackTrace));
+  } else {
+    future._completeError(error, stackTrace);
+  }
+}
+
+void _cancelAndErrorWithReplacement(StreamSubscription subscription,
+    _Future future, error, StackTrace stackTrace) {
+  AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
+  if (replacement != null) {
+    error = _nonNullError(replacement.error);
+    stackTrace = replacement.stackTrace;
+  }
+  _cancelAndError(subscription, future, error, stackTrace);
+}
+
+typedef void _ErrorCallback(error, StackTrace stackTrace);
+
+/** Helper function to make an onError argument to [_runUserCode]. */
+_ErrorCallback _cancelAndErrorClosure(
+    StreamSubscription subscription, _Future future) {
+  return (error, StackTrace stackTrace) {
+    _cancelAndError(subscription, future, error, stackTrace);
+  };
+}
+
+/** Helper function to cancel a subscription and wait for the potential future,
+  before completing with a value. */
+void _cancelAndValue(StreamSubscription subscription, _Future future, value) {
+  var cancelFuture = subscription.cancel();
+  if (cancelFuture != null && !identical(cancelFuture, Future._nullFuture)) {
+    cancelFuture.whenComplete(() => future._complete(value));
+  } else {
+    future._complete(value);
+  }
+}
+
+/**
+ * A [Stream] that forwards subscriptions to another stream.
+ *
+ * This stream implements [Stream], but forwards all subscriptions
+ * to an underlying stream, and wraps the returned subscription to
+ * modify the events on the way.
+ *
+ * This class is intended for internal use only.
+ */
+abstract class _ForwardingStream<S, T> extends Stream<T> {
+  final Stream<S> _source;
+
+  _ForwardingStream(this._source);
+
+  bool get isBroadcast => _source.isBroadcast;
+
+  StreamSubscription<T> listen(void onData(T value),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    cancelOnError = identical(true, cancelOnError);
+    return _createSubscription(onData, onError, onDone, cancelOnError);
+  }
+
+  StreamSubscription<T> _createSubscription(void onData(T data),
+      Function onError, void onDone(), bool cancelOnError) {
+    return new _ForwardingStreamSubscription<S, T>(
+        this, onData, onError, onDone, cancelOnError);
+  }
+
+  // Override the following methods in subclasses to change the behavior.
+
+  void _handleData(S data, _EventSink<T> sink) {
+    sink._add(data as Object);
+  }
+
+  void _handleError(error, StackTrace stackTrace, _EventSink<T> sink) {
+    sink._addError(error, stackTrace);
+  }
+
+  void _handleDone(_EventSink<T> sink) {
+    sink._close();
+  }
+}
+
+/**
+ * Abstract superclass for subscriptions that forward to other subscriptions.
+ */
+class _ForwardingStreamSubscription<S, T>
+    extends _BufferingStreamSubscription<T> {
+  final _ForwardingStream<S, T> _stream;
+
+  StreamSubscription<S> _subscription;
+
+  _ForwardingStreamSubscription(this._stream, void onData(T data),
+      Function onError, void onDone(), bool cancelOnError)
+      : super(onData, onError, onDone, cancelOnError) {
+    _subscription = _stream._source
+        .listen(_handleData, onError: _handleError, onDone: _handleDone);
+  }
+
+  // _StreamSink interface.
+  // Transformers sending more than one event have no way to know if the stream
+  // is canceled or closed after the first, so we just ignore remaining events.
+
+  void _add(T data) {
+    if (_isClosed) return;
+    super._add(data);
+  }
+
+  void _addError(Object error, StackTrace stackTrace) {
+    if (_isClosed) return;
+    super._addError(error, stackTrace);
+  }
+
+  // StreamSubscription callbacks.
+
+  void _onPause() {
+    if (_subscription == null) return;
+    _subscription.pause();
+  }
+
+  void _onResume() {
+    if (_subscription == null) return;
+    _subscription.resume();
+  }
+
+  Future _onCancel() {
+    if (_subscription != null) {
+      StreamSubscription subscription = _subscription;
+      _subscription = null;
+      return subscription.cancel();
+    }
+    return null;
+  }
+
+  // Methods used as listener on source subscription.
+
+  void _handleData(S data) {
+    _stream._handleData(data, this);
+  }
+
+  void _handleError(error, StackTrace stackTrace) {
+    _stream._handleError(error, stackTrace, this);
+  }
+
+  void _handleDone() {
+    _stream._handleDone(this);
+  }
+}
+
+// -------------------------------------------------------------------
+// Stream transformers used by the default Stream implementation.
+// -------------------------------------------------------------------
+
+typedef bool _Predicate<T>(T value);
+
+void _addErrorWithReplacement(_EventSink sink, error, StackTrace stackTrace) {
+  AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
+  if (replacement != null) {
+    error = _nonNullError(replacement.error);
+    stackTrace = replacement.stackTrace;
+  }
+  sink._addError(error, stackTrace);
+}
+
+class _WhereStream<T> extends _ForwardingStream<T, T> {
+  final _Predicate<T> _test;
+
+  _WhereStream(Stream<T> source, bool test(T value))
+      : _test = test,
+        super(source);
+
+  void _handleData(T inputEvent, _EventSink<T> sink) {
+    bool satisfies;
+    try {
+      satisfies = _test(inputEvent);
+    } catch (e, s) {
+      _addErrorWithReplacement(sink, e, s);
+      return;
+    }
+    if (satisfies) {
+      sink._add(inputEvent);
+    }
+  }
+}
+
+typedef T _Transformation<S, T>(S value);
+
+/**
+ * A stream pipe that converts data events before passing them on.
+ */
+class _MapStream<S, T> extends _ForwardingStream<S, T> {
+  final _Transformation<S, T> _transform;
+
+  _MapStream(Stream<S> source, T transform(S event))
+      : this._transform = transform,
+        super(source);
+
+  void _handleData(S inputEvent, _EventSink<T> sink) {
+    T outputEvent;
+    try {
+      outputEvent = _transform(inputEvent);
+    } catch (e, s) {
+      _addErrorWithReplacement(sink, e, s);
+      return;
+    }
+    sink._add(outputEvent);
+  }
+}
+
+/**
+ * A stream pipe that converts data events before passing them on.
+ */
+class _ExpandStream<S, T> extends _ForwardingStream<S, T> {
+  final _Transformation<S, Iterable<T>> _expand;
+
+  _ExpandStream(Stream<S> source, Iterable<T> expand(S event))
+      : this._expand = expand,
+        super(source);
+
+  void _handleData(S inputEvent, _EventSink<T> sink) {
+    try {
+      for (T value in _expand(inputEvent)) {
+        sink._add(value);
+      }
+    } catch (e, s) {
+      // If either _expand or iterating the generated iterator throws,
+      // we abort the iteration.
+      _addErrorWithReplacement(sink, e, s);
+    }
+  }
+}
+
+typedef bool _ErrorTest(error);
+
+/**
+ * A stream pipe that converts or disposes error events
+ * before passing them on.
+ */
+class _HandleErrorStream<T> extends _ForwardingStream<T, T> {
+  final Function _transform;
+  final _ErrorTest _test;
+
+  _HandleErrorStream(Stream<T> source, Function onError, bool test(error))
+      : this._transform = onError,
+        this._test = test,
+        super(source);
+
+  void _handleError(Object error, StackTrace stackTrace, _EventSink<T> sink) {
+    bool matches = true;
+    if (_test != null) {
+      try {
+        matches = _test(error);
+      } catch (e, s) {
+        _addErrorWithReplacement(sink, e, s);
+        return;
+      }
+    }
+    if (matches) {
+      try {
+        _invokeErrorHandler(_transform, error, stackTrace);
+      } catch (e, s) {
+        if (identical(e, error)) {
+          sink._addError(error, stackTrace);
+        } else {
+          _addErrorWithReplacement(sink, e, s);
+        }
+        return;
+      }
+    } else {
+      sink._addError(error, stackTrace);
+    }
+  }
+}
+
+class _TakeStream<T> extends _ForwardingStream<T, T> {
+  final int _count;
+
+  _TakeStream(Stream<T> source, int count)
+      : this._count = count,
+        super(source) {
+    // This test is done early to avoid handling an async error
+    // in the _handleData method.
+    ArgumentError.checkNotNull(count, "count");
+  }
+
+  StreamSubscription<T> _createSubscription(void onData(T data),
+      Function onError, void onDone(), bool cancelOnError) {
+    if (_count == 0) {
+      _source.listen(null).cancel();
+      return new _DoneStreamSubscription<T>(onDone);
+    }
+    return new _StateStreamSubscription<T>(
+        this, onData, onError, onDone, cancelOnError, _count);
+  }
+
+  void _handleData(T inputEvent, _EventSink<T> sink) {
+    _StateStreamSubscription<T> subscription = sink;
+    int count = subscription._count;
+    if (count > 0) {
+      sink._add(inputEvent);
+      count -= 1;
+      subscription._count = count;
+      if (count == 0) {
+        // Closing also unsubscribes all subscribers, which unsubscribes
+        // this from source.
+        sink._close();
+      }
+    }
+  }
+}
+
+/**
+ * A [_ForwardingStreamSubscription] with one extra state field.
+ *
+ * Use by several different classes, storing an integer, bool or general.
+ */
+class _StateStreamSubscription<T> extends _ForwardingStreamSubscription<T, T> {
+  // Raw state field. Typed access provided by getters and setters below.
+  var _sharedState;
+
+  _StateStreamSubscription(_ForwardingStream<T, T> stream, void onData(T data),
+      Function onError, void onDone(), bool cancelOnError, this._sharedState)
+      : super(stream, onData, onError, onDone, cancelOnError);
+
+  bool get _flag => _sharedState;
+  void set _flag(bool flag) {
+    _sharedState = flag;
+  }
+
+  int get _count => _sharedState;
+  void set _count(int count) {
+    _sharedState = count;
+  }
+
+  Object get _value => _sharedState;
+  void set _value(Object value) {
+    _sharedState = value;
+  }
+}
+
+class _TakeWhileStream<T> extends _ForwardingStream<T, T> {
+  final _Predicate<T> _test;
+
+  _TakeWhileStream(Stream<T> source, bool test(T value))
+      : this._test = test,
+        super(source);
+
+  void _handleData(T inputEvent, _EventSink<T> sink) {
+    bool satisfies;
+    try {
+      satisfies = _test(inputEvent);
+    } catch (e, s) {
+      _addErrorWithReplacement(sink, e, s);
+      // The test didn't say true. Didn't say false either, but we stop anyway.
+      sink._close();
+      return;
+    }
+    if (satisfies) {
+      sink._add(inputEvent);
+    } else {
+      sink._close();
+    }
+  }
+}
+
+class _SkipStream<T> extends _ForwardingStream<T, T> {
+  final int _count;
+
+  _SkipStream(Stream<T> source, int count)
+      : this._count = count,
+        super(source) {
+    // This test is done early to avoid handling an async error
+    // in the _handleData method.
+    ArgumentError.checkNotNull(count, "count");
+    RangeError.checkNotNegative(count, "count");
+  }
+
+  StreamSubscription<T> _createSubscription(void onData(T data),
+      Function onError, void onDone(), bool cancelOnError) {
+    return new _StateStreamSubscription<T>(
+        this, onData, onError, onDone, cancelOnError, _count);
+  }
+
+  void _handleData(T inputEvent, _EventSink<T> sink) {
+    _StateStreamSubscription<T> subscription = sink;
+    int count = subscription._count;
+    if (count > 0) {
+      subscription._count = count - 1;
+      return;
+    }
+    sink._add(inputEvent);
+  }
+}
+
+class _SkipWhileStream<T> extends _ForwardingStream<T, T> {
+  final _Predicate<T> _test;
+
+  _SkipWhileStream(Stream<T> source, bool test(T value))
+      : this._test = test,
+        super(source);
+
+  StreamSubscription<T> _createSubscription(void onData(T data),
+      Function onError, void onDone(), bool cancelOnError) {
+    return new _StateStreamSubscription<T>(
+        this, onData, onError, onDone, cancelOnError, false);
+  }
+
+  void _handleData(T inputEvent, _EventSink<T> sink) {
+    _StateStreamSubscription<T> subscription = sink;
+    bool hasFailed = subscription._flag;
+    if (hasFailed) {
+      sink._add(inputEvent);
+      return;
+    }
+    bool satisfies;
+    try {
+      satisfies = _test(inputEvent);
+    } catch (e, s) {
+      _addErrorWithReplacement(sink, e, s);
+      // A failure to return a boolean is considered "not matching".
+      subscription._flag = true;
+      return;
+    }
+    if (!satisfies) {
+      subscription._flag = true;
+      sink._add(inputEvent);
+    }
+  }
+}
+
+typedef bool _Equality<T>(T a, T b);
+
+class _DistinctStream<T> extends _ForwardingStream<T, T> {
+  static final _SENTINEL = new Object();
+
+  final _Equality<T> _equals;
+
+  _DistinctStream(Stream<T> source, bool equals(T a, T b))
+      : _equals = equals,
+        super(source);
+
+  StreamSubscription<T> _createSubscription(void onData(T data),
+      Function onError, void onDone(), bool cancelOnError) {
+    return new _StateStreamSubscription<T>(
+        this, onData, onError, onDone, cancelOnError, _SENTINEL);
+  }
+
+  void _handleData(T inputEvent, _EventSink<T> sink) {
+    _StateStreamSubscription<T> subscription = sink;
+    var previous = subscription._value;
+    if (identical(previous, _SENTINEL)) {
+      // First event.
+      subscription._value = inputEvent;
+      sink._add(inputEvent);
+    } else {
+      T previousEvent = previous;
+      bool isEqual;
+      try {
+        if (_equals == null) {
+          isEqual = (previousEvent == inputEvent);
+        } else {
+          isEqual = _equals(previousEvent, inputEvent);
+        }
+      } catch (e, s) {
+        _addErrorWithReplacement(sink, e, s);
+        return;
+      }
+      if (!isEqual) {
+        sink._add(inputEvent);
+        subscription._value = inputEvent;
+      }
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/async/stream_transformers.dart b/sdk_nnbd/lib/async/stream_transformers.dart
new file mode 100644
index 0000000..9ec13bd
--- /dev/null
+++ b/sdk_nnbd/lib/async/stream_transformers.dart
@@ -0,0 +1,336 @@
+// 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 dart.async;
+
+/**
+ * Wraps an [_EventSink] so it exposes only the [EventSink] interface.
+ */
+class _EventSinkWrapper<T> implements EventSink<T> {
+  _EventSink _sink;
+  _EventSinkWrapper(this._sink);
+
+  void add(T data) {
+    _sink._add(data);
+  }
+
+  void addError(error, [StackTrace stackTrace]) {
+    _sink._addError(error, stackTrace);
+  }
+
+  void close() {
+    _sink._close();
+  }
+}
+
+/**
+ * A StreamSubscription that pipes data through a sink.
+ *
+ * The constructor of this class takes a [_SinkMapper] which maps from
+ * [EventSink] to [EventSink]. The input to the mapper is the output of
+ * the transformation. The returned sink is the transformation's input.
+ */
+class _SinkTransformerStreamSubscription<S, T>
+    extends _BufferingStreamSubscription<T> {
+  /// The transformer's input sink.
+  EventSink<S> _transformerSink;
+
+  /// The subscription to the input stream.
+  StreamSubscription<S> _subscription;
+
+  _SinkTransformerStreamSubscription(Stream<S> source, _SinkMapper<S, T> mapper,
+      void onData(T data), Function onError, void onDone(), bool cancelOnError)
+      // We set the adapter's target only when the user is allowed to send data.
+      : super(onData, onError, onDone, cancelOnError) {
+    _EventSinkWrapper<T> eventSink = new _EventSinkWrapper<T>(this);
+    _transformerSink = mapper(eventSink);
+    _subscription =
+        source.listen(_handleData, onError: _handleError, onDone: _handleDone);
+  }
+
+  /** Whether this subscription is still subscribed to its source. */
+  bool get _isSubscribed => _subscription != null;
+
+  // _EventSink interface.
+
+  /**
+   * Adds an event to this subscriptions.
+   *
+   * Contrary to normal [_BufferingStreamSubscription]s we may receive
+   * events when the stream is already closed. Report them as state
+   * error.
+   */
+  void _add(T data) {
+    if (_isClosed) {
+      throw new StateError("Stream is already closed");
+    }
+    super._add(data);
+  }
+
+  /**
+   * Adds an error event to this subscriptions.
+   *
+   * Contrary to normal [_BufferingStreamSubscription]s we may receive
+   * events when the stream is already closed. Report them as state
+   * error.
+   */
+  void _addError(Object error, StackTrace stackTrace) {
+    if (_isClosed) {
+      throw new StateError("Stream is already closed");
+    }
+    super._addError(error, stackTrace);
+  }
+
+  /**
+   * Adds a close event to this subscriptions.
+   *
+   * Contrary to normal [_BufferingStreamSubscription]s we may receive
+   * events when the stream is already closed. Report them as state
+   * error.
+   */
+  void _close() {
+    if (_isClosed) {
+      throw new StateError("Stream is already closed");
+    }
+    super._close();
+  }
+
+  // _BufferingStreamSubscription hooks.
+
+  void _onPause() {
+    if (_isSubscribed) _subscription.pause();
+  }
+
+  void _onResume() {
+    if (_isSubscribed) _subscription.resume();
+  }
+
+  Future _onCancel() {
+    if (_isSubscribed) {
+      StreamSubscription subscription = _subscription;
+      _subscription = null;
+      return subscription.cancel();
+    }
+    return null;
+  }
+
+  void _handleData(S data) {
+    try {
+      _transformerSink.add(data);
+    } catch (e, s) {
+      _addError(e, s);
+    }
+  }
+
+  void _handleError(error, [StackTrace stackTrace]) {
+    try {
+      _transformerSink.addError(error, stackTrace);
+    } catch (e, s) {
+      if (identical(e, error)) {
+        _addError(error, stackTrace);
+      } else {
+        _addError(e, s);
+      }
+    }
+  }
+
+  void _handleDone() {
+    try {
+      _subscription = null;
+      _transformerSink.close();
+    } catch (e, s) {
+      _addError(e, s);
+    }
+  }
+}
+
+typedef EventSink<S> _SinkMapper<S, T>(EventSink<T> output);
+
+/**
+ * A StreamTransformer for Sink-mappers.
+ *
+ * A Sink-mapper takes an [EventSink] (its output) and returns another
+ * EventSink (its input).
+ *
+ * Note that this class can be `const`.
+ */
+class _StreamSinkTransformer<S, T> extends StreamTransformerBase<S, T> {
+  final _SinkMapper<S, T> _sinkMapper;
+  const _StreamSinkTransformer(this._sinkMapper);
+
+  Stream<T> bind(Stream<S> stream) =>
+      new _BoundSinkStream<S, T>(stream, _sinkMapper);
+}
+
+/**
+ * The result of binding a StreamTransformer for Sink-mappers.
+ *
+ * It contains the bound Stream and the sink-mapper. Only when the user starts
+ * listening to this stream is the sink-mapper invoked. The result is used
+ * to create a StreamSubscription that transforms events.
+ */
+class _BoundSinkStream<S, T> extends Stream<T> {
+  final _SinkMapper<S, T> _sinkMapper;
+  final Stream<S> _stream;
+
+  bool get isBroadcast => _stream.isBroadcast;
+
+  _BoundSinkStream(this._stream, this._sinkMapper);
+
+  StreamSubscription<T> listen(void onData(T event),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    cancelOnError = identical(true, cancelOnError);
+    StreamSubscription<T> subscription =
+        new _SinkTransformerStreamSubscription<S, T>(
+            _stream, _sinkMapper, onData, onError, onDone, cancelOnError);
+    return subscription;
+  }
+}
+
+/// Data-handler coming from [StreamTransformer.fromHandlers].
+typedef void _TransformDataHandler<S, T>(S data, EventSink<T> sink);
+
+/// Error-handler coming from [StreamTransformer.fromHandlers].
+typedef void _TransformErrorHandler<T>(
+    Object error, StackTrace stackTrace, EventSink<T> sink);
+
+/// Done-handler coming from [StreamTransformer.fromHandlers].
+typedef void _TransformDoneHandler<T>(EventSink<T> sink);
+
+/**
+ * Wraps handlers (from [StreamTransformer.fromHandlers]) into an `EventSink`.
+ *
+ * This way we can reuse the code from [_StreamSinkTransformer].
+ */
+class _HandlerEventSink<S, T> implements EventSink<S> {
+  final _TransformDataHandler<S, T> _handleData;
+  final _TransformErrorHandler<T> _handleError;
+  final _TransformDoneHandler<T> _handleDone;
+
+  /// The output sink where the handlers should send their data into.
+  EventSink<T> _sink;
+
+  _HandlerEventSink(
+      this._handleData, this._handleError, this._handleDone, this._sink) {
+    if (_sink == null) {
+      throw new ArgumentError("The provided sink must not be null.");
+    }
+  }
+
+  bool get _isClosed => _sink == null;
+
+  void add(S data) {
+    if (_isClosed) {
+      throw StateError("Sink is closed");
+    }
+    if (_handleData != null) {
+      _handleData(data, _sink);
+    } else {
+      _sink.add(data as T);
+    }
+  }
+
+  void addError(Object error, [StackTrace stackTrace]) {
+    if (_isClosed) {
+      throw StateError("Sink is closed");
+    }
+    if (_handleError != null) {
+      _handleError(error, stackTrace, _sink);
+    } else {
+      _sink.addError(error, stackTrace);
+    }
+  }
+
+  void close() {
+    if (_isClosed) return;
+    var sink = _sink;
+    _sink = null;
+    if (_handleDone != null) {
+      _handleDone(sink);
+    } else {
+      sink.close();
+    }
+  }
+}
+
+/**
+ * A StreamTransformer that transformers events with the given handlers.
+ *
+ * Note that this transformer can only be used once.
+ */
+class _StreamHandlerTransformer<S, T> extends _StreamSinkTransformer<S, T> {
+  _StreamHandlerTransformer(
+      {void handleData(S data, EventSink<T> sink),
+      void handleError(Object error, StackTrace stackTrace, EventSink<T> sink),
+      void handleDone(EventSink<T> sink)})
+      : super((EventSink<T> outputSink) {
+          return new _HandlerEventSink<S, T>(
+              handleData, handleError, handleDone, outputSink);
+        });
+
+  Stream<T> bind(Stream<S> stream) {
+    return super.bind(stream);
+  }
+}
+
+/**
+ * A StreamTransformer that overrides [StreamTransformer.bind] with a callback.
+ */
+class _StreamBindTransformer<S, T> extends StreamTransformerBase<S, T> {
+  final Stream<T> Function(Stream<S>) _bind;
+  _StreamBindTransformer(this._bind);
+
+  Stream<T> bind(Stream<S> stream) => _bind(stream);
+}
+
+/// A closure mapping a stream and cancelOnError to a StreamSubscription.
+typedef StreamSubscription<T> _SubscriptionTransformer<S, T>(
+    Stream<S> stream, bool cancelOnError);
+
+/**
+ * A [StreamTransformer] that minimizes the number of additional classes.
+ *
+ * Instead of implementing three classes: a [StreamTransformer], a [Stream]
+ * (as the result of a `bind` call) and a [StreamSubscription] (which does the
+ * actual work), this class only requires a function that is invoked when the
+ * last bit (the subscription) of the transformer-workflow is needed.
+ *
+ * The given transformer function maps from Stream and cancelOnError to a
+ * `StreamSubscription`. As such it can also act on `cancel` events, making it
+ * fully general.
+ */
+class _StreamSubscriptionTransformer<S, T> extends StreamTransformerBase<S, T> {
+  final _SubscriptionTransformer<S, T> _onListen;
+
+  const _StreamSubscriptionTransformer(this._onListen);
+
+  Stream<T> bind(Stream<S> stream) =>
+      new _BoundSubscriptionStream<S, T>(stream, _onListen);
+}
+
+/**
+ * A stream transformed by a [_StreamSubscriptionTransformer].
+ *
+ * When this stream is listened to it invokes the [_onListen] function with
+ * the stored [_stream]. Usually the transformer starts listening at this
+ * moment.
+ */
+class _BoundSubscriptionStream<S, T> extends Stream<T> {
+  final _SubscriptionTransformer<S, T> _onListen;
+  final Stream<S> _stream;
+
+  bool get isBroadcast => _stream.isBroadcast;
+
+  _BoundSubscriptionStream(this._stream, this._onListen);
+
+  StreamSubscription<T> listen(void onData(T event),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    cancelOnError = identical(true, cancelOnError);
+    StreamSubscription<T> result = _onListen(_stream, cancelOnError);
+    result.onData(onData);
+    result.onError(onError);
+    result.onDone(onDone);
+    return result;
+  }
+}
diff --git a/sdk_nnbd/lib/async/timer.dart b/sdk_nnbd/lib/async/timer.dart
new file mode 100644
index 0000000..aa2f088
--- /dev/null
+++ b/sdk_nnbd/lib/async/timer.dart
@@ -0,0 +1,127 @@
+// Copyright (c) 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 dart.async;
+
+/**
+ * A count-down timer that can be configured to fire once or repeatedly.
+ *
+ * The timer counts down from the specified duration to 0.
+ * When the timer reaches 0, the timer invokes the specified callback function.
+ * Use a periodic timer to repeatedly count down the same interval.
+ *
+ * A negative duration is treated the same as a duration of 0.
+ * If the duration is statically known to be 0, consider using [run].
+ *
+ * Frequently the duration is either a constant or computed as in the
+ * following example (taking advantage of the multiplication operator of
+ * the [Duration] class):
+ * ```dart
+ * const timeout = const Duration(seconds: 3);
+ * const ms = const Duration(milliseconds: 1);
+ *
+ * startTimeout([int milliseconds]) {
+ *   var duration = milliseconds == null ? timeout : ms * milliseconds;
+ *   return new Timer(duration, handleTimeout);
+ * }
+ * ...
+ * void handleTimeout() {  // callback function
+ *   ...
+ * }
+ * ```
+ * Note: If Dart code using Timer is compiled to JavaScript, the finest
+ * granularity available in the browser is 4 milliseconds.
+ *
+ * See [Stopwatch] for measuring elapsed time.
+ */
+abstract class Timer {
+  /**
+   * Creates a new timer.
+   *
+   * The [callback] function is invoked after the given [duration].
+   *
+   */
+  factory Timer(Duration duration, void callback()) {
+    if (Zone.current == Zone.root) {
+      // No need to bind the callback. We know that the root's timer will
+      // be invoked in the root zone.
+      return Zone.current.createTimer(duration, callback);
+    }
+    return Zone.current
+        .createTimer(duration, Zone.current.bindCallbackGuarded(callback));
+  }
+
+  /**
+   * Creates a new repeating timer.
+   *
+   * The [callback] is invoked repeatedly with [duration] intervals until
+   * canceled with the [cancel] function.
+   *
+   * The exact timing depends on the underlying timer implementation.
+   * No more than `n` callbacks will be made in `duration * n` time,
+   * but the time between two consecutive callbacks
+   * can be shorter and longer than `duration`.
+   *
+   * In particular, an implementation may schedule the next callback, e.g.,
+   * a `duration` after either when the previous callback ended,
+   * when the previous callback started, or when the previous callback was
+   * scheduled for - even if the actual callback was delayed.
+   */
+  factory Timer.periodic(Duration duration, void callback(Timer timer)) {
+    if (Zone.current == Zone.root) {
+      // No need to bind the callback. We know that the root's timer will
+      // be invoked in the root zone.
+      return Zone.current.createPeriodicTimer(duration, callback);
+    }
+    var boundCallback = Zone.current.bindUnaryCallbackGuarded<Timer>(callback);
+    return Zone.current.createPeriodicTimer(duration, boundCallback);
+  }
+
+  /**
+   * Runs the given [callback] asynchronously as soon as possible.
+   *
+   * This function is equivalent to `new Timer(Duration.zero, callback)`.
+   */
+  static void run(void callback()) {
+    new Timer(Duration.zero, callback);
+  }
+
+  /**
+   * Cancels the timer.
+   *
+   * Once a [Timer] has been canceled, the callback function will not be called
+   * by the timer. Calling [cancel] more than once on a [Timer] is allowed, and
+   * will have no further effect.
+   */
+  void cancel();
+
+  /**
+   * The number of durations preceding the most recent timer event.
+   *
+   * The value starts at zero and is incremented each time a timer event
+   * occurs, so each callback will see a larger value than the previous one.
+   *
+   * If a periodic timer with a non-zero duration is delayed too much,
+   * so more than one tick should have happened,
+   * all but the last tick in the past are considered "missed",
+   * and no callback is invoked for them.
+   * The [tick] count reflects the number of durations that have passed and
+   * not the number of callback invocations that have happened.
+   */
+  int get tick;
+
+  /**
+   * Returns whether the timer is still active.
+   *
+   * A non-periodic timer is active if the callback has not been executed,
+   * and the timer has not been canceled.
+   *
+   * A periodic timer is active if it has not been canceled.
+   */
+  bool get isActive;
+
+  external static Timer _createTimer(Duration duration, void callback());
+  external static Timer _createPeriodicTimer(
+      Duration duration, void callback(Timer timer));
+}
diff --git a/sdk_nnbd/lib/async/zone.dart b/sdk_nnbd/lib/async/zone.dart
new file mode 100644
index 0000000..911ecff
--- /dev/null
+++ b/sdk_nnbd/lib/async/zone.dart
@@ -0,0 +1,1516 @@
+// 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 dart.async;
+
+typedef R ZoneCallback<R>();
+typedef R ZoneUnaryCallback<R, T>(T arg);
+typedef R ZoneBinaryCallback<R, T1, T2>(T1 arg1, T2 arg2);
+
+typedef HandleUncaughtErrorHandler = void Function(Zone self,
+    ZoneDelegate parent, Zone zone, Object error, StackTrace stackTrace);
+typedef RunHandler = R Function<R>(
+    Zone self, ZoneDelegate parent, Zone zone, R Function() f);
+typedef RunUnaryHandler = R Function<R, T>(
+    Zone self, ZoneDelegate parent, Zone zone, R Function(T arg) f, T arg);
+typedef RunBinaryHandler = R Function<R, T1, T2>(Zone self, ZoneDelegate parent,
+    Zone zone, R Function(T1 arg1, T2 arg2) f, T1 arg1, T2 arg2);
+typedef RegisterCallbackHandler = ZoneCallback<R> Function<R>(
+    Zone self, ZoneDelegate parent, Zone zone, R Function() f);
+typedef RegisterUnaryCallbackHandler = ZoneUnaryCallback<R, T> Function<R, T>(
+    Zone self, ZoneDelegate parent, Zone zone, R Function(T arg) f);
+typedef RegisterBinaryCallbackHandler
+    = ZoneBinaryCallback<R, T1, T2> Function<R, T1, T2>(Zone self,
+        ZoneDelegate parent, Zone zone, R Function(T1 arg1, T2 arg2) f);
+typedef AsyncError ErrorCallbackHandler(Zone self, ZoneDelegate parent,
+    Zone zone, Object error, StackTrace stackTrace);
+typedef void ScheduleMicrotaskHandler(
+    Zone self, ZoneDelegate parent, Zone zone, void f());
+typedef Timer CreateTimerHandler(
+    Zone self, ZoneDelegate parent, Zone zone, Duration duration, void f());
+typedef Timer CreatePeriodicTimerHandler(Zone self, ZoneDelegate parent,
+    Zone zone, Duration period, void f(Timer timer));
+typedef void PrintHandler(
+    Zone self, ZoneDelegate parent, Zone zone, String line);
+typedef Zone ForkHandler(Zone self, ZoneDelegate parent, Zone zone,
+    ZoneSpecification specification, Map zoneValues);
+
+/** Pair of error and stack trace. Returned by [Zone.errorCallback]. */
+class AsyncError implements Error {
+  final Object error;
+  final StackTrace stackTrace;
+
+  AsyncError(this.error, this.stackTrace);
+
+  String toString() => '$error';
+}
+
+class _ZoneFunction<T extends Function> {
+  final _Zone zone;
+  final T function;
+  const _ZoneFunction(this.zone, this.function);
+}
+
+/**
+ * This class provides the specification for a forked zone.
+ *
+ * When forking a new zone (see [Zone.fork]) one can override the default
+ * behavior of the zone by providing callbacks. These callbacks must be
+ * given in an instance of this class.
+ *
+ * Handlers have the same signature as the same-named methods on [Zone] but
+ * receive three additional arguments:
+ *
+ *   1. the zone the handlers are attached to (the "self" zone).
+ *   2. a [ZoneDelegate] to the parent zone.
+ *   3. the zone that first received the request (before the request was
+ *     bubbled up).
+ *
+ * Handlers can either stop propagation the request (by simply not calling the
+ * parent handler), or forward to the parent zone, potentially modifying the
+ * arguments on the way.
+ */
+abstract class ZoneSpecification {
+  /**
+   * Creates a specification with the provided handlers.
+   */
+  const factory ZoneSpecification(
+      {HandleUncaughtErrorHandler handleUncaughtError,
+      RunHandler run,
+      RunUnaryHandler runUnary,
+      RunBinaryHandler runBinary,
+      RegisterCallbackHandler registerCallback,
+      RegisterUnaryCallbackHandler registerUnaryCallback,
+      RegisterBinaryCallbackHandler registerBinaryCallback,
+      ErrorCallbackHandler errorCallback,
+      ScheduleMicrotaskHandler scheduleMicrotask,
+      CreateTimerHandler createTimer,
+      CreatePeriodicTimerHandler createPeriodicTimer,
+      PrintHandler print,
+      ForkHandler fork}) = _ZoneSpecification;
+
+  /**
+   * Creates a specification from [other] with the provided handlers overriding
+   * the ones in [other].
+   */
+  factory ZoneSpecification.from(ZoneSpecification other,
+      {HandleUncaughtErrorHandler handleUncaughtError,
+      RunHandler run,
+      RunUnaryHandler runUnary,
+      RunBinaryHandler runBinary,
+      RegisterCallbackHandler registerCallback,
+      RegisterUnaryCallbackHandler registerUnaryCallback,
+      RegisterBinaryCallbackHandler registerBinaryCallback,
+      ErrorCallbackHandler errorCallback,
+      ScheduleMicrotaskHandler scheduleMicrotask,
+      CreateTimerHandler createTimer,
+      CreatePeriodicTimerHandler createPeriodicTimer,
+      PrintHandler print,
+      ForkHandler fork}) {
+    return new ZoneSpecification(
+        handleUncaughtError: handleUncaughtError ?? other.handleUncaughtError,
+        run: run ?? other.run,
+        runUnary: runUnary ?? other.runUnary,
+        runBinary: runBinary ?? other.runBinary,
+        registerCallback: registerCallback ?? other.registerCallback,
+        registerUnaryCallback:
+            registerUnaryCallback ?? other.registerUnaryCallback,
+        registerBinaryCallback:
+            registerBinaryCallback ?? other.registerBinaryCallback,
+        errorCallback: errorCallback ?? other.errorCallback,
+        scheduleMicrotask: scheduleMicrotask ?? other.scheduleMicrotask,
+        createTimer: createTimer ?? other.createTimer,
+        createPeriodicTimer: createPeriodicTimer ?? other.createPeriodicTimer,
+        print: print ?? other.print,
+        fork: fork ?? other.fork);
+  }
+
+  HandleUncaughtErrorHandler get handleUncaughtError;
+  RunHandler get run;
+  RunUnaryHandler get runUnary;
+  RunBinaryHandler get runBinary;
+  RegisterCallbackHandler get registerCallback;
+  RegisterUnaryCallbackHandler get registerUnaryCallback;
+  RegisterBinaryCallbackHandler get registerBinaryCallback;
+  ErrorCallbackHandler get errorCallback;
+  ScheduleMicrotaskHandler get scheduleMicrotask;
+  CreateTimerHandler get createTimer;
+  CreatePeriodicTimerHandler get createPeriodicTimer;
+  PrintHandler get print;
+  ForkHandler get fork;
+}
+
+/**
+ * Internal [ZoneSpecification] class.
+ *
+ * The implementation wants to rely on the fact that the getters cannot change
+ * dynamically. We thus require users to go through the redirecting
+ * [ZoneSpecification] constructor which instantiates this class.
+ */
+class _ZoneSpecification implements ZoneSpecification {
+  const _ZoneSpecification(
+      {this.handleUncaughtError,
+      this.run,
+      this.runUnary,
+      this.runBinary,
+      this.registerCallback,
+      this.registerUnaryCallback,
+      this.registerBinaryCallback,
+      this.errorCallback,
+      this.scheduleMicrotask,
+      this.createTimer,
+      this.createPeriodicTimer,
+      this.print,
+      this.fork});
+
+  final HandleUncaughtErrorHandler handleUncaughtError;
+  final RunHandler run;
+  final RunUnaryHandler runUnary;
+  final RunBinaryHandler runBinary;
+  final RegisterCallbackHandler registerCallback;
+  final RegisterUnaryCallbackHandler registerUnaryCallback;
+  final RegisterBinaryCallbackHandler registerBinaryCallback;
+  final ErrorCallbackHandler errorCallback;
+  final ScheduleMicrotaskHandler scheduleMicrotask;
+  final CreateTimerHandler createTimer;
+  final CreatePeriodicTimerHandler createPeriodicTimer;
+  final PrintHandler print;
+  final ForkHandler fork;
+}
+
+/**
+ * An adapted view of the parent zone.
+ *
+ * This class allows the implementation of a zone method to invoke methods on
+ * the parent zone while retaining knowledge of the originating zone.
+ *
+ * Custom zones (created through [Zone.fork] or [runZoned]) can provide
+ * implementations of most methods of zones. This is similar to overriding
+ * methods on [Zone], except that this mechanism doesn't require subclassing.
+ *
+ * A custom zone function (provided through a [ZoneSpecification]) typically
+ * records or wraps its parameters and then delegates the operation to its
+ * parent zone using the provided [ZoneDelegate].
+ *
+ * While zones have access to their parent zone (through [Zone.parent]) it is
+ * recommended to call the methods on the provided parent delegate for two
+ * reasons:
+ * 1. the delegate methods take an additional `zone` argument which is the
+ *   zone the action has been initiated in.
+ * 2. delegate calls are more efficient, since the implementation knows how
+ *   to skip zones that would just delegate to their parents.
+ */
+abstract class ZoneDelegate {
+  void handleUncaughtError(Zone zone, error, StackTrace stackTrace);
+  R run<R>(Zone zone, R f());
+  R runUnary<R, T>(Zone zone, R f(T arg), T arg);
+  R runBinary<R, T1, T2>(Zone zone, R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2);
+  ZoneCallback<R> registerCallback<R>(Zone zone, R f());
+  ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(Zone zone, R f(T arg));
+  ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>(
+      Zone zone, R f(T1 arg1, T2 arg2));
+  AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace);
+  void scheduleMicrotask(Zone zone, void f());
+  Timer createTimer(Zone zone, Duration duration, void f());
+  Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer));
+  void print(Zone zone, String line);
+  Zone fork(Zone zone, ZoneSpecification specification, Map zoneValues);
+}
+
+/**
+ * A zone represents an environment that remains stable across asynchronous
+ * calls.
+ *
+ * Code is always executed in the context of a zone, available as
+ * [Zone.current]. The initial `main` function runs in the context of the
+ * default zone ([Zone.root]). Code can be run in a different zone using either
+ * [runZoned], to create a new zone, or [Zone.run] to run code in the context of
+ * an existing zone likely created using [Zone.fork].
+ *
+ * Developers can create a new zone that overrides some of the functionality of
+ * an existing zone. For example, custom zones can replace of modify the
+ * behavior of `print`, timers, microtasks or how uncaught errors are handled.
+ *
+ * The [Zone] class is not subclassable, but users can provide custom zones by
+ * forking an existing zone (usually [Zone.current]) with a [ZoneSpecification].
+ * This is similar to creating a new class that extends the base `Zone` class
+ * and that overrides some methods, except without actually creating a new
+ * class. Instead the overriding methods are provided as functions that
+ * explicitly take the equivalent of their own class, the "super" class and the
+ * `this` object as parameters.
+ *
+ * Asynchronous callbacks always run in the context of the zone where they were
+ * scheduled. This is implemented using two steps:
+ * 1. the callback is first registered using one of [registerCallback],
+ *   [registerUnaryCallback], or [registerBinaryCallback]. This allows the zone
+ *   to record that a callback exists and potentially modify it (by returning a
+ *   different callback). The code doing the registration (e.g., `Future.then`)
+ *   also remembers the current zone so that it can later run the callback in
+ *   that zone.
+ * 2. At a later point the registered callback is run in the remembered zone.
+ *
+ * This is all handled internally by the platform code and most users don't need
+ * to worry about it. However, developers of new asynchronous operations,
+ * provided by the underlying system or through native extensions, must follow
+ * the protocol to be zone compatible.
+ *
+ * For convenience, zones provide [bindCallback] (and the corresponding
+ * [bindUnaryCallback] and [bindBinaryCallback]) to make it easier to respect
+ * the zone contract: these functions first invoke the corresponding `register`
+ * functions and then wrap the returned function so that it runs in the current
+ * zone when it is later asynchronously invoked.
+ *
+ * Similarly, zones provide [bindCallbackGuarded] (and the corresponding
+ * [bindUnaryCallbackGuarded] and [bindBinaryCallbackGuarded]), when the
+ * callback should be invoked through [Zone.runGuarded].
+ */
+abstract class Zone {
+  // Private constructor so that it is not possible instantiate a Zone class.
+  Zone._();
+
+  /**
+   * The root zone.
+   *
+   * All isolate entry functions (`main` or spawned functions) start running in
+   * the root zone (that is, [Zone.current] is identical to [Zone.root] when the
+   * entry function is called). If no custom zone is created, the rest of the
+   * program always runs in the root zone.
+   *
+   * The root zone implements the default behavior of all zone operations.
+   * Many methods, like [registerCallback] do the bare minimum required of the
+   * function, and are only provided as a hook for custom zones. Others, like
+   * [scheduleMicrotask], interact with the underlying system to implement the
+   * desired behavior.
+   */
+  static const Zone root = _rootZone;
+
+  /** The currently running zone. */
+  static Zone _current = _rootZone;
+
+  /** The zone that is currently active. */
+  static Zone get current => _current;
+
+  /**
+   * Handles uncaught asynchronous errors.
+   *
+   * There are two kind of asynchronous errors that are handled by this
+   * function:
+   * 1. Uncaught errors that were thrown in asynchronous callbacks, for example,
+   *   a `throw` in the function passed to [Timer.run].
+   * 2. Asynchronous errors that are pushed through [Future] and [Stream]
+   *   chains, but for which no child registered an error handler.
+   *   Most asynchronous classes, like [Future] or [Stream] push errors to their
+   *   listeners. Errors are propagated this way until either a listener handles
+   *   the error (for example with [Future.catchError]), or no listener is
+   *   available anymore. In the latter case, futures and streams invoke the
+   *   zone's [handleUncaughtError].
+   *
+   * By default, when handled by the root zone, uncaught asynchronous errors are
+   * treated like uncaught synchronous exceptions.
+   */
+  void handleUncaughtError(error, StackTrace stackTrace);
+
+  /**
+   * The parent zone of the this zone.
+   *
+   * Is `null` if `this` is the [root] zone.
+   *
+   * Zones are created by [fork] on an existing zone, or by [runZoned] which
+   * forks the [current] zone. The new zone's parent zone is the zone it was
+   * forked from.
+   */
+  Zone get parent;
+
+  /**
+   * The error zone is the one that is responsible for dealing with uncaught
+   * errors.
+   *
+   * This is the closest parent zone of this zone that provides a
+   * [handleUncaughtError] method.
+   *
+   * Asynchronous errors never cross zone boundaries between zones with
+   * different error handlers.
+   *
+   * Example:
+   * ```
+   * import 'dart:async';
+   *
+   * main() {
+   *   var future;
+   *   runZoned(() {
+   *     // The asynchronous error is caught by the custom zone which prints
+   *     // 'asynchronous error'.
+   *     future = new Future.error("asynchronous error");
+   *   }, onError: (e) { print(e); });  // Creates a zone with an error handler.
+   *   // The following `catchError` handler is never invoked, because the
+   *   // custom zone created by the call to `runZoned` provides an
+   *   // error handler.
+   *   future.catchError((e) { throw "is never reached"; });
+   * }
+   * ```
+   *
+   * Note that errors cannot enter a child zone with a different error handler
+   * either:
+   * ```
+   * import 'dart:async';
+   *
+   * main() {
+   *   runZoned(() {
+   *     // The following asynchronous error is *not* caught by the `catchError`
+   *     // in the nested zone, since errors are not to cross zone boundaries
+   *     // with different error handlers.
+   *     // Instead the error is handled by the current error handler,
+   *     // printing "Caught by outer zone: asynchronous error".
+   *     var future = new Future.error("asynchronous error");
+   *     runZoned(() {
+   *       future.catchError((e) { throw "is never reached"; });
+   *     }, onError: (e) { throw "is never reached"; });
+   *   }, onError: (e) { print("Caught by outer zone: $e"); });
+   * }
+   * ```
+   */
+  Zone get errorZone;
+
+  /**
+   * Returns true if `this` and [otherZone] are in the same error zone.
+   *
+   * Two zones are in the same error zone if they have the same [errorZone].
+   */
+  bool inSameErrorZone(Zone otherZone);
+
+  /**
+   * Creates a new zone as a child of `this`.
+   *
+   * The new zone uses the closures in the given [specification] to override
+   * the current's zone behavior. All specification entries that are `null`
+   * inherit the behavior from the parent zone (`this`).
+   *
+   * The new zone inherits the stored values (accessed through [operator []])
+   * of this zone and updates them with values from [zoneValues], which either
+   * adds new values or overrides existing ones.
+   *
+   * Note that the fork operation is interceptible. A zone can thus change
+   * the zone specification (or zone values), giving the forking zone full
+   * control over the child zone.
+   */
+  Zone fork({ZoneSpecification specification, Map zoneValues});
+
+  /**
+   * Executes [action] in this zone.
+   *
+   * By default (as implemented in the [root] zone), runs [action]
+   * with [current] set to this zone.
+   *
+   * If [action] throws, the synchronous exception is not caught by the zone's
+   * error handler. Use [runGuarded] to achieve that.
+   *
+   * Since the root zone is the only zone that can modify the value of
+   * [current], custom zones intercepting run should always delegate to their
+   * parent zone. They may take actions before and after the call.
+   */
+  R run<R>(R action());
+
+  /**
+   * Executes the given [action] with [argument] in this zone.
+   *
+   * As [run] except that [action] is called with one [argument] instead of
+   * none.
+   */
+  R runUnary<R, T>(R action(T argument), T argument);
+
+  /**
+   * Executes the given [action] with [argument1] and [argument2] in this
+   * zone.
+   *
+   * As [run] except that [action] is called with two arguments instead of none.
+   */
+  R runBinary<R, T1, T2>(
+      R action(T1 argument1, T2 argument2), T1 argument1, T2 argument2);
+
+  /**
+   * Executes the given [action] in this zone and catches synchronous
+   * errors.
+   *
+   * This function is equivalent to:
+   * ```
+   * try {
+   *   this.run(action);
+   * } catch (e, s) {
+   *   this.handleUncaughtError(e, s);
+   * }
+   * ```
+   *
+   * See [run].
+   */
+  void runGuarded(void action());
+
+  /**
+   * Executes the given [action] with [argument] in this zone and
+   * catches synchronous errors.
+   *
+   * See [runGuarded].
+   */
+  void runUnaryGuarded<T>(void action(T argument), T argument);
+
+  /**
+   * Executes the given [action] with [argument1] and [argument2] in this
+   * zone and catches synchronous errors.
+   *
+   * See [runGuarded].
+   */
+  void runBinaryGuarded<T1, T2>(
+      void action(T1 argument1, T2 argument2), T1 argument1, T2 argument2);
+
+  /**
+   * Registers the given callback in this zone.
+   *
+   * When implementing an asynchronous primitive that uses callbacks, the
+   * callback must be registered using [registerCallback] at the point where the
+   * user provides the callback. This allows zones to record other information
+   * that they need at the same time, perhaps even wrapping the callback, so
+   * that the callback is prepared when it is later run in the same zones
+   * (using [run]). For example, a zone may decide
+   * to store the stack trace (at the time of the registration) with the
+   * callback.
+   *
+   * Returns the callback that should be used in place of the provided
+   * [callback]. Frequently zones simply return the original callback.
+   *
+   * Custom zones may intercept this operation. The default implementation in
+   * [Zone.root] returns the original callback unchanged.
+   */
+  ZoneCallback<R> registerCallback<R>(R callback());
+
+  /**
+   * Registers the given callback in this zone.
+   *
+   * Similar to [registerCallback] but with a unary callback.
+   */
+  ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(R callback(T arg));
+
+  /**
+   * Registers the given callback in this zone.
+   *
+   * Similar to [registerCallback] but with a unary callback.
+   */
+  ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>(
+      R callback(T1 arg1, T2 arg2));
+
+  /**
+   *  Registers the provided [callback] and returns a function that will
+   *  execute in this zone.
+   *
+   *  Equivalent to:
+   *
+   *      ZoneCallback registered = this.registerCallback(callback);
+   *      return () => this.run(registered);
+   *
+   */
+  ZoneCallback<R> bindCallback<R>(R callback());
+
+  /**
+   *  Registers the provided [callback] and returns a function that will
+   *  execute in this zone.
+   *
+   *  Equivalent to:
+   *
+   *      ZoneCallback registered = this.registerUnaryCallback(callback);
+   *      return (arg) => thin.runUnary(registered, arg);
+   */
+  ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R callback(T argument));
+
+  /**
+   *  Registers the provided [callback] and returns a function that will
+   *  execute in this zone.
+   *
+   *  Equivalent to:
+   *
+   *      ZoneCallback registered = registerBinaryCallback(callback);
+   *      return (arg1, arg2) => thin.runBinary(registered, arg1, arg2);
+   */
+  ZoneBinaryCallback<R, T1, T2> bindBinaryCallback<R, T1, T2>(
+      R callback(T1 argument1, T2 argument2));
+
+  /**
+   * Registers the provided [callback] and returns a function that will
+   * execute in this zone.
+   *
+   * When the function executes, errors are caught and treated as uncaught
+   * errors.
+   *
+   * Equivalent to:
+   *
+   *     ZoneCallback registered = this.registerCallback(callback);
+   *     return () => this.runGuarded(registered);
+   *
+   */
+  void Function() bindCallbackGuarded(void callback());
+
+  /**
+   * Registers the provided [callback] and returns a function that will
+   * execute in this zone.
+   *
+   * When the function executes, errors are caught and treated as uncaught
+   * errors.
+   *
+   * Equivalent to:
+   *
+   *     ZoneCallback registered = this.registerUnaryCallback(callback);
+   *     return (arg) => this.runUnaryGuarded(registered, arg);
+   */
+  void Function(T) bindUnaryCallbackGuarded<T>(void callback(T argument));
+
+  /**
+   *  Registers the provided [callback] and returns a function that will
+   *  execute in this zone.
+   *
+   *  Equivalent to:
+   *
+   *      ZoneCallback registered = registerBinaryCallback(callback);
+   *      return (arg1, arg2) => this.runBinaryGuarded(registered, arg1, arg2);
+   */
+  void Function(T1, T2) bindBinaryCallbackGuarded<T1, T2>(
+      void callback(T1 argument1, T2 argument2));
+
+  /**
+   * Intercepts errors when added programmatically to a `Future` or `Stream`.
+   *
+   * When calling [Completer.completeError], [StreamController.addError],
+   * or some [Future] constructors, the current zone is allowed to intercept
+   * and replace the error.
+   *
+   * Future constructors invoke this function when the error is received
+   * directly, for example with [Future.error], or when the error is caught
+   * synchronously, for example with [Future.sync].
+   *
+   * There is no guarantee that an error is only sent through [errorCallback]
+   * once. Libraries that use intermediate controllers or completers might
+   * end up invoking [errorCallback] multiple times.
+   *
+   * Returns `null` if no replacement is desired. Otherwise returns an instance
+   * of [AsyncError] holding the new pair of error and stack trace.
+   *
+   * Although not recommended, the returned instance may have its `error` member
+   * ([AsyncError.error]) be equal to `null` in which case the error should be
+   * replaced by a [NullThrownError].
+   *
+   * Custom zones may intercept this operation.
+   *
+   * Implementations of a new asynchronous primitive that converts synchronous
+   * errors to asynchronous errors rarely need to invoke [errorCallback], since
+   * errors are usually reported through future completers or stream
+   * controllers.
+   */
+  AsyncError errorCallback(Object error, StackTrace stackTrace);
+
+  /**
+   * Runs [callback] asynchronously in this zone.
+   *
+   * The global `scheduleMicrotask` delegates to the current zone's
+   * [scheduleMicrotask]. The root zone's implementation interacts with the
+   * underlying system to schedule the given callback as a microtask.
+   *
+   * Custom zones may intercept this operation (for example to wrap the given
+   * [callback]).
+   */
+  void scheduleMicrotask(void callback());
+
+  /**
+   * Creates a Timer where the callback is executed in this zone.
+   */
+  Timer createTimer(Duration duration, void callback());
+
+  /**
+   * Creates a periodic Timer where the callback is executed in this zone.
+   */
+  Timer createPeriodicTimer(Duration period, void callback(Timer timer));
+
+  /**
+   * Prints the given [line].
+   *
+   * The global `print` function delegates to the current zone's [print]
+   * function which makes it possible to intercept printing.
+   *
+   * Example:
+   * ```
+   * import 'dart:async';
+   *
+   * main() {
+   *   runZoned(() {
+   *     // Ends up printing: "Intercepted: in zone".
+   *     print("in zone");
+   *   }, zoneSpecification: new ZoneSpecification(
+   *       print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
+   *     parent.print(zone, "Intercepted: $line");
+   *   }));
+   * }
+   * ```
+   */
+  void print(String line);
+
+  /**
+   * Call to enter the Zone.
+   *
+   * The previous current zone is returned.
+   */
+  static Zone _enter(Zone zone) {
+    assert(zone != null);
+    assert(!identical(zone, _current));
+    Zone previous = _current;
+    _current = zone;
+    return previous;
+  }
+
+  /**
+   * Call to leave the Zone.
+   *
+   * The previous Zone must be provided as `previous`.
+   */
+  static void _leave(Zone previous) {
+    assert(previous != null);
+    Zone._current = previous;
+  }
+
+  /**
+   * Retrieves the zone-value associated with [key].
+   *
+   * If this zone does not contain the value looks up the same key in the
+   * parent zone. If the [key] is not found returns `null`.
+   *
+   * Any object can be used as key, as long as it has compatible `operator ==`
+   * and `hashCode` implementations.
+   * By controlling access to the key, a zone can grant or deny access to the
+   * zone value.
+   */
+  operator [](Object key);
+}
+
+ZoneDelegate _parentDelegate(_Zone zone) {
+  if (zone.parent == null) return null;
+  return zone.parent._delegate;
+}
+
+class _ZoneDelegate implements ZoneDelegate {
+  final _Zone _delegationTarget;
+
+  _ZoneDelegate(this._delegationTarget);
+
+  void handleUncaughtError(Zone zone, error, StackTrace stackTrace) {
+    var implementation = _delegationTarget._handleUncaughtError;
+    _Zone implZone = implementation.zone;
+    HandleUncaughtErrorHandler handler = implementation.function;
+    return handler(
+        implZone, _parentDelegate(implZone), zone, error, stackTrace);
+  }
+
+  R run<R>(Zone zone, R f()) {
+    var implementation = _delegationTarget._run;
+    _Zone implZone = implementation.zone;
+    RunHandler handler = implementation.function;
+    return handler(implZone, _parentDelegate(implZone), zone, f);
+  }
+
+  R runUnary<R, T>(Zone zone, R f(T arg), T arg) {
+    var implementation = _delegationTarget._runUnary;
+    _Zone implZone = implementation.zone;
+    RunUnaryHandler handler = implementation.function;
+    return handler(implZone, _parentDelegate(implZone), zone, f, arg);
+  }
+
+  R runBinary<R, T1, T2>(Zone zone, R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) {
+    var implementation = _delegationTarget._runBinary;
+    _Zone implZone = implementation.zone;
+    RunBinaryHandler handler = implementation.function;
+    return handler(implZone, _parentDelegate(implZone), zone, f, arg1, arg2);
+  }
+
+  ZoneCallback<R> registerCallback<R>(Zone zone, R f()) {
+    var implementation = _delegationTarget._registerCallback;
+    _Zone implZone = implementation.zone;
+    RegisterCallbackHandler handler = implementation.function;
+    return handler(implZone, _parentDelegate(implZone), zone, f);
+  }
+
+  ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(Zone zone, R f(T arg)) {
+    var implementation = _delegationTarget._registerUnaryCallback;
+    _Zone implZone = implementation.zone;
+    RegisterUnaryCallbackHandler handler = implementation.function;
+    return handler(implZone, _parentDelegate(implZone), zone, f);
+  }
+
+  ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>(
+      Zone zone, R f(T1 arg1, T2 arg2)) {
+    var implementation = _delegationTarget._registerBinaryCallback;
+    _Zone implZone = implementation.zone;
+    RegisterBinaryCallbackHandler handler = implementation.function;
+    return handler(implZone, _parentDelegate(implZone), zone, f);
+  }
+
+  AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace) {
+    var implementation = _delegationTarget._errorCallback;
+    _Zone implZone = implementation.zone;
+    if (identical(implZone, _rootZone)) return null;
+    ErrorCallbackHandler handler = implementation.function;
+    return handler(
+        implZone, _parentDelegate(implZone), zone, error, stackTrace);
+  }
+
+  void scheduleMicrotask(Zone zone, f()) {
+    var implementation = _delegationTarget._scheduleMicrotask;
+    _Zone implZone = implementation.zone;
+    ScheduleMicrotaskHandler handler = implementation.function;
+    handler(implZone, _parentDelegate(implZone), zone, f);
+  }
+
+  Timer createTimer(Zone zone, Duration duration, void f()) {
+    var implementation = _delegationTarget._createTimer;
+    _Zone implZone = implementation.zone;
+    CreateTimerHandler handler = implementation.function;
+    return handler(implZone, _parentDelegate(implZone), zone, duration, f);
+  }
+
+  Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)) {
+    var implementation = _delegationTarget._createPeriodicTimer;
+    _Zone implZone = implementation.zone;
+    CreatePeriodicTimerHandler handler = implementation.function;
+    return handler(implZone, _parentDelegate(implZone), zone, period, f);
+  }
+
+  void print(Zone zone, String line) {
+    var implementation = _delegationTarget._print;
+    _Zone implZone = implementation.zone;
+    PrintHandler handler = implementation.function;
+    handler(implZone, _parentDelegate(implZone), zone, line);
+  }
+
+  Zone fork(Zone zone, ZoneSpecification specification, Map zoneValues) {
+    var implementation = _delegationTarget._fork;
+    _Zone implZone = implementation.zone;
+    ForkHandler handler = implementation.function;
+    return handler(
+        implZone, _parentDelegate(implZone), zone, specification, zoneValues);
+  }
+}
+
+/**
+ * Base class for Zone implementations.
+ */
+abstract class _Zone implements Zone {
+  const _Zone();
+
+  // TODO(floitsch): the types of the `_ZoneFunction`s should have a type for
+  // all fields.
+  _ZoneFunction<Function> get _run;
+  _ZoneFunction<Function> get _runUnary;
+  _ZoneFunction<Function> get _runBinary;
+  _ZoneFunction<Function> get _registerCallback;
+  _ZoneFunction<Function> get _registerUnaryCallback;
+  _ZoneFunction<Function> get _registerBinaryCallback;
+  _ZoneFunction<ErrorCallbackHandler> get _errorCallback;
+  _ZoneFunction<ScheduleMicrotaskHandler> get _scheduleMicrotask;
+  _ZoneFunction<CreateTimerHandler> get _createTimer;
+  _ZoneFunction<CreatePeriodicTimerHandler> get _createPeriodicTimer;
+  _ZoneFunction<PrintHandler> get _print;
+  _ZoneFunction<ForkHandler> get _fork;
+  _ZoneFunction<HandleUncaughtErrorHandler> get _handleUncaughtError;
+  _Zone get parent;
+  ZoneDelegate get _delegate;
+  Map get _map;
+
+  bool inSameErrorZone(Zone otherZone) {
+    return identical(this, otherZone) ||
+        identical(errorZone, otherZone.errorZone);
+  }
+}
+
+class _CustomZone extends _Zone {
+  // The actual zone and implementation of each of these
+  // inheritable zone functions.
+  // TODO(floitsch): the types of the `_ZoneFunction`s should have a type for
+  // all fields.
+  _ZoneFunction<Function> _run;
+  _ZoneFunction<Function> _runUnary;
+  _ZoneFunction<Function> _runBinary;
+  _ZoneFunction<Function> _registerCallback;
+  _ZoneFunction<Function> _registerUnaryCallback;
+  _ZoneFunction<Function> _registerBinaryCallback;
+  _ZoneFunction<ErrorCallbackHandler> _errorCallback;
+  _ZoneFunction<ScheduleMicrotaskHandler> _scheduleMicrotask;
+  _ZoneFunction<CreateTimerHandler> _createTimer;
+  _ZoneFunction<CreatePeriodicTimerHandler> _createPeriodicTimer;
+  _ZoneFunction<PrintHandler> _print;
+  _ZoneFunction<ForkHandler> _fork;
+  _ZoneFunction<HandleUncaughtErrorHandler> _handleUncaughtError;
+
+  // A cached delegate to this zone.
+  ZoneDelegate _delegateCache;
+
+  /// The parent zone.
+  final _Zone parent;
+
+  /// The zone's scoped value declaration map.
+  ///
+  /// This is always a [HashMap].
+  final Map _map;
+
+  ZoneDelegate get _delegate {
+    if (_delegateCache != null) return _delegateCache;
+    _delegateCache = new _ZoneDelegate(this);
+    return _delegateCache;
+  }
+
+  _CustomZone(this.parent, ZoneSpecification specification, this._map) {
+    // The root zone will have implementations of all parts of the
+    // specification, so it will never try to access the (null) parent.
+    // All other zones have a non-null parent.
+    _run = (specification.run != null)
+        ? new _ZoneFunction<Function>(this, specification.run)
+        : parent._run;
+    _runUnary = (specification.runUnary != null)
+        ? new _ZoneFunction<Function>(this, specification.runUnary)
+        : parent._runUnary;
+    _runBinary = (specification.runBinary != null)
+        ? new _ZoneFunction<Function>(this, specification.runBinary)
+        : parent._runBinary;
+    _registerCallback = (specification.registerCallback != null)
+        ? new _ZoneFunction<Function>(this, specification.registerCallback)
+        : parent._registerCallback;
+    _registerUnaryCallback = (specification.registerUnaryCallback != null)
+        ? new _ZoneFunction<Function>(this, specification.registerUnaryCallback)
+        : parent._registerUnaryCallback;
+    _registerBinaryCallback = (specification.registerBinaryCallback != null)
+        ? new _ZoneFunction<Function>(
+            this, specification.registerBinaryCallback)
+        : parent._registerBinaryCallback;
+    _errorCallback = (specification.errorCallback != null)
+        ? new _ZoneFunction<ErrorCallbackHandler>(
+            this, specification.errorCallback)
+        : parent._errorCallback;
+    _scheduleMicrotask = (specification.scheduleMicrotask != null)
+        ? new _ZoneFunction<ScheduleMicrotaskHandler>(
+            this, specification.scheduleMicrotask)
+        : parent._scheduleMicrotask;
+    _createTimer = (specification.createTimer != null)
+        ? new _ZoneFunction<CreateTimerHandler>(this, specification.createTimer)
+        : parent._createTimer;
+    _createPeriodicTimer = (specification.createPeriodicTimer != null)
+        ? new _ZoneFunction<CreatePeriodicTimerHandler>(
+            this, specification.createPeriodicTimer)
+        : parent._createPeriodicTimer;
+    _print = (specification.print != null)
+        ? new _ZoneFunction<PrintHandler>(this, specification.print)
+        : parent._print;
+    _fork = (specification.fork != null)
+        ? new _ZoneFunction<ForkHandler>(this, specification.fork)
+        : parent._fork;
+    _handleUncaughtError = (specification.handleUncaughtError != null)
+        ? new _ZoneFunction<HandleUncaughtErrorHandler>(
+            this, specification.handleUncaughtError)
+        : parent._handleUncaughtError;
+  }
+
+  /**
+   * The closest error-handling zone.
+   *
+   * Returns `this` if `this` has an error-handler. Otherwise returns the
+   * parent's error-zone.
+   */
+  Zone get errorZone => _handleUncaughtError.zone;
+
+  void runGuarded(void f()) {
+    try {
+      run(f);
+    } catch (e, s) {
+      handleUncaughtError(e, s);
+    }
+  }
+
+  void runUnaryGuarded<T>(void f(T arg), T arg) {
+    try {
+      runUnary(f, arg);
+    } catch (e, s) {
+      handleUncaughtError(e, s);
+    }
+  }
+
+  void runBinaryGuarded<T1, T2>(void f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) {
+    try {
+      runBinary(f, arg1, arg2);
+    } catch (e, s) {
+      handleUncaughtError(e, s);
+    }
+  }
+
+  ZoneCallback<R> bindCallback<R>(R f()) {
+    var registered = registerCallback(f);
+    return () => this.run(registered);
+  }
+
+  ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R f(T arg)) {
+    var registered = registerUnaryCallback(f);
+    return (arg) => this.runUnary(registered, arg);
+  }
+
+  ZoneBinaryCallback<R, T1, T2> bindBinaryCallback<R, T1, T2>(
+      R f(T1 arg1, T2 arg2)) {
+    var registered = registerBinaryCallback(f);
+    return (arg1, arg2) => this.runBinary(registered, arg1, arg2);
+  }
+
+  void Function() bindCallbackGuarded(void f()) {
+    var registered = registerCallback(f);
+    return () => this.runGuarded(registered);
+  }
+
+  void Function(T) bindUnaryCallbackGuarded<T>(void f(T arg)) {
+    var registered = registerUnaryCallback(f);
+    return (arg) => this.runUnaryGuarded(registered, arg);
+  }
+
+  void Function(T1, T2) bindBinaryCallbackGuarded<T1, T2>(
+      void f(T1 arg1, T2 arg2)) {
+    var registered = registerBinaryCallback(f);
+    return (arg1, arg2) => this.runBinaryGuarded(registered, arg1, arg2);
+  }
+
+  operator [](Object key) {
+    var result = _map[key];
+    if (result != null || _map.containsKey(key)) return result;
+    // If we are not the root zone, look up in the parent zone.
+    if (parent != null) {
+      // We do not optimize for repeatedly looking up a key which isn't
+      // there. That would require storing the key and keeping it alive.
+      // Copying the key/value from the parent does not keep any new values
+      // alive.
+      var value = parent[key];
+      if (value != null) {
+        _map[key] = value;
+      }
+      return value;
+    }
+    assert(this == _rootZone);
+    return null;
+  }
+
+  // Methods that can be customized by the zone specification.
+
+  void handleUncaughtError(error, StackTrace stackTrace) {
+    var implementation = this._handleUncaughtError;
+    assert(implementation != null);
+    ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
+    HandleUncaughtErrorHandler handler = implementation.function;
+    return handler(
+        implementation.zone, parentDelegate, this, error, stackTrace);
+  }
+
+  Zone fork({ZoneSpecification specification, Map zoneValues}) {
+    var implementation = this._fork;
+    assert(implementation != null);
+    ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
+    ForkHandler handler = implementation.function;
+    return handler(
+        implementation.zone, parentDelegate, this, specification, zoneValues);
+  }
+
+  R run<R>(R f()) {
+    var implementation = this._run;
+    assert(implementation != null);
+    ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
+    RunHandler handler = implementation.function;
+    return handler(implementation.zone, parentDelegate, this, f);
+  }
+
+  R runUnary<R, T>(R f(T arg), T arg) {
+    var implementation = this._runUnary;
+    assert(implementation != null);
+    ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
+    RunUnaryHandler handler = implementation.function;
+    return handler(implementation.zone, parentDelegate, this, f, arg);
+  }
+
+  R runBinary<R, T1, T2>(R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) {
+    var implementation = this._runBinary;
+    assert(implementation != null);
+    ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
+    RunBinaryHandler handler = implementation.function;
+    return handler(implementation.zone, parentDelegate, this, f, arg1, arg2);
+  }
+
+  ZoneCallback<R> registerCallback<R>(R callback()) {
+    var implementation = this._registerCallback;
+    assert(implementation != null);
+    ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
+    RegisterCallbackHandler handler = implementation.function;
+    return handler(implementation.zone, parentDelegate, this, callback);
+  }
+
+  ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(R callback(T arg)) {
+    var implementation = this._registerUnaryCallback;
+    assert(implementation != null);
+    ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
+    RegisterUnaryCallbackHandler handler = implementation.function;
+    return handler(implementation.zone, parentDelegate, this, callback);
+  }
+
+  ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>(
+      R callback(T1 arg1, T2 arg2)) {
+    var implementation = this._registerBinaryCallback;
+    assert(implementation != null);
+    ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
+    RegisterBinaryCallbackHandler handler = implementation.function;
+    return handler(implementation.zone, parentDelegate, this, callback);
+  }
+
+  AsyncError errorCallback(Object error, StackTrace stackTrace) {
+    var implementation = this._errorCallback;
+    assert(implementation != null);
+    final Zone implementationZone = implementation.zone;
+    if (identical(implementationZone, _rootZone)) return null;
+    final ZoneDelegate parentDelegate = _parentDelegate(implementationZone);
+    ErrorCallbackHandler handler = implementation.function;
+    return handler(implementationZone, parentDelegate, this, error, stackTrace);
+  }
+
+  void scheduleMicrotask(void f()) {
+    var implementation = this._scheduleMicrotask;
+    assert(implementation != null);
+    ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
+    ScheduleMicrotaskHandler handler = implementation.function;
+    return handler(implementation.zone, parentDelegate, this, f);
+  }
+
+  Timer createTimer(Duration duration, void f()) {
+    var implementation = this._createTimer;
+    assert(implementation != null);
+    ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
+    CreateTimerHandler handler = implementation.function;
+    return handler(implementation.zone, parentDelegate, this, duration, f);
+  }
+
+  Timer createPeriodicTimer(Duration duration, void f(Timer timer)) {
+    var implementation = this._createPeriodicTimer;
+    assert(implementation != null);
+    ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
+    CreatePeriodicTimerHandler handler = implementation.function;
+    return handler(implementation.zone, parentDelegate, this, duration, f);
+  }
+
+  void print(String line) {
+    var implementation = this._print;
+    assert(implementation != null);
+    ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
+    PrintHandler handler = implementation.function;
+    return handler(implementation.zone, parentDelegate, this, line);
+  }
+}
+
+void _rootHandleUncaughtError(
+    Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace) {
+  _schedulePriorityAsyncCallback(() {
+    error ??= new NullThrownError();
+    if (stackTrace == null) throw error;
+    _rethrow(error, stackTrace);
+  });
+}
+
+external void _rethrow(Object error, StackTrace stackTrace);
+
+R _rootRun<R>(Zone self, ZoneDelegate parent, Zone zone, R f()) {
+  if (Zone._current == zone) return f();
+
+  Zone old = Zone._enter(zone);
+  try {
+    return f();
+  } finally {
+    Zone._leave(old);
+  }
+}
+
+R _rootRunUnary<R, T>(
+    Zone self, ZoneDelegate parent, Zone zone, R f(T arg), T arg) {
+  if (Zone._current == zone) return f(arg);
+
+  Zone old = Zone._enter(zone);
+  try {
+    return f(arg);
+  } finally {
+    Zone._leave(old);
+  }
+}
+
+R _rootRunBinary<R, T1, T2>(Zone self, ZoneDelegate parent, Zone zone,
+    R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) {
+  if (Zone._current == zone) return f(arg1, arg2);
+
+  Zone old = Zone._enter(zone);
+  try {
+    return f(arg1, arg2);
+  } finally {
+    Zone._leave(old);
+  }
+}
+
+ZoneCallback<R> _rootRegisterCallback<R>(
+    Zone self, ZoneDelegate parent, Zone zone, R f()) {
+  return f;
+}
+
+ZoneUnaryCallback<R, T> _rootRegisterUnaryCallback<R, T>(
+    Zone self, ZoneDelegate parent, Zone zone, R f(T arg)) {
+  return f;
+}
+
+ZoneBinaryCallback<R, T1, T2> _rootRegisterBinaryCallback<R, T1, T2>(
+    Zone self, ZoneDelegate parent, Zone zone, R f(T1 arg1, T2 arg2)) {
+  return f;
+}
+
+AsyncError _rootErrorCallback(Zone self, ZoneDelegate parent, Zone zone,
+        Object error, StackTrace stackTrace) =>
+    null;
+
+void _rootScheduleMicrotask(
+    Zone self, ZoneDelegate parent, Zone zone, void f()) {
+  if (!identical(_rootZone, zone)) {
+    bool hasErrorHandler = !_rootZone.inSameErrorZone(zone);
+    if (hasErrorHandler) {
+      f = zone.bindCallbackGuarded(f);
+    } else {
+      f = zone.bindCallback(f);
+    }
+    // Use root zone as event zone if the function is already bound.
+    zone = _rootZone;
+  }
+  _scheduleAsyncCallback(f);
+}
+
+Timer _rootCreateTimer(Zone self, ZoneDelegate parent, Zone zone,
+    Duration duration, void callback()) {
+  if (!identical(_rootZone, zone)) {
+    callback = zone.bindCallback(callback);
+  }
+  return Timer._createTimer(duration, callback);
+}
+
+Timer _rootCreatePeriodicTimer(Zone self, ZoneDelegate parent, Zone zone,
+    Duration duration, void callback(Timer timer)) {
+  if (!identical(_rootZone, zone)) {
+    // TODO(floitsch): the return type should be 'void'.
+    callback = zone.bindUnaryCallback<dynamic, Timer>(callback);
+  }
+  return Timer._createPeriodicTimer(duration, callback);
+}
+
+void _rootPrint(Zone self, ZoneDelegate parent, Zone zone, String line) {
+  printToConsole(line);
+}
+
+void _printToZone(String line) {
+  Zone.current.print(line);
+}
+
+Zone _rootFork(Zone self, ZoneDelegate parent, Zone zone,
+    ZoneSpecification specification, Map zoneValues) {
+  // TODO(floitsch): it would be nice if we could get rid of this hack.
+  // Change the static zoneOrDirectPrint function to go through zones
+  // from now on.
+  printToZone = _printToZone;
+
+  if (specification == null) {
+    specification = const ZoneSpecification();
+  } else if (specification is! _ZoneSpecification) {
+    throw new ArgumentError("ZoneSpecifications must be instantiated"
+        " with the provided constructor.");
+  }
+  Map valueMap;
+  if (zoneValues == null) {
+    if (zone is _Zone) {
+      valueMap = zone._map;
+    } else {
+      valueMap = new HashMap();
+    }
+  } else {
+    valueMap = new HashMap.from(zoneValues);
+  }
+  return new _CustomZone(zone, specification, valueMap);
+}
+
+class _RootZone extends _Zone {
+  const _RootZone();
+
+  _ZoneFunction<Function> get _run =>
+      const _ZoneFunction<Function>(_rootZone, _rootRun);
+  _ZoneFunction<Function> get _runUnary =>
+      const _ZoneFunction<Function>(_rootZone, _rootRunUnary);
+  _ZoneFunction<Function> get _runBinary =>
+      const _ZoneFunction<Function>(_rootZone, _rootRunBinary);
+  _ZoneFunction<Function> get _registerCallback =>
+      const _ZoneFunction<Function>(_rootZone, _rootRegisterCallback);
+  _ZoneFunction<Function> get _registerUnaryCallback =>
+      const _ZoneFunction<Function>(_rootZone, _rootRegisterUnaryCallback);
+  _ZoneFunction<Function> get _registerBinaryCallback =>
+      const _ZoneFunction<Function>(_rootZone, _rootRegisterBinaryCallback);
+  _ZoneFunction<ErrorCallbackHandler> get _errorCallback =>
+      const _ZoneFunction<ErrorCallbackHandler>(_rootZone, _rootErrorCallback);
+  _ZoneFunction<ScheduleMicrotaskHandler> get _scheduleMicrotask =>
+      const _ZoneFunction<ScheduleMicrotaskHandler>(
+          _rootZone, _rootScheduleMicrotask);
+  _ZoneFunction<CreateTimerHandler> get _createTimer =>
+      const _ZoneFunction<CreateTimerHandler>(_rootZone, _rootCreateTimer);
+  _ZoneFunction<CreatePeriodicTimerHandler> get _createPeriodicTimer =>
+      const _ZoneFunction<CreatePeriodicTimerHandler>(
+          _rootZone, _rootCreatePeriodicTimer);
+  _ZoneFunction<PrintHandler> get _print =>
+      const _ZoneFunction<PrintHandler>(_rootZone, _rootPrint);
+  _ZoneFunction<ForkHandler> get _fork =>
+      const _ZoneFunction<ForkHandler>(_rootZone, _rootFork);
+  _ZoneFunction<HandleUncaughtErrorHandler> get _handleUncaughtError =>
+      const _ZoneFunction<HandleUncaughtErrorHandler>(
+          _rootZone, _rootHandleUncaughtError);
+
+  // The parent zone.
+  _Zone get parent => null;
+
+  /// The zone's scoped value declaration map.
+  ///
+  /// This is always a [HashMap].
+  Map get _map => _rootMap;
+
+  static final _rootMap = new HashMap();
+
+  static ZoneDelegate _rootDelegate;
+
+  ZoneDelegate get _delegate {
+    if (_rootDelegate != null) return _rootDelegate;
+    return _rootDelegate = new _ZoneDelegate(this);
+  }
+
+  /**
+   * The closest error-handling zone.
+   *
+   * Returns `this` if `this` has an error-handler. Otherwise returns the
+   * parent's error-zone.
+   */
+  Zone get errorZone => this;
+
+  // Zone interface.
+
+  void runGuarded(void f()) {
+    try {
+      if (identical(_rootZone, Zone._current)) {
+        f();
+        return;
+      }
+      _rootRun(null, null, this, f);
+    } catch (e, s) {
+      handleUncaughtError(e, s);
+    }
+  }
+
+  void runUnaryGuarded<T>(void f(T arg), T arg) {
+    try {
+      if (identical(_rootZone, Zone._current)) {
+        f(arg);
+        return;
+      }
+      _rootRunUnary(null, null, this, f, arg);
+    } catch (e, s) {
+      handleUncaughtError(e, s);
+    }
+  }
+
+  void runBinaryGuarded<T1, T2>(void f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) {
+    try {
+      if (identical(_rootZone, Zone._current)) {
+        f(arg1, arg2);
+        return;
+      }
+      _rootRunBinary(null, null, this, f, arg1, arg2);
+    } catch (e, s) {
+      handleUncaughtError(e, s);
+    }
+  }
+
+  ZoneCallback<R> bindCallback<R>(R f()) {
+    return () => this.run<R>(f);
+  }
+
+  ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R f(T arg)) {
+    return (arg) => this.runUnary<R, T>(f, arg);
+  }
+
+  ZoneBinaryCallback<R, T1, T2> bindBinaryCallback<R, T1, T2>(
+      R f(T1 arg1, T2 arg2)) {
+    return (arg1, arg2) => this.runBinary<R, T1, T2>(f, arg1, arg2);
+  }
+
+  void Function() bindCallbackGuarded(void f()) {
+    return () => this.runGuarded(f);
+  }
+
+  void Function(T) bindUnaryCallbackGuarded<T>(void f(T arg)) {
+    return (arg) => this.runUnaryGuarded(f, arg);
+  }
+
+  void Function(T1, T2) bindBinaryCallbackGuarded<T1, T2>(
+      void f(T1 arg1, T2 arg2)) {
+    return (arg1, arg2) => this.runBinaryGuarded(f, arg1, arg2);
+  }
+
+  operator [](Object key) => null;
+
+  // Methods that can be customized by the zone specification.
+
+  void handleUncaughtError(error, StackTrace stackTrace) {
+    _rootHandleUncaughtError(null, null, this, error, stackTrace);
+  }
+
+  Zone fork({ZoneSpecification specification, Map zoneValues}) {
+    return _rootFork(null, null, this, specification, zoneValues);
+  }
+
+  R run<R>(R f()) {
+    if (identical(Zone._current, _rootZone)) return f();
+    return _rootRun(null, null, this, f);
+  }
+
+  R runUnary<R, T>(R f(T arg), T arg) {
+    if (identical(Zone._current, _rootZone)) return f(arg);
+    return _rootRunUnary(null, null, this, f, arg);
+  }
+
+  R runBinary<R, T1, T2>(R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) {
+    if (identical(Zone._current, _rootZone)) return f(arg1, arg2);
+    return _rootRunBinary(null, null, this, f, arg1, arg2);
+  }
+
+  ZoneCallback<R> registerCallback<R>(R f()) => f;
+
+  ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(R f(T arg)) => f;
+
+  ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>(
+          R f(T1 arg1, T2 arg2)) =>
+      f;
+
+  AsyncError errorCallback(Object error, StackTrace stackTrace) => null;
+
+  void scheduleMicrotask(void f()) {
+    _rootScheduleMicrotask(null, null, this, f);
+  }
+
+  Timer createTimer(Duration duration, void f()) {
+    return Timer._createTimer(duration, f);
+  }
+
+  Timer createPeriodicTimer(Duration duration, void f(Timer timer)) {
+    return Timer._createPeriodicTimer(duration, f);
+  }
+
+  void print(String line) {
+    printToConsole(line);
+  }
+}
+
+const _rootZone = const _RootZone();
+
+/**
+ * Runs [body] in its own zone.
+ *
+ * Creates a new zone using [Zone.fork] based on [zoneSpecification] and
+ * [zoneValues], then runs [body] in that zone and returns the result.
+ *
+ * If [onError] is provided, it must have one of the types
+ * * `void Function(Object)`
+ * * `void Function(Object, StackTrace)`
+ * and the [onError] handler is used *both* to handle asynchronous errors
+ * by overriding [ZoneSpecification.handleUncaughtError] in [zoneSpecification],
+ * if any, *and* to handle errors thrown synchronously by the call to [body].
+ *
+ * If an error occurs synchronously in [body],
+ * then throwing in the [onError] handler
+ * makes the call to `runZone` throw that error,
+ * and otherwise the call to `runZoned` returns `null`.
+ *
+ * If the zone specification has a `handleUncaughtError` value or the [onError]
+ * parameter is provided, the zone becomes an error-zone.
+ *
+ * Errors will never cross error-zone boundaries by themselves.
+ * Errors that try to cross error-zone boundaries are considered uncaught in
+ * their originating error zone.
+ *
+ *     var future = new Future.value(499);
+ *     runZoned(() {
+ *       var future2 = future.then((_) { throw "error in first error-zone"; });
+ *       runZoned(() {
+ *         var future3 = future2.catchError((e) { print("Never reached!"); });
+ *       }, onError: (e) { print("unused error handler"); });
+ *     }, onError: (e) { print("catches error of first error-zone."); });
+ *
+ * Example:
+ *
+ *     runZoned(() {
+ *       new Future(() { throw "asynchronous error"; });
+ *     }, onError: print);  // Will print "asynchronous error".
+ *
+ * It is possible to manually pass an error from one error zone to another
+ * by re-throwing it in the new zone. If [onError] throws, that error will
+ * occur in the original zone where [runZoned] was called.
+ */
+R runZoned<R>(R body(),
+    {Map zoneValues, ZoneSpecification zoneSpecification, Function onError}) {
+  if (onError == null) {
+    return _runZoned<R>(body, zoneValues, zoneSpecification);
+  }
+  void Function(Object) unaryOnError;
+  void Function(Object, StackTrace) binaryOnError;
+  if (onError is void Function(Object, StackTrace)) {
+    binaryOnError = onError;
+  } else if (onError is void Function(Object)) {
+    unaryOnError = onError;
+  } else {
+    throw new ArgumentError("onError callback must take either an Object "
+        "(the error), or both an Object (the error) and a StackTrace.");
+  }
+  HandleUncaughtErrorHandler errorHandler = (Zone self, ZoneDelegate parent,
+      Zone zone, error, StackTrace stackTrace) {
+    try {
+      if (binaryOnError != null) {
+        self.parent.runBinary(binaryOnError, error, stackTrace);
+      } else {
+        assert(unaryOnError != null);
+        self.parent.runUnary(unaryOnError, error);
+      }
+    } catch (e, s) {
+      if (identical(e, error)) {
+        parent.handleUncaughtError(zone, error, stackTrace);
+      } else {
+        parent.handleUncaughtError(zone, e, s);
+      }
+    }
+  };
+  if (zoneSpecification == null) {
+    zoneSpecification =
+        new ZoneSpecification(handleUncaughtError: errorHandler);
+  } else {
+    zoneSpecification = new ZoneSpecification.from(zoneSpecification,
+        handleUncaughtError: errorHandler);
+  }
+  try {
+    return _runZoned<R>(body, zoneValues, zoneSpecification);
+  } catch (e, stackTrace) {
+    if (binaryOnError != null) {
+      binaryOnError(e, stackTrace);
+    } else {
+      assert(unaryOnError != null);
+      unaryOnError(e);
+    }
+  }
+  return null;
+}
+
+/// Runs [body] in a new zone based on [zoneValues] and [specification].
+R _runZoned<R>(R body(), Map zoneValues, ZoneSpecification specification) =>
+    Zone.current
+        .fork(specification: specification, zoneValues: zoneValues)
+        .run<R>(body);
diff --git a/sdk_nnbd/lib/cli/cli.dart b/sdk_nnbd/lib/cli/cli.dart
new file mode 100644
index 0000000..9c19c3a
--- /dev/null
+++ b/sdk_nnbd/lib/cli/cli.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// {@category VM}
+library dart.cli;
+
+import 'dart:async';
+import 'dart:math';
+
+part 'wait_for.dart';
diff --git a/sdk_nnbd/lib/cli/cli_sources.gni b/sdk_nnbd/lib/cli/cli_sources.gni
new file mode 100644
index 0000000..e90e1de
--- /dev/null
+++ b/sdk_nnbd/lib/cli/cli_sources.gni
@@ -0,0 +1,10 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+cli_sdk_sources = [
+  "cli.dart",
+
+  # The above file needs to be first if additional parts are added to the lib.
+  "wait_for.dart",
+]
diff --git a/sdk_nnbd/lib/cli/wait_for.dart b/sdk_nnbd/lib/cli/wait_for.dart
new file mode 100644
index 0000000..1886ff1
--- /dev/null
+++ b/sdk_nnbd/lib/cli/wait_for.dart
@@ -0,0 +1,152 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.cli;
+
+/**
+ * Synchronously blocks the calling isolate to wait for asynchronous events to
+ * complete.
+ *
+ * If the [timeout] parameter is supplied, [waitForEvent] will return after
+ * the specified timeout even if no events have occurred.
+ *
+ * This call does the following:
+ * - suspends the current execution stack,
+ * - runs the microtask queue until it is empty,
+ * - waits until the message queue is not empty,
+ * - handles messages on the message queue, plus their associated microtasks,
+ *   until the message queue is empty,
+ * - resumes the original stack.
+ *
+ * This function breaks the usual promise offered by Dart semantics that
+ * message handlers and microtasks run to completion before the next message
+ * handler or microtask begins to run. Of particular note is that use of this
+ * function in a finally block will allow microtasks and message handlers to
+ * run before all finally blocks for an exception have completed, possibly
+ * breaking invariants in your program.
+ *
+ * This function will synchronously throw the first unhandled exception it
+ * encounters in running the microtasks and message handlers as though the
+ * throwing microtask or message handler was the only Dart invocation on the
+ * stack. That is, unhandled exceptions in a microtask or message handler will
+ * skip over stacks suspended in a call to [waitForEvent].
+ *
+ * Calls to this function may be nested. Earlier invocations will not
+ * be able to complete until subsequent ones do. Messages that arrive after
+ * a subsequent invocation are "consumed" by that invocation, and do not
+ * unblock an earlier invocation. Please be aware that nesting calls to
+ * [waitForEvent] can lead to deadlock when subsequent calls block to wait for
+ * a condition that is only satisfied after an earlier call returns.
+ *
+ * Please note that this call is only available in the standalone command-line
+ * Dart VM. Further, because it suspends the current execution stack until the
+ * message queue is empty, even when running in the standalone command-line VM
+ * there exists a risk that the current execution stack will be starved.
+ */
+external void _waitForEvent(int timeoutMillis);
+
+@pragma("vm:entry-point")
+void Function(int) _getWaitForEvent() => _waitForEvent;
+
+// This should be set from C++ code by the embedder to wire up waitFor() to the
+// native implementation. In the standalone VM this is set to _waitForEvent()
+// above. If it is null, calling waitFor() will throw an UnsupportedError.
+@pragma("vm:entry-point")
+void Function(int) _waitForEventClosure;
+
+class _WaitForUtils {
+  static void waitForEvent({Duration timeout}) {
+    if (_waitForEventClosure == null) {
+      throw new UnsupportedError("waitFor is not supported by this embedder");
+    }
+    _waitForEventClosure(timeout == null ? 0 : max(1, timeout.inMilliseconds));
+  }
+}
+
+/**
+ * Suspends the stack, runs microtasks, and handles incoming events until
+ * [future] completes.
+ *
+ * WARNING: EXPERIMENTAL. USE AT YOUR OWN RISK.
+ *
+ * This call does the following:
+ * - While [future] is not completed:
+ *   - suspends the current execution stack,
+ *   - runs the microtask queue until it is empty,
+ *   - waits until the message queue is not empty,
+ *   - handles messages on the message queue, plus their associated microtasks,
+ *     until the message queue is empty,
+ *   - resumes the original stack.
+ *
+ * This function breaks the usual promise offered by Dart semantics that
+ * message handlers and microtasks run to completion before the next message
+ * handler or microtask begins to run. Of particular note is that use of this
+ * function in a finally block will allow microtasks and message handlers to
+ * run before all finally blocks for an exception have completed, possibly
+ * breaking invariants in your program.
+ *
+ * Use of this function should be considered a last resort when it is not
+ * possible to convert a Dart program entirely to an asynchronous style using
+ * `async` and `await`.
+ *
+ * If the [Future] completes normally, its result is returned. If the [Future]
+ * completes with an error, the error and stack trace are wrapped in an
+ * [AsyncError] and thrown. If a microtask or message handler run during this
+ * call results in an unhandled exception, that exception will be propagated
+ * as though the microtask or message handler was the only Dart invocation on
+ * the stack. That is, unhandled exceptions in a microtask or message handler
+ * will skip over stacks suspended in a call to [waitFor].
+ *
+ * If the optional `timeout` parameter is passed, [waitFor] throws a
+ * [TimeoutException] if the [Future] is not completed within the specified
+ * period.
+ *
+ * Calls to [waitFor] may be nested. Earlier invocations will not complete
+ * until subsequent ones do, but the completion of a subsequent invocation will
+ * cause the previous invocation to wake up and check its [Future] for
+ * completion.
+ *
+ * Please be aware that nesting calls to [waitFor] can lead to deadlock if
+ * subsequent calls block waiting for a condition that is only satisfied when
+ * an earlier call returns.
+ */
+T waitFor<T>(Future<T> future, {Duration timeout}) {
+  T result;
+  bool futureCompleted = false;
+  Object error;
+  StackTrace stacktrace;
+  future.then((r) {
+    futureCompleted = true;
+    result = r;
+  }, onError: (e, st) {
+    error = e;
+    stacktrace = st;
+  });
+
+  Stopwatch s;
+  if (timeout != null) {
+    s = new Stopwatch()..start();
+  }
+  Timer.run(() {}); // Enusre there is at least one message.
+  while (!futureCompleted && (error == null)) {
+    Duration remaining;
+    if (timeout != null) {
+      if (s.elapsed >= timeout) {
+        throw new TimeoutException("waitFor() timed out", timeout);
+      }
+      remaining = timeout - s.elapsed;
+    }
+    _WaitForUtils.waitForEvent(timeout: remaining);
+  }
+  if (timeout != null) {
+    s.stop();
+  }
+  Timer.run(() {}); // Ensure that previous calls to waitFor are woken up.
+
+  if (error != null) {
+    throw new AsyncError(error, stacktrace);
+  }
+
+  return result;
+}
diff --git a/sdk_nnbd/lib/collection/collection.dart b/sdk_nnbd/lib/collection/collection.dart
new file mode 100644
index 0000000..b050a48
--- /dev/null
+++ b/sdk_nnbd/lib/collection/collection.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 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.
+
+/// Classes and utilities that supplement the collection support in dart:core.
+///
+/// To use this library in your code:
+///
+///     import 'dart:collection';
+///
+/// {@category Core}
+library dart.collection;
+
+import 'dart:_internal' hide Symbol;
+import 'dart:math' show Random; // Used by ListMixin.shuffle.
+
+part 'collections.dart';
+part 'hash_map.dart';
+part 'hash_set.dart';
+part 'iterable.dart';
+part 'iterator.dart';
+part 'linked_hash_map.dart';
+part 'linked_hash_set.dart';
+part 'linked_list.dart';
+part 'list.dart';
+part 'maps.dart';
+part 'queue.dart';
+part 'set.dart';
+part 'splay_tree.dart';
diff --git a/sdk_nnbd/lib/collection/collection_sources.gni b/sdk_nnbd/lib/collection/collection_sources.gni
new file mode 100644
index 0000000..3f2f19e
--- /dev/null
+++ b/sdk_nnbd/lib/collection/collection_sources.gni
@@ -0,0 +1,23 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for 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 file contains all sources for the dart:collection library.
+collection_sdk_sources = [
+  "collection.dart",
+
+  # The above file needs to be first as it lists the parts below.
+  "collections.dart",
+  "hash_map.dart",
+  "hash_set.dart",
+  "iterable.dart",
+  "iterator.dart",
+  "linked_hash_map.dart",
+  "linked_hash_set.dart",
+  "linked_list.dart",
+  "list.dart",
+  "maps.dart",
+  "queue.dart",
+  "set.dart",
+  "splay_tree.dart",
+]
diff --git a/sdk_nnbd/lib/collection/collections.dart b/sdk_nnbd/lib/collection/collections.dart
new file mode 100644
index 0000000..9b43996
--- /dev/null
+++ b/sdk_nnbd/lib/collection/collections.dart
@@ -0,0 +1,24 @@
+// 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 dart.collection;
+
+/// An unmodifiable [List] view of another List.
+///
+/// The source of the elements may be a [List] or any [Iterable] with
+/// efficient [Iterable.length] and [Iterable.elementAt].
+class UnmodifiableListView<E> extends UnmodifiableListBase<E> {
+  final Iterable<E> _source;
+
+  /// Creates an unmodifiable list backed by [source].
+  ///
+  /// The [source] of the elements may be a [List] or any [Iterable] with
+  /// efficient [Iterable.length] and [Iterable.elementAt].
+  UnmodifiableListView(Iterable<E> source) : _source = source;
+
+  List<R> cast<R>() => UnmodifiableListView(_source.cast<R>());
+  int get length => _source.length;
+
+  E operator [](int index) => _source.elementAt(index);
+}
diff --git a/sdk_nnbd/lib/collection/hash_map.dart b/sdk_nnbd/lib/collection/hash_map.dart
new file mode 100644
index 0000000..525f43a
--- /dev/null
+++ b/sdk_nnbd/lib/collection/hash_map.dart
@@ -0,0 +1,156 @@
+// 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 dart.collection;
+
+/// Default function for equality comparison in customized HashMaps
+bool _defaultEquals(a, b) => a == b;
+
+/// Default function for hash-code computation in customized HashMaps
+int _defaultHashCode(a) => a.hashCode;
+
+/// Type of custom equality function
+typedef _Equality<K> = bool Function(K a, K b);
+
+/// Type of custom hash code function.
+typedef _Hasher<K> = int Function(K object);
+
+/// A hash-table based implementation of [Map].
+///
+/// The keys of a `HashMap` must have consistent [Object.==]
+/// and [Object.hashCode] implementations. This means that the `==` operator
+/// must define a stable equivalence relation on the keys (reflexive,
+/// symmetric, transitive, and consistent over time), and that `hashCode`
+/// must be the same for objects that are considered equal by `==`.
+///
+/// The map allows `null` as a key.
+///
+/// Iterating the map's keys, values or entries (through [forEach])
+/// may happen in any order.
+/// The iteration order only changes when the map is modified.
+/// Values are iterated in the same order as their associated keys,
+/// so iterating the [keys] and [values] in parallel
+/// will give matching key and value pairs.
+abstract class HashMap<K, V> implements Map<K, V> {
+  /// Creates an unordered hash-table based [Map].
+  ///
+  /// The created map is not ordered in any way. When iterating the keys or
+  /// values, the iteration order is unspecified except that it will stay the
+  /// same as long as the map isn't changed.
+  ///
+  /// If [equals] is provided, it is used to compare the keys in the table with
+  /// new keys. If [equals] is omitted, the key's own [Object.==] is used
+  /// instead.
+  ///
+  /// Similar, if [hashCode] is provided, it is used to produce a hash value
+  /// for keys in order to place them in the hash table. If it is omitted, the
+  /// key's own [Object.hashCode] is used.
+  ///
+  /// If using methods like [operator []], [remove] and [containsKey] together
+  /// with a custom equality and hashcode, an extra `isValidKey` function
+  /// can be supplied. This function is called before calling [equals] or
+  /// [hashCode] with an argument that may not be a [K] instance, and if the
+  /// call returns false, the key is assumed to not be in the set.
+  /// The [isValidKey] function defaults to just testing if the object is a
+  /// [K] instance.
+  ///
+  /// Example:
+  ///
+  ///     new HashMap<int,int>(equals: (int a, int b) => (b - a) % 5 == 0,
+  ///                          hashCode: (int e) => e % 5)
+  ///
+  /// This example map does not need an `isValidKey` function to be passed.
+  /// The default function accepts only `int` values, which can safely be
+  /// passed to both the `equals` and `hashCode` functions.
+  ///
+  /// If neither `equals`, `hashCode`, nor `isValidKey` is provided,
+  /// the default `isValidKey` instead accepts all keys.
+  /// The default equality and hashcode operations are assumed to work on all
+  /// objects.
+  ///
+  /// Likewise, if `equals` is [identical], `hashCode` is [identityHashCode]
+  /// and `isValidKey` is omitted, the resulting map is identity based,
+  /// and the `isValidKey` defaults to accepting all keys.
+  /// Such a map can be created directly using [HashMap.identity].
+  ///
+  /// The used `equals` and `hashCode` method should always be consistent,
+  /// so that if `equals(a, b)` then `hashCode(a) == hashCode(b)`. The hash
+  /// of an object, or what it compares equal to, should not change while the
+  /// object is a key in the map. If it does change, the result is
+  /// unpredictable.
+  ///
+  /// If you supply one of [equals] and [hashCode],
+  /// you should generally also to supply the other.
+  external factory HashMap(
+      {bool equals(K key1, K key2),
+      int hashCode(K key),
+      bool isValidKey(potentialKey)});
+
+  /// Creates an unordered identity-based map.
+  ///
+  /// Effectively a shorthand for:
+  ///
+  ///     new HashMap<K, V>(equals: identical,
+  ///                       hashCode: identityHashCode)
+  external factory HashMap.identity();
+
+  /// Creates a [HashMap] that contains all key/value pairs of [other].
+  ///
+  /// The keys must all be instances of [K] and the values of [V].
+  /// The [other] map itself can have any type.
+  factory HashMap.from(Map other) {
+    Map<K, V> result = HashMap<K, V>();
+    other.forEach((k, v) {
+      result[k] = v;
+    });
+    return result;
+  }
+
+  /// Creates a [HashMap] that contains all key/value pairs of [other].
+  factory HashMap.of(Map<K, V> other) => HashMap<K, V>()..addAll(other);
+
+  /// Creates a [HashMap] where the keys and values are computed from the
+  /// [iterable].
+  ///
+  /// For each element of the [iterable] this constructor computes a key/value
+  /// pair, by applying [key] and [value] respectively.
+  ///
+  /// The keys of the key/value pairs do not need to be unique. The last
+  /// occurrence of a key will simply overwrite any previous value.
+  ///
+  /// If no values are specified for [key] and [value] the default is the
+  /// identity function.
+  factory HashMap.fromIterable(Iterable iterable,
+      {K key(element), V value(element)}) {
+    Map<K, V> map = HashMap<K, V>();
+    MapBase._fillMapWithMappedIterable(map, iterable, key, value);
+    return map;
+  }
+
+  /// Creates a [HashMap] associating the given [keys] to [values].
+  ///
+  /// This constructor iterates over [keys] and [values] and maps each element
+  /// of [keys] to the corresponding element of [values].
+  ///
+  /// If [keys] contains the same object multiple times, the last occurrence
+  /// overwrites the previous value.
+  ///
+  /// It is an error if the two [Iterable]s don't have the same length.
+  factory HashMap.fromIterables(Iterable<K> keys, Iterable<V> values) {
+    Map<K, V> map = HashMap<K, V>();
+    MapBase._fillMapWithIterables(map, keys, values);
+    return map;
+  }
+
+  /// Creates a [HashMap] containing the entries of [entries].
+  ///
+  /// Returns a new `HashMap<K, V>` where all entries of [entries]
+  /// have been added in iteration order.
+  ///
+  /// If multiple [entries] have the same key,
+  /// later occurrences overwrite the earlier ones.
+  @Since("2.1")
+  factory HashMap.fromEntries(Iterable<MapEntry<K, V>> entries) =>
+      HashMap<K, V>()..addEntries(entries);
+}
diff --git a/sdk_nnbd/lib/collection/hash_set.dart b/sdk_nnbd/lib/collection/hash_set.dart
new file mode 100644
index 0000000..3fd00fe
--- /dev/null
+++ b/sdk_nnbd/lib/collection/hash_set.dart
@@ -0,0 +1,115 @@
+// 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 dart.collection;
+
+/// An unordered hash-table based [Set] implementation.
+///
+/// The elements of a `HashSet` must have consistent equality
+/// and hashCode implementations. This means that the equals operation
+/// must define a stable equivalence relation on the elements (reflexive,
+/// symmetric, transitive, and consistent over time), and that the hashCode
+/// must consistent with equality, so that the same for objects that are
+/// considered equal.
+///
+/// The set allows `null` as an element.
+///
+/// Most simple operations on `HashSet` are done in (potentially amortized)
+/// constant time: [add], [contains], [remove], and [length], provided the hash
+/// codes of objects are well distributed.
+///
+/// The iteration order of the set is not specified and depends on
+/// the hashcodes of the provided elements. However, the order is stable:
+/// multiple iterations over the same set produce the same order, as long as
+/// the set is not modified.
+abstract class HashSet<E> implements Set<E> {
+  /// Create a hash set using the provided [equals] as equality.
+  ///
+  /// The provided [equals] must define a stable equivalence relation, and
+  /// [hashCode] must be consistent with [equals]. If the [equals] or [hashCode]
+  /// methods won't work on all objects, but only on some instances of E, the
+  /// [isValidKey] predicate can be used to restrict the keys that the functions
+  /// are applied to.
+  /// Any key for which [isValidKey] returns false is automatically assumed
+  /// to not be in the set when asking `contains`.
+  ///
+  /// If [equals] or [hashCode] are omitted, the set uses
+  /// the elements' intrinsic [Object.==] and [Object.hashCode].
+  ///
+  /// If you supply one of [equals] and [hashCode],
+  /// you should generally also to supply the other.
+  ///
+  /// If the supplied `equals` or `hashCode` functions won't work on all [E]
+  /// objects, and the map will be used in a setting where a non-`E` object
+  /// is passed to, e.g., `contains`, then the [isValidKey] function should
+  /// also be supplied.
+  ///
+  /// If [isValidKey] is omitted, it defaults to testing if the object is an
+  /// [E] instance. That means that:
+  ///
+  ///     new HashSet<int>(equals: (int e1, int e2) => (e1 - e2) % 5 == 0,
+  ///                      hashCode: (int e) => e % 5)
+  ///
+  /// does not need an `isValidKey` argument, because it defaults to only
+  /// accepting `int` values which are accepted by both `equals` and `hashCode`.
+  ///
+  /// If neither `equals`, `hashCode`, nor `isValidKey` is provided,
+  /// the default `isValidKey` instead accepts all values.
+  /// The default equality and hashcode operations are assumed to work on all
+  /// objects.
+  ///
+  /// Likewise, if `equals` is [identical], `hashCode` is [identityHashCode]
+  /// and `isValidKey` is omitted, the resulting set is identity based,
+  /// and the `isValidKey` defaults to accepting all keys.
+  /// Such a map can be created directly using [HashSet.identity].
+  external factory HashSet(
+      {bool equals(E e1, E e2),
+      int hashCode(E e),
+      bool isValidKey(potentialKey)});
+
+  /// Creates an unordered identity-based set.
+  ///
+  /// Effectively a shorthand for:
+  ///
+  ///     new HashSet<E>(equals: identical,
+  ///                    hashCode: identityHashCode)
+  external factory HashSet.identity();
+
+  /// Create a hash set containing all [elements].
+  ///
+  /// Creates a hash set as by `new HashSet<E>()` and adds all given [elements]
+  /// to the set. The elements are added in order. If [elements] contains
+  /// two entries that are equal, but not identical, then the first one is
+  /// the one in the resulting set.
+  ///
+  /// All the [elements] should be instances of [E].
+  /// The `elements` iterable itself may have any element type, so this
+  /// constructor can be used to down-cast a `Set`, for example as:
+  /// ```dart
+  /// Set<SuperType> superSet = ...;
+  /// Set<SubType> subSet =
+  ///     new HashSet<SubType>.from(superSet.whereType<SubType>());
+  /// ```
+  factory HashSet.from(Iterable elements) {
+    HashSet<E> result = HashSet<E>();
+    for (final e in elements) {
+      result.add(e);
+    }
+    return result;
+  }
+
+  /// Create a hash set containing all [elements].
+  ///
+  /// Creates a hash set as by `new HashSet<E>()` and adds all given [elements]
+  /// to the set. The elements are added in order. If [elements] contains
+  /// two entries that are equal, but not identical, then the first one is
+  /// the one in the resulting set.
+  factory HashSet.of(Iterable<E> elements) => HashSet<E>()..addAll(elements);
+
+  /// Provides an iterator that iterates over the elements of this set.
+  ///
+  /// The order of iteration is unspecified,
+  /// but consistent between changes to the set.
+  Iterator<E> get iterator;
+}
diff --git a/sdk_nnbd/lib/collection/iterable.dart b/sdk_nnbd/lib/collection/iterable.dart
new file mode 100644
index 0000000..14e7226
--- /dev/null
+++ b/sdk_nnbd/lib/collection/iterable.dart
@@ -0,0 +1,402 @@
+// Copyright (c) 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 dart.collection;
+
+/// This [Iterable] mixin implements all [Iterable] members except `iterator`.
+///
+/// All other methods are implemented in terms of `iterator`.
+abstract class IterableMixin<E> implements Iterable<E> {
+  // This class has methods copied verbatim into:
+  // - IterableBase
+  // - SetMixin
+  // If changing a method here, also change the other copies.
+
+  Iterable<R> cast<R>() => Iterable.castFrom<E, R>(this);
+  Iterable<T> map<T>(T f(E element)) => MappedIterable<E, T>(this, f);
+
+  Iterable<E> where(bool f(E element)) => WhereIterable<E>(this, f);
+
+  Iterable<T> whereType<T>() => WhereTypeIterable<T>(this);
+
+  Iterable<T> expand<T>(Iterable<T> f(E element)) =>
+      ExpandIterable<E, T>(this, f);
+
+  Iterable<E> followedBy(Iterable<E> other) {
+    // Type workaround because IterableMixin<E> doesn't promote
+    // to EfficientLengthIterable<E>.
+    Iterable<E> self = this;
+    if (self is EfficientLengthIterable<E>) {
+      return FollowedByIterable<E>.firstEfficient(self, other);
+    }
+    return FollowedByIterable<E>(this, other);
+  }
+
+  bool contains(Object element) {
+    for (E e in this) {
+      if (e == element) return true;
+    }
+    return false;
+  }
+
+  void forEach(void f(E element)) {
+    for (E element in this) f(element);
+  }
+
+  E reduce(E combine(E value, E element)) {
+    Iterator<E> iterator = this.iterator;
+    if (!iterator.moveNext()) {
+      throw IterableElementError.noElement();
+    }
+    E value = iterator.current;
+    while (iterator.moveNext()) {
+      value = combine(value, iterator.current);
+    }
+    return value;
+  }
+
+  T fold<T>(T initialValue, T combine(T previousValue, E element)) {
+    var value = initialValue;
+    for (E element in this) value = combine(value, element);
+    return value;
+  }
+
+  bool every(bool f(E element)) {
+    for (E element in this) {
+      if (!f(element)) return false;
+    }
+    return true;
+  }
+
+  String join([String separator = ""]) {
+    Iterator<E> iterator = this.iterator;
+    if (!iterator.moveNext()) return "";
+    StringBuffer buffer = StringBuffer();
+    if (separator == null || separator == "") {
+      do {
+        buffer.write("${iterator.current}");
+      } while (iterator.moveNext());
+    } else {
+      buffer.write("${iterator.current}");
+      while (iterator.moveNext()) {
+        buffer.write(separator);
+        buffer.write("${iterator.current}");
+      }
+    }
+    return buffer.toString();
+  }
+
+  bool any(bool test(E element)) {
+    for (E element in this) {
+      if (test(element)) return true;
+    }
+    return false;
+  }
+
+  List<E> toList({bool growable = true}) =>
+      List<E>.from(this, growable: growable);
+
+  Set<E> toSet() => Set<E>.from(this);
+
+  int get length {
+    assert(this is! EfficientLengthIterable);
+    int count = 0;
+    Iterator it = iterator;
+    while (it.moveNext()) {
+      count++;
+    }
+    return count;
+  }
+
+  bool get isEmpty => !iterator.moveNext();
+
+  bool get isNotEmpty => !isEmpty;
+
+  Iterable<E> take(int count) {
+    return TakeIterable<E>(this, count);
+  }
+
+  Iterable<E> takeWhile(bool test(E value)) {
+    return TakeWhileIterable<E>(this, test);
+  }
+
+  Iterable<E> skip(int count) {
+    return SkipIterable<E>(this, count);
+  }
+
+  Iterable<E> skipWhile(bool test(E value)) {
+    return SkipWhileIterable<E>(this, test);
+  }
+
+  E get first {
+    Iterator<E> it = iterator;
+    if (!it.moveNext()) {
+      throw IterableElementError.noElement();
+    }
+    return it.current;
+  }
+
+  E get last {
+    Iterator<E> it = iterator;
+    if (!it.moveNext()) {
+      throw IterableElementError.noElement();
+    }
+    E result;
+    do {
+      result = it.current;
+    } while (it.moveNext());
+    return result;
+  }
+
+  E get single {
+    Iterator<E> it = iterator;
+    if (!it.moveNext()) throw IterableElementError.noElement();
+    E result = it.current;
+    if (it.moveNext()) throw IterableElementError.tooMany();
+    return result;
+  }
+
+  E firstWhere(bool test(E value), {E orElse()}) {
+    for (E element in this) {
+      if (test(element)) return element;
+    }
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E lastWhere(bool test(E value), {E orElse()}) {
+    E result;
+    bool foundMatching = false;
+    for (E element in this) {
+      if (test(element)) {
+        result = element;
+        foundMatching = true;
+      }
+    }
+    if (foundMatching) return result;
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E singleWhere(bool test(E element), {E orElse()}) {
+    E result;
+    bool foundMatching = false;
+    for (E element in this) {
+      if (test(element)) {
+        if (foundMatching) {
+          throw IterableElementError.tooMany();
+        }
+        result = element;
+        foundMatching = true;
+      }
+    }
+    if (foundMatching) return result;
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E elementAt(int index) {
+    ArgumentError.checkNotNull(index, "index");
+    RangeError.checkNotNegative(index, "index");
+    int elementIndex = 0;
+    for (E element in this) {
+      if (index == elementIndex) return element;
+      elementIndex++;
+    }
+    throw RangeError.index(index, this, "index", null, elementIndex);
+  }
+
+  String toString() => IterableBase.iterableToShortString(this, '(', ')');
+}
+
+/// Base class for implementing [Iterable].
+///
+/// This class implements all methods of [Iterable], except [Iterable.iterator],
+/// in terms of `iterator`.
+abstract class IterableBase<E> extends Iterable<E> {
+  const IterableBase();
+
+  /// Convert an `Iterable` to a string like [IterableBase.toString].
+  ///
+  /// Allows using other delimiters than '(' and ')'.
+  ///
+  /// Handles circular references where converting one of the elements
+  /// to a string ends up converting [iterable] to a string again.
+  static String iterableToShortString(Iterable iterable,
+      [String leftDelimiter = '(', String rightDelimiter = ')']) {
+    if (_isToStringVisiting(iterable)) {
+      if (leftDelimiter == "(" && rightDelimiter == ")") {
+        // Avoid creating a new string in the "common" case.
+        return "(...)";
+      }
+      return "$leftDelimiter...$rightDelimiter";
+    }
+    List<String> parts = <String>[];
+    _toStringVisiting.add(iterable);
+    try {
+      _iterablePartsToStrings(iterable, parts);
+    } finally {
+      assert(identical(_toStringVisiting.last, iterable));
+      _toStringVisiting.removeLast();
+    }
+    return (StringBuffer(leftDelimiter)
+          ..writeAll(parts, ", ")
+          ..write(rightDelimiter))
+        .toString();
+  }
+
+  /// Converts an `Iterable` to a string.
+  ///
+  /// Converts each elements to a string, and separates the results by ", ".
+  /// Then wraps the result in [leftDelimiter] and [rightDelimiter].
+  ///
+  /// Unlike [iterableToShortString], this conversion doesn't omit any
+  /// elements or puts any limit on the size of the result.
+  ///
+  /// Handles circular references where converting one of the elements
+  /// to a string ends up converting [iterable] to a string again.
+  static String iterableToFullString(Iterable iterable,
+      [String leftDelimiter = '(', String rightDelimiter = ')']) {
+    if (_isToStringVisiting(iterable)) {
+      return "$leftDelimiter...$rightDelimiter";
+    }
+    StringBuffer buffer = StringBuffer(leftDelimiter);
+    _toStringVisiting.add(iterable);
+    try {
+      buffer.writeAll(iterable, ", ");
+    } finally {
+      assert(identical(_toStringVisiting.last, iterable));
+      _toStringVisiting.removeLast();
+    }
+    buffer.write(rightDelimiter);
+    return buffer.toString();
+  }
+}
+
+/// A collection used to identify cyclic lists during toString() calls.
+final List _toStringVisiting = [];
+
+/// Check if we are currently visiting `o` in a toString call.
+bool _isToStringVisiting(Object o) {
+  for (int i = 0; i < _toStringVisiting.length; i++) {
+    if (identical(o, _toStringVisiting[i])) return true;
+  }
+  return false;
+}
+
+/// Convert elements of [iterable] to strings and store them in [parts].
+void _iterablePartsToStrings(Iterable iterable, List<String> parts) {
+  /*
+   * This is the complicated part of [iterableToShortString].
+   * It is extracted as a separate function to avoid having too much code
+   * inside the try/finally.
+   */
+  /// Try to stay below this many characters.
+  const int lengthLimit = 80;
+
+  /// Always at least this many elements at the start.
+  const int headCount = 3;
+
+  /// Always at least this many elements at the end.
+  const int tailCount = 2;
+
+  /// Stop iterating after this many elements. Iterables can be infinite.
+  const int maxCount = 100;
+  // Per entry length overhead. It's for ", " for all after the first entry,
+  // and for "(" and ")" for the initial entry. By pure luck, that's the same
+  // number.
+  const int overhead = 2;
+  const int ellipsisSize = 3; // "...".length.
+
+  int length = 0;
+  int count = 0;
+  Iterator it = iterable.iterator;
+  // Initial run of elements, at least headCount, and then continue until
+  // passing at most lengthLimit characters.
+  while (length < lengthLimit || count < headCount) {
+    if (!it.moveNext()) return;
+    String next = "${it.current}";
+    parts.add(next);
+    length += next.length + overhead;
+    count++;
+  }
+
+  String penultimateString;
+  String ultimateString;
+
+  // Find last two elements. One or more of them may already be in the
+  // parts array. Include their length in `length`.
+  Object penultimate;
+  Object ultimate;
+  if (!it.moveNext()) {
+    if (count <= headCount + tailCount) return;
+    ultimateString = parts.removeLast();
+    penultimateString = parts.removeLast();
+  } else {
+    penultimate = it.current;
+    count++;
+    if (!it.moveNext()) {
+      if (count <= headCount + 1) {
+        parts.add("$penultimate");
+        return;
+      }
+      ultimateString = "$penultimate";
+      penultimateString = parts.removeLast();
+      length += ultimateString.length + overhead;
+    } else {
+      ultimate = it.current;
+      count++;
+      // Then keep looping, keeping the last two elements in variables.
+      assert(count < maxCount);
+      while (it.moveNext()) {
+        penultimate = ultimate;
+        ultimate = it.current;
+        count++;
+        if (count > maxCount) {
+          // If we haven't found the end before maxCount, give up.
+          // This cannot happen in the code above because each entry
+          // increases length by at least two, so there is no way to
+          // visit more than ~40 elements before this loop.
+
+          // Remove any surplus elements until length, including ", ...)",
+          // is at most lengthLimit.
+          while (length > lengthLimit - ellipsisSize - overhead &&
+              count > headCount) {
+            length -= parts.removeLast().length + overhead;
+            count--;
+          }
+          parts.add("...");
+          return;
+        }
+      }
+      penultimateString = "$penultimate";
+      ultimateString = "$ultimate";
+      length += ultimateString.length + penultimateString.length + 2 * overhead;
+    }
+  }
+
+  // If there is a gap between the initial run and the last two,
+  // prepare to add an ellipsis.
+  String elision;
+  if (count > parts.length + tailCount) {
+    elision = "...";
+    length += ellipsisSize + overhead;
+  }
+
+  // If the last two elements were very long, and we have more than
+  // headCount elements in the initial run, drop some to make room for
+  // the last two.
+  while (length > lengthLimit && parts.length > headCount) {
+    length -= parts.removeLast().length + overhead;
+    if (elision == null) {
+      elision = "...";
+      length += ellipsisSize + overhead;
+    }
+  }
+  if (elision != null) {
+    parts.add(elision);
+  }
+  parts.add(penultimateString);
+  parts.add(ultimateString);
+}
diff --git a/sdk_nnbd/lib/collection/iterator.dart b/sdk_nnbd/lib/collection/iterator.dart
new file mode 100644
index 0000000..671f0ee
--- /dev/null
+++ b/sdk_nnbd/lib/collection/iterator.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 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 dart.collection;
+
+/// The [HasNextIterator] class wraps an [Iterator] and provides methods to
+/// iterate over an object using `hasNext` and `next`.
+///
+/// An [HasNextIterator] does not implement the [Iterator] interface.
+class HasNextIterator<E> {
+  static const int _HAS_NEXT_AND_NEXT_IN_CURRENT = 0;
+  static const int _NO_NEXT = 1;
+  static const int _NOT_MOVED_YET = 2;
+
+  Iterator<E> _iterator;
+  int _state = _NOT_MOVED_YET;
+
+  HasNextIterator(this._iterator);
+
+  bool get hasNext {
+    if (_state == _NOT_MOVED_YET) _move();
+    return _state == _HAS_NEXT_AND_NEXT_IN_CURRENT;
+  }
+
+  E next() {
+    // Call to hasNext is necessary to make sure we are positioned at the first
+    // element when we start iterating.
+    if (!hasNext) throw StateError("No more elements");
+    assert(_state == _HAS_NEXT_AND_NEXT_IN_CURRENT);
+    E result = _iterator.current;
+    _move();
+    return result;
+  }
+
+  void _move() {
+    if (_iterator.moveNext()) {
+      _state = _HAS_NEXT_AND_NEXT_IN_CURRENT;
+    } else {
+      _state = _NO_NEXT;
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/collection/linked_hash_map.dart b/sdk_nnbd/lib/collection/linked_hash_map.dart
new file mode 100644
index 0000000..e3a650d
--- /dev/null
+++ b/sdk_nnbd/lib/collection/linked_hash_map.dart
@@ -0,0 +1,141 @@
+// 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 dart.collection;
+
+/// A hash-table based implementation of [Map].
+///
+/// The insertion order of keys is remembered,
+/// and keys are iterated in the order they were inserted into the map.
+/// Values are iterated in their corresponding key's order.
+/// Changing a key's value, when the key is already in the map,
+/// does not change the iteration order,
+/// but removing the key and adding it again
+/// will make it be last in the iteration order.
+///
+/// The keys of a `LinkedHashMap` must have consistent [Object.==]
+/// and [Object.hashCode] implementations. This means that the `==` operator
+/// must define a stable equivalence relation on the keys (reflexive,
+/// symmetric, transitive, and consistent over time), and that `hashCode`
+/// must be the same for objects that are considered equal by `==`.
+///
+/// The map allows `null` as a key.
+abstract class LinkedHashMap<K, V> implements Map<K, V> {
+  /// Creates an insertion-ordered hash-table based [Map].
+  ///
+  /// If [equals] is provided, it is used to compare the keys in the table with
+  /// new keys. If [equals] is omitted, the key's own [Object.==] is used
+  /// instead.
+  ///
+  /// Similar, if [hashCode] is provided, it is used to produce a hash value
+  /// for keys in order to place them in the hash table. If it is omitted, the
+  /// key's own [Object.hashCode] is used.
+  ///
+  /// If using methods like [operator []], [remove] and [containsKey] together
+  /// with a custom equality and hashcode, an extra `isValidKey` function
+  /// can be supplied. This function is called before calling [equals] or
+  /// [hashCode] with an argument that may not be a [K] instance, and if the
+  /// call returns false, the key is assumed to not be in the set.
+  /// The [isValidKey] function defaults to just testing if the object is a
+  /// [K] instance.
+  ///
+  /// Example:
+  ///
+  ///     new LinkedHashMap<int,int>(equals: (int a, int b) => (b - a) % 5 == 0,
+  ///                                hashCode: (int e) => e % 5)
+  ///
+  /// This example map does not need an `isValidKey` function to be passed.
+  /// The default function accepts only `int` values, which can safely be
+  /// passed to both the `equals` and `hashCode` functions.
+  ///
+  /// If neither `equals`, `hashCode`, nor `isValidKey` is provided,
+  /// the default `isValidKey` instead accepts all keys.
+  /// The default equality and hashcode operations are assumed to work on all
+  /// objects.
+  ///
+  /// Likewise, if `equals` is [identical], `hashCode` is [identityHashCode]
+  /// and `isValidKey` is omitted, the resulting map is identity based,
+  /// and the `isValidKey` defaults to accepting all keys.
+  /// Such a map can be created directly using [LinkedHashMap.identity].
+  ///
+  /// The used `equals` and `hashCode` method should always be consistent,
+  /// so that if `equals(a, b)` then `hashCode(a) == hashCode(b)`. The hash
+  /// of an object, or what it compares equal to, should not change while the
+  /// object is in the table. If it does change, the result is unpredictable.
+  ///
+  /// If you supply one of [equals] and [hashCode],
+  /// you should generally also to supply the other.
+  external factory LinkedHashMap(
+      {bool equals(K key1, K key2),
+      int hashCode(K key),
+      bool isValidKey(potentialKey)});
+
+  /// Creates an insertion-ordered identity-based map.
+  ///
+  /// Effectively a shorthand for:
+  ///
+  ///     new LinkedHashMap<K, V>(equals: identical,
+  ///                             hashCode: identityHashCode)
+  external factory LinkedHashMap.identity();
+
+  /// Creates a [LinkedHashMap] that contains all key value pairs of [other].
+  ///
+  /// The keys must all be instances of [K] and the values to [V].
+  /// The [other] map itself can have any type.
+  factory LinkedHashMap.from(Map other) {
+    LinkedHashMap<K, V> result = LinkedHashMap<K, V>();
+    other.forEach((k, v) {
+      result[k] = v;
+    });
+    return result;
+  }
+
+  /// Creates a [LinkedHashMap] that contains all key value pairs of [other].
+  factory LinkedHashMap.of(Map<K, V> other) =>
+      LinkedHashMap<K, V>()..addAll(other);
+
+  /// Creates a [LinkedHashMap] where the keys and values are computed from the
+  /// [iterable].
+  ///
+  /// For each element of the [iterable] this constructor computes a key/value
+  /// pair, by applying [key] and [value] respectively.
+  ///
+  /// The keys of the key/value pairs do not need to be unique. The last
+  /// occurrence of a key will simply overwrite any previous value.
+  ///
+  /// If no values are specified for [key] and [value] the default is the
+  /// identity function.
+  factory LinkedHashMap.fromIterable(Iterable iterable,
+      {K key(element), V value(element)}) {
+    LinkedHashMap<K, V> map = LinkedHashMap<K, V>();
+    MapBase._fillMapWithMappedIterable(map, iterable, key, value);
+    return map;
+  }
+
+  /// Creates a [LinkedHashMap] associating the given [keys] to [values].
+  ///
+  /// This constructor iterates over [keys] and [values] and maps each element of
+  /// [keys] to the corresponding element of [values].
+  ///
+  /// If [keys] contains the same object multiple times, the last occurrence
+  /// overwrites the previous value.
+  ///
+  /// It is an error if the two [Iterable]s don't have the same length.
+  factory LinkedHashMap.fromIterables(Iterable<K> keys, Iterable<V> values) {
+    LinkedHashMap<K, V> map = LinkedHashMap<K, V>();
+    MapBase._fillMapWithIterables(map, keys, values);
+    return map;
+  }
+
+  /// Creates a [LinkedHashMap] containing the entries of [entries].
+  ///
+  /// Returns a new `LinkedHashMap<K, V>` where all entries of [entries]
+  /// have been added in iteration order.
+  ///
+  /// If multiple [entries] have the same key,
+  /// later occurrences overwrite the earlier ones.
+  @Since("2.1")
+  factory LinkedHashMap.fromEntries(Iterable<MapEntry<K, V>> entries) =>
+      <K, V>{}..addEntries(entries);
+}
diff --git a/sdk_nnbd/lib/collection/linked_hash_set.dart b/sdk_nnbd/lib/collection/linked_hash_set.dart
new file mode 100644
index 0000000..a058b5e
--- /dev/null
+++ b/sdk_nnbd/lib/collection/linked_hash_set.dart
@@ -0,0 +1,120 @@
+// 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 dart.collection;
+
+/// A [LinkedHashSet] is a hash-table based [Set] implementation.
+///
+/// The `LinkedHashSet` also keep track of the order that elements were inserted
+/// in, and iteration happens in first-to-last insertion order.
+///
+/// The elements of a `LinkedHashSet` must have consistent [Object.==]
+/// and [Object.hashCode] implementations. This means that the `==` operator
+/// must define a stable equivalence relation on the elements (reflexive,
+/// symmetric, transitive, and consistent over time), and that `hashCode`
+/// must be the same for objects that are considered equal by `==`.
+///
+/// The set allows `null` as an element.
+///
+/// Iteration of elements is done in element insertion order.
+/// An element that was added after another will occur later in the iteration.
+/// Adding an element that is already in the set
+/// does not change its position in the iteration order,
+/// but removing an element and adding it again,
+/// will make it the last element of an iteration.
+///
+/// Most simple operations on `HashSet` are done in (potentially amortized)
+/// constant time: [add], [contains], [remove], and [length], provided the hash
+/// codes of objects are well distributed..
+abstract class LinkedHashSet<E> implements Set<E> {
+  /// Create an insertion-ordered hash set using the provided
+  /// [equals] and [hashCode].
+  ///
+  /// The provided [equals] must define a stable equivalence relation, and
+  /// [hashCode] must be consistent with [equals]. If the [equals] or [hashCode]
+  /// methods won't work on all objects, but only on some instances of E, the
+  /// [isValidKey] predicate can be used to restrict the keys that the functions
+  /// are applied to.
+  /// Any key for which [isValidKey] returns false is automatically assumed
+  /// to not be in the set when asking `contains`.
+  ///
+  /// If [equals] or [hashCode] are omitted, the set uses
+  /// the elements' intrinsic [Object.==] and [Object.hashCode],
+  /// and [isValidKey] is ignored since these operations are assumed
+  /// to work on all objects.
+  ///
+  /// If you supply one of [equals] and [hashCode],
+  /// you should generally also to supply the other.
+  ///
+  /// If the supplied `equals` or `hashCode` functions won't work on all [E]
+  /// objects, and the map will be used in a setting where a non-`E` object
+  /// is passed to, e.g., `contains`, then the [isValidKey] function should
+  /// also be supplied.
+  ///
+  /// If [isValidKey] is omitted, it defaults to testing if the object is an
+  /// [E] instance. That means that:
+  ///
+  ///     new LinkedHashSet<int>(equals: (int e1, int e2) => (e1 - e2) % 5 == 0,
+  ///                            hashCode: (int e) => e % 5)
+  ///
+  /// does not need an `isValidKey` argument, because it defaults to only
+  /// accepting `int` values which are accepted by both `equals` and `hashCode`.
+  ///
+  /// If neither `equals`, `hashCode`, nor `isValidKey` is provided,
+  /// the default `isValidKey` instead accepts all values.
+  /// The default equality and hashcode operations are assumed to work on all
+  /// objects.
+  ///
+  /// Likewise, if `equals` is [identical], `hashCode` is [identityHashCode]
+  /// and `isValidKey` is omitted, the resulting set is identity based,
+  /// and the `isValidKey` defaults to accepting all keys.
+  /// Such a map can be created directly using [LinkedHashSet.identity].
+  external factory LinkedHashSet(
+      {bool equals(E e1, E e2),
+      int hashCode(E e),
+      bool isValidKey(potentialKey)});
+
+  /// Creates an insertion-ordered identity-based set.
+  ///
+  /// Effectively a shorthand for:
+  ///
+  ///     new LinkedHashSet<E>(equals: identical,
+  ///                          hashCode: identityHashCode)
+  external factory LinkedHashSet.identity();
+
+  /// Create a linked hash set containing all [elements].
+  ///
+  /// Creates a linked hash set as by `new LinkedHashSet<E>()` and adds each
+  /// element of `elements` to this set in the order they are iterated.
+  ///
+  /// All the [elements] should be instances of [E].
+  /// The `elements` iterable itself may have any element type,
+  /// so this constructor can be used to down-cast a `Set`, for example as:
+  ///
+  ///     Set<SuperType> superSet = ...;
+  ///     Iterable<SuperType> tmp = superSet.where((e) => e is SubType);
+  ///     Set<SubType> subSet = new LinkedHashSet<SubType>.from(tmp);
+  factory LinkedHashSet.from(Iterable elements) {
+    LinkedHashSet<E> result = LinkedHashSet<E>();
+    for (final element in elements) {
+      result.add(element);
+    }
+    return result;
+  }
+
+  /// Create a linked hash set from [elements].
+  ///
+  /// Creates a linked hash set as by `new LinkedHashSet<E>()` and adds each
+  /// element of `elements` to this set in the order they are iterated.
+  factory LinkedHashSet.of(Iterable<E> elements) =>
+      LinkedHashSet<E>()..addAll(elements);
+
+  /// Executes a function on each element of the set.
+  ///
+  /// The elements are iterated in insertion order.
+  void forEach(void action(E element));
+
+  /// Provides an iterator that iterates over the elements in insertion order.
+  Iterator<E> get iterator;
+}
diff --git a/sdk_nnbd/lib/collection/linked_list.dart b/sdk_nnbd/lib/collection/linked_list.dart
new file mode 100644
index 0000000..91461cb
--- /dev/null
+++ b/sdk_nnbd/lib/collection/linked_list.dart
@@ -0,0 +1,263 @@
+// 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 dart.collection;
+
+/// A specialized double-linked list of elements that extends [LinkedListEntry].
+///
+/// This is not a generic data structure. It only accepts elements that extend
+/// the [LinkedListEntry] class. See the [Queue] implementations for generic
+/// collections that allow constant time adding and removing at the ends.
+///
+/// This is not a [List] implementation. Despite its name, this class does not
+/// implement the [List] interface. It does not allow constant time lookup by
+/// index.
+///
+/// Because the elements themselves contain the links of this linked list,
+/// each element can be in only one list at a time. To add an element to another
+/// list, it must first be removed from its current list (if any).
+///
+/// In return, each element knows its own place in the linked list, as well as
+/// which list it is in. This allows constant time
+/// [LinkedListEntry.insertAfter], [LinkedListEntry.insertBefore] and
+/// [LinkedListEntry.unlink] operations when all you have is the element.
+///
+/// A `LinkedList` also allows constant time adding and removing at either end,
+/// and a constant time length getter.
+class LinkedList<E extends LinkedListEntry<E>> extends Iterable<E> {
+  int _modificationCount = 0;
+  int _length = 0;
+  E _first;
+
+  /// Construct a new empty linked list.
+  LinkedList();
+
+  /// Add [entry] to the beginning of the linked list.
+  void addFirst(E entry) {
+    _insertBefore(_first, entry, updateFirst: true);
+    _first = entry;
+  }
+
+  /// Add [entry] to the end of the linked list.
+  void add(E entry) {
+    _insertBefore(_first, entry, updateFirst: false);
+  }
+
+  /// Add [entries] to the end of the linked list.
+  void addAll(Iterable<E> entries) {
+    entries.forEach(add);
+  }
+
+  /// Remove [entry] from the linked list.
+  ///
+  /// Returns false and does nothing if [entry] is not in this linked list.
+  ///
+  /// This is equivalent to calling `entry.unlink()` if the entry is in this
+  /// list.
+  bool remove(E entry) {
+    if (entry._list != this) return false;
+    _unlink(entry); // Unlink will decrement length.
+    return true;
+  }
+
+  Iterator<E> get iterator => _LinkedListIterator<E>(this);
+
+  int get length => _length;
+
+  /// Remove all elements from this linked list.
+  void clear() {
+    _modificationCount++;
+    if (isEmpty) return;
+
+    E next = _first;
+    do {
+      E entry = next;
+      next = entry._next;
+      entry._next = entry._previous = entry._list = null;
+    } while (!identical(next, _first));
+
+    _first = null;
+    _length = 0;
+  }
+
+  E get first {
+    if (isEmpty) {
+      throw StateError('No such element');
+    }
+    return _first;
+  }
+
+  E get last {
+    if (isEmpty) {
+      throw StateError('No such element');
+    }
+    return _first._previous;
+  }
+
+  E get single {
+    if (isEmpty) {
+      throw StateError('No such element');
+    }
+    if (_length > 1) {
+      throw StateError('Too many elements');
+    }
+    return _first;
+  }
+
+  /// Call [action] with each entry in this linked list.
+  ///
+  /// It's an error if [action] modify the linked list.
+  void forEach(void action(E entry)) {
+    int modificationCount = _modificationCount;
+    if (isEmpty) return;
+
+    E current = _first;
+    do {
+      action(current);
+      if (modificationCount != _modificationCount) {
+        throw ConcurrentModificationError(this);
+      }
+      current = current._next;
+    } while (!identical(current, _first));
+  }
+
+  bool get isEmpty => _length == 0;
+
+  /// Inserts [newEntry] as last entry of the list.
+  ///
+  /// If [updateFirst] is true and [entry] is the first entry in the list,
+  /// updates the [_first] field to point to the [newEntry] as first entry.
+  void _insertBefore(E entry, E newEntry, {bool updateFirst}) {
+    if (newEntry.list != null) {
+      throw StateError('LinkedListEntry is already in a LinkedList');
+    }
+    _modificationCount++;
+
+    newEntry._list = this;
+    if (isEmpty) {
+      assert(entry == null);
+      newEntry._previous = newEntry._next = newEntry;
+      _first = newEntry;
+      _length++;
+      return;
+    }
+    E predecessor = entry._previous;
+    E successor = entry;
+    newEntry._previous = predecessor;
+    newEntry._next = successor;
+    predecessor._next = newEntry;
+    successor._previous = newEntry;
+    if (updateFirst && identical(entry, _first)) {
+      _first = newEntry;
+    }
+    _length++;
+  }
+
+  void _unlink(E entry) {
+    _modificationCount++;
+    entry._next._previous = entry._previous;
+    E next = entry._previous._next = entry._next;
+    _length--;
+    entry._list = entry._next = entry._previous = null;
+    if (isEmpty) {
+      _first = null;
+    } else if (identical(entry, _first)) {
+      _first = next;
+    }
+  }
+}
+
+class _LinkedListIterator<E extends LinkedListEntry<E>> implements Iterator<E> {
+  final LinkedList<E> _list;
+  final int _modificationCount;
+  E _current;
+  LinkedListEntry<E> _next;
+  bool _visitedFirst;
+
+  _LinkedListIterator(LinkedList<E> list)
+      : _list = list,
+        _modificationCount = list._modificationCount,
+        _next = list._first,
+        _visitedFirst = false;
+
+  E get current => _current;
+
+  bool moveNext() {
+    if (_modificationCount != _list._modificationCount) {
+      throw ConcurrentModificationError(this);
+    }
+    if (_list.isEmpty || (_visitedFirst && identical(_next, _list.first))) {
+      _current = null;
+      return false;
+    }
+    _visitedFirst = true;
+    _current = _next;
+    _next = _next._next;
+    return true;
+  }
+}
+
+/// An object that can be an element in a [LinkedList].
+///
+/// All elements of a `LinkedList` must extend this class.
+/// The class provides the internal links that link elements together
+/// in the `LinkedList`, and a reference to the linked list itself
+/// that an element is currently part of.
+///
+/// An entry can be in at most one linked list at a time.
+/// While an entry is in a linked list, the [list] property points to that
+/// linked list, and otherwise the `list` property is `null`.
+///
+/// When created, an entry is not in any linked list.
+abstract class LinkedListEntry<E extends LinkedListEntry<E>> {
+  LinkedList<E> _list;
+  E _next;
+  E _previous;
+
+  /// Get the linked list containing this element.
+  ///
+  /// Returns `null` if this entry is not currently in any list.
+  LinkedList<E> get list => _list;
+
+  /// Unlink the element from its linked list.
+  ///
+  /// The entry must currently be in a linked list when this method is called.
+  void unlink() {
+    _list._unlink(this);
+  }
+
+  /// Return the successor of this element in its linked list.
+  ///
+  /// Returns `null` if there is no successor in the linked list, or if this
+  /// entry is not currently in any list.
+  E get next {
+    if (_list == null || identical(_list.first, _next)) return null;
+    return _next;
+  }
+
+  /// Return the predecessor of this element in its linked list.
+  ///
+  /// Returns `null` if there is no predecessor in the linked list, or if this
+  /// entry is not currently in any list.
+  E get previous {
+    if (_list == null || identical(this, _list.first)) return null;
+    return _previous;
+  }
+
+  /// Insert an element after this element in this element's linked list.
+  ///
+  /// This entry must be in a linked list when this method is called.
+  /// The [entry] must not be in a linked list.
+  void insertAfter(E entry) {
+    _list._insertBefore(_next, entry, updateFirst: false);
+  }
+
+  /// Insert an element before this element in this element's linked list.
+  ///
+  /// This entry must be in a linked list when this method is called.
+  /// The [entry] must not be in a linked list.
+  void insertBefore(E entry) {
+    _list._insertBefore(this, entry, updateFirst: true);
+  }
+}
diff --git a/sdk_nnbd/lib/collection/list.dart b/sdk_nnbd/lib/collection/list.dart
new file mode 100644
index 0000000..1d83aa4
--- /dev/null
+++ b/sdk_nnbd/lib/collection/list.dart
@@ -0,0 +1,535 @@
+// 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 dart.collection;
+
+/// Abstract implementation of a list.
+///
+/// `ListBase` can be used as a base class for implementing the `List`
+/// interface.
+///
+/// All operations are defined in terms of `length`, `operator[]`,
+/// `operator[]=` and `length=`, which need to be implemented.
+///
+/// *NOTICE*: Forwarding just these four operations to a normal growable [List]
+/// (as created by `new List()`) will give very bad performance for `add` and
+/// `addAll` operations of `ListBase`. These operations are implemented by
+/// increasing the length of the list by one for each `add` operation, and
+/// repeatedly increasing the length of a growable list is not efficient.
+/// To avoid this, either override 'add' and 'addAll' to also forward directly
+/// to the growable list, or, preferably, use `DelegatingList` from
+/// "package:collection/wrappers.dart" instead.
+abstract class ListBase<E> extends Object with ListMixin<E> {
+  /// Convert a `List` to a string as `[each, element, as, string]`.
+  ///
+  /// Handles circular references where converting one of the elements
+  /// to a string ends up converting [list] to a string again.
+  static String listToString(List list) =>
+      IterableBase.iterableToFullString(list, '[', ']');
+}
+
+/// Base implementation of a [List] class.
+///
+/// `ListMixin` can be used as a mixin to make a class implement
+/// the `List` interface.
+///
+/// This implements all read operations using only the `length` and
+/// `operator[]` members. It implements write operations using those and
+/// `length=` and `operator[]=`
+///
+/// *NOTICE*: Forwarding just these four operations to a normal growable [List]
+/// (as created by `new List()`) will give very bad performance for `add` and
+/// `addAll` operations of `ListBase`. These operations are implemented by
+/// increasing the length of the list by one for each `add` operation, and
+/// repeatedly increasing the length of a growable list is not efficient.
+/// To avoid this, either override 'add' and 'addAll' to also forward directly
+/// to the growable list, or, if possible, use `DelegatingList` from
+/// "package:collection/wrappers.dart" instead.
+abstract class ListMixin<E> implements List<E> {
+  // Iterable interface.
+  // TODO(lrn): When we get composable mixins, reuse IterableMixin instead
+  // of redaclating everything.
+  Iterator<E> get iterator => ListIterator<E>(this);
+
+  E elementAt(int index) => this[index];
+
+  Iterable<E> followedBy(Iterable<E> other) =>
+      FollowedByIterable<E>.firstEfficient(this, other);
+
+  void forEach(void action(E element)) {
+    int length = this.length;
+    for (int i = 0; i < length; i++) {
+      action(this[i]);
+      if (length != this.length) {
+        throw ConcurrentModificationError(this);
+      }
+    }
+  }
+
+  @pragma("vm:prefer-inline")
+  bool get isEmpty => length == 0;
+
+  bool get isNotEmpty => !isEmpty;
+
+  E get first {
+    if (length == 0) throw IterableElementError.noElement();
+    return this[0];
+  }
+
+  void set first(E value) {
+    if (length == 0) throw IterableElementError.noElement();
+    this[0] = value;
+  }
+
+  E get last {
+    if (length == 0) throw IterableElementError.noElement();
+    return this[length - 1];
+  }
+
+  void set last(E value) {
+    if (length == 0) throw IterableElementError.noElement();
+    this[length - 1] = value;
+  }
+
+  E get single {
+    if (length == 0) throw IterableElementError.noElement();
+    if (length > 1) throw IterableElementError.tooMany();
+    return this[0];
+  }
+
+  bool contains(Object element) {
+    int length = this.length;
+    for (int i = 0; i < length; i++) {
+      if (this[i] == element) return true;
+      if (length != this.length) {
+        throw ConcurrentModificationError(this);
+      }
+    }
+    return false;
+  }
+
+  bool every(bool test(E element)) {
+    int length = this.length;
+    for (int i = 0; i < length; i++) {
+      if (!test(this[i])) return false;
+      if (length != this.length) {
+        throw ConcurrentModificationError(this);
+      }
+    }
+    return true;
+  }
+
+  bool any(bool test(E element)) {
+    int length = this.length;
+    for (int i = 0; i < length; i++) {
+      if (test(this[i])) return true;
+      if (length != this.length) {
+        throw ConcurrentModificationError(this);
+      }
+    }
+    return false;
+  }
+
+  E firstWhere(bool test(E element), {E orElse()}) {
+    int length = this.length;
+    for (int i = 0; i < length; i++) {
+      E element = this[i];
+      if (test(element)) return element;
+      if (length != this.length) {
+        throw ConcurrentModificationError(this);
+      }
+    }
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E lastWhere(bool test(E element), {E orElse()}) {
+    int length = this.length;
+    for (int i = length - 1; i >= 0; i--) {
+      E element = this[i];
+      if (test(element)) return element;
+      if (length != this.length) {
+        throw ConcurrentModificationError(this);
+      }
+    }
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E singleWhere(bool test(E element), {E orElse()}) {
+    int length = this.length;
+    E match;
+    bool matchFound = false;
+    for (int i = 0; i < length; i++) {
+      E element = this[i];
+      if (test(element)) {
+        if (matchFound) {
+          throw IterableElementError.tooMany();
+        }
+        matchFound = true;
+        match = element;
+      }
+      if (length != this.length) {
+        throw ConcurrentModificationError(this);
+      }
+    }
+    if (matchFound) return match;
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  String join([String separator = ""]) {
+    if (length == 0) return "";
+    StringBuffer buffer = StringBuffer()..writeAll(this, separator);
+    return buffer.toString();
+  }
+
+  Iterable<E> where(bool test(E element)) => WhereIterable<E>(this, test);
+
+  Iterable<T> whereType<T>() => WhereTypeIterable<T>(this);
+
+  Iterable<T> map<T>(T f(E element)) => MappedListIterable<E, T>(this, f);
+
+  Iterable<T> expand<T>(Iterable<T> f(E element)) =>
+      ExpandIterable<E, T>(this, f);
+
+  E reduce(E combine(E previousValue, E element)) {
+    int length = this.length;
+    if (length == 0) throw IterableElementError.noElement();
+    E value = this[0];
+    for (int i = 1; i < length; i++) {
+      value = combine(value, this[i]);
+      if (length != this.length) {
+        throw ConcurrentModificationError(this);
+      }
+    }
+    return value;
+  }
+
+  T fold<T>(T initialValue, T combine(T previousValue, E element)) {
+    var value = initialValue;
+    int length = this.length;
+    for (int i = 0; i < length; i++) {
+      value = combine(value, this[i]);
+      if (length != this.length) {
+        throw ConcurrentModificationError(this);
+      }
+    }
+    return value;
+  }
+
+  Iterable<E> skip(int count) => SubListIterable<E>(this, count, null);
+
+  Iterable<E> skipWhile(bool test(E element)) {
+    return SkipWhileIterable<E>(this, test);
+  }
+
+  Iterable<E> take(int count) => SubListIterable<E>(this, 0, count);
+
+  Iterable<E> takeWhile(bool test(E element)) {
+    return TakeWhileIterable<E>(this, test);
+  }
+
+  List<E> toList({bool growable = true}) {
+    List<E> result;
+    if (growable) {
+      result = <E>[]..length = length;
+    } else {
+      result = List<E>(length);
+    }
+    for (int i = 0; i < length; i++) {
+      result[i] = this[i];
+    }
+    return result;
+  }
+
+  Set<E> toSet() {
+    Set<E> result = Set<E>();
+    for (int i = 0; i < length; i++) {
+      result.add(this[i]);
+    }
+    return result;
+  }
+
+  // List interface.
+  void add(E element) {
+    this[this.length++] = element;
+  }
+
+  void addAll(Iterable<E> iterable) {
+    int i = this.length;
+    for (E element in iterable) {
+      assert(this.length == i || (throw ConcurrentModificationError(this)));
+      this.length = i + 1;
+      this[i] = element;
+      i++;
+    }
+  }
+
+  bool remove(Object element) {
+    for (int i = 0; i < this.length; i++) {
+      if (this[i] == element) {
+        this._closeGap(i, i + 1);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /// Removes elements from the list starting at [start] up to but not including
+  /// [end].  Arguments are pre-validated.
+  void _closeGap(int start, int end) {
+    int length = this.length;
+    assert(0 <= start);
+    assert(start < end);
+    assert(end <= length);
+    int size = end - start;
+    for (int i = end; i < length; i++) {
+      this[i - size] = this[i];
+    }
+    this.length = length - size;
+  }
+
+  void removeWhere(bool test(E element)) {
+    _filter(test, false);
+  }
+
+  void retainWhere(bool test(E element)) {
+    _filter(test, true);
+  }
+
+  void _filter(bool test(E element), bool retainMatching) {
+    List<E> retained = <E>[];
+    int length = this.length;
+    for (int i = 0; i < length; i++) {
+      var element = this[i];
+      if (test(element) == retainMatching) {
+        retained.add(element);
+      }
+      if (length != this.length) {
+        throw ConcurrentModificationError(this);
+      }
+    }
+    if (retained.length != this.length) {
+      this.setRange(0, retained.length, retained);
+      this.length = retained.length;
+    }
+  }
+
+  void clear() {
+    this.length = 0;
+  }
+
+  List<R> cast<R>() => List.castFrom<E, R>(this);
+  E removeLast() {
+    if (length == 0) {
+      throw IterableElementError.noElement();
+    }
+    E result = this[length - 1];
+    length--;
+    return result;
+  }
+
+  void sort([int compare(E a, E b)]) {
+    Sort.sort(this, compare ?? _compareAny);
+  }
+
+  static int _compareAny(a, b) {
+    // In strong mode Comparable.compare requires an implicit cast to ensure
+    // `a` and `b` are Comparable.
+    return Comparable.compare(a, b);
+  }
+
+  void shuffle([Random random]) {
+    random ??= Random();
+    int length = this.length;
+    while (length > 1) {
+      int pos = random.nextInt(length);
+      length -= 1;
+      var tmp = this[length];
+      this[length] = this[pos];
+      this[pos] = tmp;
+    }
+  }
+
+  Map<int, E> asMap() {
+    return ListMapView<E>(this);
+  }
+
+  List<E> operator +(List<E> other) {
+    var result = <E>[]..length = (this.length + other.length);
+    result.setRange(0, this.length, this);
+    result.setRange(this.length, result.length, other);
+    return result;
+  }
+
+  List<E> sublist(int start, [int end]) {
+    int listLength = this.length;
+    end ??= listLength;
+    RangeError.checkValidRange(start, end, listLength);
+    int length = end - start;
+    List<E> result = <E>[]..length = length;
+    for (int i = 0; i < length; i++) {
+      result[i] = this[start + i];
+    }
+    return result;
+  }
+
+  Iterable<E> getRange(int start, int end) {
+    RangeError.checkValidRange(start, end, this.length);
+    return SubListIterable<E>(this, start, end);
+  }
+
+  void removeRange(int start, int end) {
+    RangeError.checkValidRange(start, end, this.length);
+    if (end > start) {
+      _closeGap(start, end);
+    }
+  }
+
+  void fillRange(int start, int end, [E fill]) {
+    RangeError.checkValidRange(start, end, this.length);
+    for (int i = start; i < end; i++) {
+      this[i] = fill;
+    }
+  }
+
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+    RangeError.checkValidRange(start, end, this.length);
+    int length = end - start;
+    if (length == 0) return;
+    RangeError.checkNotNegative(skipCount, "skipCount");
+
+    List<E> otherList;
+    int otherStart;
+    // TODO(floitsch): Make this accept more.
+    if (iterable is List<E>) {
+      otherList = iterable;
+      otherStart = skipCount;
+    } else {
+      otherList = iterable.skip(skipCount).toList(growable: false);
+      otherStart = 0;
+    }
+    if (otherStart + length > otherList.length) {
+      throw IterableElementError.tooFew();
+    }
+    if (otherStart < start) {
+      // Copy backwards to ensure correct copy if [from] is this.
+      for (int i = length - 1; i >= 0; i--) {
+        this[start + i] = otherList[otherStart + i];
+      }
+    } else {
+      for (int i = 0; i < length; i++) {
+        this[start + i] = otherList[otherStart + i];
+      }
+    }
+  }
+
+  void replaceRange(int start, int end, Iterable<E> newContents) {
+    RangeError.checkValidRange(start, end, this.length);
+    if (newContents is! EfficientLengthIterable) {
+      newContents = newContents.toList();
+    }
+    int removeLength = end - start;
+    int insertLength = newContents.length;
+    if (removeLength >= insertLength) {
+      int insertEnd = start + insertLength;
+      this.setRange(start, insertEnd, newContents);
+      if (removeLength > insertLength) {
+        _closeGap(insertEnd, end);
+      }
+    } else {
+      int delta = insertLength - removeLength;
+      int newLength = this.length + delta;
+      int insertEnd = start + insertLength; // aka. end + delta.
+      this.length = newLength;
+      this.setRange(insertEnd, newLength, this, end);
+      this.setRange(start, insertEnd, newContents);
+    }
+  }
+
+  int indexOf(Object element, [int start = 0]) {
+    if (start < 0) start = 0;
+    for (int i = start; i < this.length; i++) {
+      if (this[i] == element) return i;
+    }
+    return -1;
+  }
+
+  int indexWhere(bool test(E element), [int start = 0]) {
+    if (start < 0) start = 0;
+    for (int i = start; i < this.length; i++) {
+      if (test(this[i])) return i;
+    }
+    return -1;
+  }
+
+  int lastIndexOf(Object element, [int start]) {
+    if (start == null || start >= this.length) start = this.length - 1;
+    for (int i = start; i >= 0; i--) {
+      if (this[i] == element) return i;
+    }
+    return -1;
+  }
+
+  int lastIndexWhere(bool test(E element), [int start]) {
+    if (start == null || start >= this.length) start = this.length - 1;
+    for (int i = start; i >= 0; i--) {
+      if (test(this[i])) return i;
+    }
+    return -1;
+  }
+
+  void insert(int index, E element) {
+    ArgumentError.checkNotNull(index, "index");
+    RangeError.checkValueInInterval(index, 0, length, "index");
+    if (index == this.length) {
+      add(element);
+      return;
+    }
+    this.length++;
+    setRange(index + 1, this.length, this, index);
+    this[index] = element;
+  }
+
+  E removeAt(int index) {
+    E result = this[index];
+    _closeGap(index, index + 1);
+    return result;
+  }
+
+  void insertAll(int index, Iterable<E> iterable) {
+    RangeError.checkValueInInterval(index, 0, length, "index");
+    if (iterable is! EfficientLengthIterable || identical(iterable, this)) {
+      iterable = iterable.toList();
+    }
+    int insertionLength = iterable.length;
+    // There might be errors after the length change, in which case the list
+    // will end up being modified but the operation not complete. Unless we
+    // always go through a "toList" we can't really avoid that.
+    this.length += insertionLength;
+    if (iterable.length != insertionLength) {
+      // If the iterable's length is linked to this list's length somehow,
+      // we can't insert one in the other.
+      this.length -= insertionLength;
+      throw ConcurrentModificationError(iterable);
+    }
+    setRange(index + insertionLength, this.length, this, index);
+    setAll(index, iterable);
+  }
+
+  void setAll(int index, Iterable<E> iterable) {
+    if (iterable is List) {
+      setRange(index, index + iterable.length, iterable);
+    } else {
+      for (E element in iterable) {
+        this[index++] = element;
+      }
+    }
+  }
+
+  Iterable<E> get reversed => ReversedListIterable<E>(this);
+
+  String toString() => IterableBase.iterableToFullString(this, '[', ']');
+}
diff --git a/sdk_nnbd/lib/collection/maps.dart b/sdk_nnbd/lib/collection/maps.dart
new file mode 100644
index 0000000..8159342
--- /dev/null
+++ b/sdk_nnbd/lib/collection/maps.dart
@@ -0,0 +1,378 @@
+// Copyright (c) 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 dart.collection;
+
+/// Base class for implementing a [Map].
+///
+/// This class has a basic implementation of all but five of the members of
+/// [Map].
+/// A basic `Map` class can be implemented by extending this class and
+/// implementing `keys`, `operator[]`, `operator[]=`, `remove` and `clear`.
+/// The remaining operations are implemented in terms of these five.
+///
+/// The `keys` iterable should have efficient [Iterable.length] and
+/// [Iterable.contains] operations, and it should catch concurrent modifications
+/// of the keys while iterating.
+///
+/// A more efficient implementation is usually possible by overriding
+/// some of the other members as well.
+abstract class MapBase<K, V> extends MapMixin<K, V> {
+  static String mapToString(Map m) {
+    // Reuses the list in IterableBase for detecting toString cycles.
+    if (_isToStringVisiting(m)) {
+      return '{...}';
+    }
+
+    var result = StringBuffer();
+    try {
+      _toStringVisiting.add(m);
+      result.write('{');
+      bool first = true;
+      m.forEach((k, v) {
+        if (!first) {
+          result.write(', ');
+        }
+        first = false;
+        result.write(k);
+        result.write(': ');
+        result.write(v);
+      });
+      result.write('}');
+    } finally {
+      assert(identical(_toStringVisiting.last, m));
+      _toStringVisiting.removeLast();
+    }
+
+    return result.toString();
+  }
+
+  static _id(x) => x;
+
+  /// Fills a [Map] with key/value pairs computed from [iterable].
+  ///
+  /// This method is used by [Map] classes in the named constructor
+  /// `fromIterable`.
+  static void _fillMapWithMappedIterable(
+      Map map, Iterable iterable, key(element), value(element)) {
+    key ??= _id;
+    value ??= _id;
+
+    for (var element in iterable) {
+      map[key(element)] = value(element);
+    }
+  }
+
+  /// Fills a map by associating the [keys] to [values].
+  ///
+  /// This method is used by [Map] classes in the named constructor
+  /// `fromIterables`.
+  static void _fillMapWithIterables(Map map, Iterable keys, Iterable values) {
+    Iterator keyIterator = keys.iterator;
+    Iterator valueIterator = values.iterator;
+
+    bool hasNextKey = keyIterator.moveNext();
+    bool hasNextValue = valueIterator.moveNext();
+
+    while (hasNextKey && hasNextValue) {
+      map[keyIterator.current] = valueIterator.current;
+      hasNextKey = keyIterator.moveNext();
+      hasNextValue = valueIterator.moveNext();
+    }
+
+    if (hasNextKey || hasNextValue) {
+      throw ArgumentError("Iterables do not have same length.");
+    }
+  }
+}
+
+/// Mixin implementing a [Map].
+///
+/// This mixin has a basic implementation of all but five of the members of
+/// [Map].
+/// A basic `Map` class can be implemented by mixin in this class and
+/// implementing `keys`, `operator[]`, `operator[]=`, `remove` and `clear`.
+/// The remaining operations are implemented in terms of these five.
+///
+/// The `keys` iterable should have efficient [Iterable.length] and
+/// [Iterable.contains] operations, and it should catch concurrent modifications
+/// of the keys while iterating.
+///
+/// A more efficient implementation is usually possible by overriding
+/// some of the other members as well.
+abstract class MapMixin<K, V> implements Map<K, V> {
+  Iterable<K> get keys;
+  V operator [](Object key);
+  operator []=(K key, V value);
+  V remove(Object key);
+  // The `clear` operation should not be based on `remove`.
+  // It should clear the map even if some keys are not equal to themselves.
+  void clear();
+
+  Map<RK, RV> cast<RK, RV>() => Map.castFrom<K, V, RK, RV>(this);
+  void forEach(void action(K key, V value)) {
+    for (K key in keys) {
+      action(key, this[key]);
+    }
+  }
+
+  void addAll(Map<K, V> other) {
+    for (K key in other.keys) {
+      this[key] = other[key];
+    }
+  }
+
+  bool containsValue(Object value) {
+    for (K key in keys) {
+      if (this[key] == value) return true;
+    }
+    return false;
+  }
+
+  V putIfAbsent(K key, V ifAbsent()) {
+    if (containsKey(key)) {
+      return this[key];
+    }
+    return this[key] = ifAbsent();
+  }
+
+  V update(K key, V update(V value), {V ifAbsent()}) {
+    if (this.containsKey(key)) {
+      return this[key] = update(this[key]);
+    }
+    if (ifAbsent != null) {
+      return this[key] = ifAbsent();
+    }
+    throw ArgumentError.value(key, "key", "Key not in map.");
+  }
+
+  void updateAll(V update(K key, V value)) {
+    for (var key in this.keys) {
+      this[key] = update(key, this[key]);
+    }
+  }
+
+  Iterable<MapEntry<K, V>> get entries {
+    return keys.map((K key) => MapEntry<K, V>(key, this[key]));
+  }
+
+  Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> transform(K key, V value)) {
+    var result = <K2, V2>{};
+    for (var key in this.keys) {
+      var entry = transform(key, this[key]);
+      result[entry.key] = entry.value;
+    }
+    return result;
+  }
+
+  void addEntries(Iterable<MapEntry<K, V>> newEntries) {
+    for (var entry in newEntries) {
+      this[entry.key] = entry.value;
+    }
+  }
+
+  void removeWhere(bool test(K key, V value)) {
+    var keysToRemove = <K>[];
+    for (var key in keys) {
+      if (test(key, this[key])) keysToRemove.add(key);
+    }
+    for (var key in keysToRemove) {
+      this.remove(key);
+    }
+  }
+
+  bool containsKey(Object key) => keys.contains(key);
+  int get length => keys.length;
+  bool get isEmpty => keys.isEmpty;
+  bool get isNotEmpty => keys.isNotEmpty;
+  Iterable<V> get values => _MapBaseValueIterable<K, V>(this);
+  String toString() => MapBase.mapToString(this);
+}
+
+/// Basic implementation of an unmodifiable [Map].
+///
+/// This class has a basic implementation of all but two of the members of
+/// an umodifiable [Map].
+/// A simple unmodifiable `Map` class can be implemented by extending this
+/// class and implementing `keys` and `operator[]`.
+///
+/// Modifying operations throw when used.
+/// The remaining non-modifying operations are implemented in terms of `keys`
+/// and `operator[]`.
+///
+/// The `keys` iterable should have efficient [Iterable.length] and
+/// [Iterable.contains] operations, and it should catch concurrent modifications
+/// of the keys while iterating.
+///
+/// A more efficient implementation is usually possible by overriding
+/// some of the other members as well.
+abstract class UnmodifiableMapBase<K, V> = MapBase<K, V>
+    with _UnmodifiableMapMixin<K, V>;
+
+/// Implementation of [Map.values] based on the map and its [Map.keys] iterable.
+///
+/// Iterable that iterates over the values of a `Map`.
+/// It accesses the values by iterating over the keys of the map, and using the
+/// map's `operator[]` to lookup the keys.
+class _MapBaseValueIterable<K, V> extends EfficientLengthIterable<V> {
+  final Map<K, V> _map;
+  _MapBaseValueIterable(this._map);
+
+  int get length => _map.length;
+  bool get isEmpty => _map.isEmpty;
+  bool get isNotEmpty => _map.isNotEmpty;
+  V get first => _map[_map.keys.first];
+  V get single => _map[_map.keys.single];
+  V get last => _map[_map.keys.last];
+
+  Iterator<V> get iterator => _MapBaseValueIterator<K, V>(_map);
+}
+
+/// Iterator created by [_MapBaseValueIterable].
+///
+/// Iterates over the values of a map by iterating its keys and lookup up the
+/// values.
+class _MapBaseValueIterator<K, V> implements Iterator<V> {
+  final Iterator<K> _keys;
+  final Map<K, V> _map;
+  V _current;
+
+  _MapBaseValueIterator(Map<K, V> map)
+      : _map = map,
+        _keys = map.keys.iterator;
+
+  bool moveNext() {
+    if (_keys.moveNext()) {
+      _current = _map[_keys.current];
+      return true;
+    }
+    _current = null;
+    return false;
+  }
+
+  V get current => _current;
+}
+
+/// Mixin that overrides mutating map operations with implementations that
+/// throw.
+abstract class _UnmodifiableMapMixin<K, V> implements Map<K, V> {
+  /// This operation is not supported by an unmodifiable map.
+  void operator []=(K key, V value) {
+    throw UnsupportedError("Cannot modify unmodifiable map");
+  }
+
+  /// This operation is not supported by an unmodifiable map.
+  void addAll(Map<K, V> other) {
+    throw UnsupportedError("Cannot modify unmodifiable map");
+  }
+
+  /// This operation is not supported by an unmodifiable map.
+  void addEntries(Iterable<MapEntry<K, V>> entries) {
+    throw UnsupportedError("Cannot modify unmodifiable map");
+  }
+
+  /// This operation is not supported by an unmodifiable map.
+  void clear() {
+    throw UnsupportedError("Cannot modify unmodifiable map");
+  }
+
+  /// This operation is not supported by an unmodifiable map.
+  V remove(Object key) {
+    throw UnsupportedError("Cannot modify unmodifiable map");
+  }
+
+  /// This operation is not supported by an unmodifiable map.
+  void removeWhere(bool test(K key, V value)) {
+    throw UnsupportedError("Cannot modify unmodifiable map");
+  }
+
+  /// This operation is not supported by an unmodifiable map.
+  V putIfAbsent(K key, V ifAbsent()) {
+    throw UnsupportedError("Cannot modify unmodifiable map");
+  }
+
+  /// This operation is not supported by an unmodifiable map.
+  V update(K key, V update(V value), {V ifAbsent()}) {
+    throw UnsupportedError("Cannot modify unmodifiable map");
+  }
+
+  /// This operation is not supported by an unmodifiable map.
+  void updateAll(V update(K key, V value)) {
+    throw UnsupportedError("Cannot modify unmodifiable map");
+  }
+}
+
+/// Wrapper around a class that implements [Map] that only exposes `Map`
+/// members.
+///
+/// A simple wrapper that delegates all `Map` members to the map provided in the
+/// constructor.
+///
+/// Base for delegating map implementations like [UnmodifiableMapView].
+class MapView<K, V> implements Map<K, V> {
+  final Map<K, V> _map;
+  const MapView(Map<K, V> map) : _map = map;
+
+  Map<RK, RV> cast<RK, RV>() => _map.cast<RK, RV>();
+  V operator [](Object key) => _map[key];
+  void operator []=(K key, V value) {
+    _map[key] = value;
+  }
+
+  void addAll(Map<K, V> other) {
+    _map.addAll(other);
+  }
+
+  void clear() {
+    _map.clear();
+  }
+
+  V putIfAbsent(K key, V ifAbsent()) => _map.putIfAbsent(key, ifAbsent);
+  bool containsKey(Object key) => _map.containsKey(key);
+  bool containsValue(Object value) => _map.containsValue(value);
+  void forEach(void action(K key, V value)) {
+    _map.forEach(action);
+  }
+
+  bool get isEmpty => _map.isEmpty;
+  bool get isNotEmpty => _map.isNotEmpty;
+  int get length => _map.length;
+  Iterable<K> get keys => _map.keys;
+  V remove(Object key) => _map.remove(key);
+  String toString() => _map.toString();
+  Iterable<V> get values => _map.values;
+
+  Iterable<MapEntry<K, V>> get entries => _map.entries;
+
+  void addEntries(Iterable<MapEntry<K, V>> entries) {
+    _map.addEntries(entries);
+  }
+
+  Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> transform(K key, V value)) =>
+      _map.map<K2, V2>(transform);
+
+  V update(K key, V update(V value), {V ifAbsent()}) =>
+      _map.update(key, update, ifAbsent: ifAbsent);
+
+  void updateAll(V update(K key, V value)) {
+    _map.updateAll(update);
+  }
+
+  void removeWhere(bool test(K key, V value)) {
+    _map.removeWhere(test);
+  }
+}
+
+/// View of a [Map] that disallow modifying the map.
+///
+/// A wrapper around a `Map` that forwards all members to the map provided in
+/// the constructor, except for operations that modify the map.
+/// Modifying operations throw instead.
+class UnmodifiableMapView<K, V> extends MapView<K, V>
+    with _UnmodifiableMapMixin<K, V> {
+  UnmodifiableMapView(Map<K, V> map) : super(map);
+
+  Map<RK, RV> cast<RK, RV>() =>
+      UnmodifiableMapView<RK, RV>(_map.cast<RK, RV>());
+}
diff --git a/sdk_nnbd/lib/collection/queue.dart b/sdk_nnbd/lib/collection/queue.dart
new file mode 100644
index 0000000..62994b9
--- /dev/null
+++ b/sdk_nnbd/lib/collection/queue.dart
@@ -0,0 +1,887 @@
+// 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.
+
+part of dart.collection;
+
+/// A [Queue] is a collection that can be manipulated at both ends. One
+/// can iterate over the elements of a queue through [forEach] or with
+/// an [Iterator].
+///
+/// It is generally not allowed to modify the queue (add or remove entries)
+/// while an operation on the queue is being performed, for example during a
+/// call to [forEach].
+/// Modifying the queue while it is being iterated will most likely break the
+/// iteration.
+/// This goes both for using the [iterator] directly, or for iterating an
+/// `Iterable` returned by a method like [map] or [where].
+abstract class Queue<E> implements EfficientLengthIterable<E> {
+  /// Creates a queue.
+  factory Queue() = ListQueue<E>;
+
+  /// Creates a queue containing all [elements].
+  ///
+  /// The element order in the queue is as if the elements were added using
+  /// [addLast] in the order provided by [elements.iterator].
+  ///
+  /// All the [elements] should be instances of [E].
+  /// The `elements` iterable itself may have any element type, so this
+  /// constructor can be used to down-cast a `Queue`, for example as:
+  /// ```dart
+  /// Queue<SuperType> superQueue = ...;
+  /// Queue<SubType> subQueue =
+  ///     new Queue<SubType>.from(superSet.whereType<SubType>());
+  /// ```
+  factory Queue.from(Iterable elements) = ListQueue<E>.from;
+
+  /// Creates a queue from [elements].
+  ///
+  /// The element order in the queue is as if the elements were added using
+  /// [addLast] in the order provided by [elements.iterator].
+  factory Queue.of(Iterable<E> elements) = ListQueue<E>.of;
+
+  /// Adapts [source] to be a `Queue<T>`.
+  ///
+  /// Any time the queue would produce an element that is not a [T],
+  /// the element access will throw.
+  ///
+  /// Any time a [T] value is attempted stored into the adapted queue,
+  /// the store will throw unless the value is also an instance of [S].
+  ///
+  /// If all accessed elements of [source] are actually instances of [T],
+  /// and if all elements stored into the returned queue are actually instance
+  /// of [S],
+  /// then the returned queue can be used as a `Queue<T>`.
+  static Queue<T> castFrom<S, T>(Queue<S> source) => CastQueue<S, T>(source);
+
+  /// Provides a view of this queue as a queue of [R] instances, if necessary.
+  ///
+  /// If this queue contains only instances of [R], all read operations
+  /// will work correctly. If any operation tries to access an element
+  /// that is not an instance of [R], the access will throw instead.
+  ///
+  /// Elements added to the queue (e.g., by using [addFirst] or [addAll])
+  /// must be instance of [R] to be valid arguments to the adding function,
+  /// and they must be instances of [E] as well to be accepted by
+  /// this queue as well.
+  Queue<R> cast<R>();
+
+  /// Removes and returns the first element of this queue.
+  ///
+  /// The queue must not be empty when this method is called.
+  E removeFirst();
+
+  /// Removes and returns the last element of the queue.
+  ///
+  /// The queue must not be empty when this method is called.
+  E removeLast();
+
+  /// Adds [value] at the beginning of the queue.
+  void addFirst(E value);
+
+  /// Adds [value] at the end of the queue.
+  void addLast(E value);
+
+  /// Adds [value] at the end of the queue.
+  void add(E value);
+
+  /// Remove a single instance of [value] from the queue.
+  ///
+  /// Returns `true` if a value was removed, or `false` if the queue
+  /// contained no element equal to [value].
+  bool remove(Object value);
+
+  /// Adds all elements of [iterable] at the end of the queue. The
+  /// length of the queue is extended by the length of [iterable].
+  void addAll(Iterable<E> iterable);
+
+  /// Removes all elements matched by [test] from the queue.
+  ///
+  /// The `test` function must not throw or modify the queue.
+  void removeWhere(bool test(E element));
+
+  /// Removes all elements not matched by [test] from the queue.
+  ///
+  /// The `test` function must not throw or modify the queue.
+  void retainWhere(bool test(E element));
+
+  /// Removes all elements in the queue. The size of the queue becomes zero.
+  void clear();
+}
+
+class _DoubleLink<Link extends _DoubleLink<Link>> {
+  Link _previousLink;
+  Link _nextLink;
+
+  void _link(Link previous, Link next) {
+    _nextLink = next;
+    _previousLink = previous;
+    if (previous != null) previous._nextLink = this;
+    if (next != null) next._previousLink = this;
+  }
+
+  void _unlink() {
+    if (_previousLink != null) _previousLink._nextLink = _nextLink;
+    if (_nextLink != null) _nextLink._previousLink = _previousLink;
+    _nextLink = null;
+    _previousLink = null;
+  }
+}
+
+/// An entry in a doubly linked list. It contains a pointer to the next
+/// entry, the previous entry, and the boxed element.
+class DoubleLinkedQueueEntry<E> extends _DoubleLink<DoubleLinkedQueueEntry<E>> {
+  /// The element in the queue.
+  E element;
+
+  DoubleLinkedQueueEntry(this.element);
+
+  /// Appends the given [e] as entry just after this entry.
+  void append(E e) {
+    DoubleLinkedQueueEntry<E>(e)._link(this, _nextLink);
+  }
+
+  /// Prepends the given [e] as entry just before this entry.
+  void prepend(E e) {
+    DoubleLinkedQueueEntry<E>(e)._link(_previousLink, this);
+  }
+
+  E remove() {
+    _unlink();
+    return element;
+  }
+
+  /// Returns the previous entry or `null` if there is none.
+  DoubleLinkedQueueEntry<E> previousEntry() => _previousLink;
+
+  /// Returns the next entry or `null` if there is none.
+  DoubleLinkedQueueEntry<E> nextEntry() => _nextLink;
+}
+
+/// Interface for the link classes used by [DoubleLinkedQueue].
+///
+/// Both the [_DoubleLinkedQueueElement] and [_DoubleLinkedQueueSentinel]
+/// implement this interface.
+/// The entry contains a link back to the queue, so calling `append`
+/// or `prepend` can correctly update the element count.
+abstract class _DoubleLinkedQueueEntry<E> extends DoubleLinkedQueueEntry<E> {
+  DoubleLinkedQueue<E> _queue;
+  _DoubleLinkedQueueEntry(E element, this._queue) : super(element);
+
+  DoubleLinkedQueueEntry<E> _asNonSentinelEntry();
+
+  void _append(E e) {
+    _DoubleLinkedQueueElement<E>(e, _queue)._link(this, _nextLink);
+  }
+
+  void _prepend(E e) {
+    _DoubleLinkedQueueElement<E>(e, _queue)._link(_previousLink, this);
+  }
+
+  E _remove();
+
+  E get _element => element;
+
+  DoubleLinkedQueueEntry<E> nextEntry() {
+    _DoubleLinkedQueueEntry<E> entry = _nextLink;
+    return entry._asNonSentinelEntry();
+  }
+
+  DoubleLinkedQueueEntry<E> previousEntry() {
+    _DoubleLinkedQueueEntry<E> entry = _previousLink;
+    return entry._asNonSentinelEntry();
+  }
+}
+
+/// The actual entry type used by the [DoubleLinkedQueue].
+///
+/// The entry contains a reference to the queue, allowing
+/// [append]/[prepend] to update the list length.
+class _DoubleLinkedQueueElement<E> extends _DoubleLinkedQueueEntry<E> {
+  _DoubleLinkedQueueElement(E element, DoubleLinkedQueue<E> queue)
+      : super(element, queue);
+
+  void append(E e) {
+    _append(e);
+    if (_queue != null) _queue._elementCount++;
+  }
+
+  void prepend(E e) {
+    _prepend(e);
+    if (_queue != null) _queue._elementCount++;
+  }
+
+  E _remove() {
+    _queue = null;
+    _unlink();
+    return element;
+  }
+
+  E remove() {
+    if (_queue != null) _queue._elementCount--;
+    return _remove();
+  }
+
+  _DoubleLinkedQueueElement<E> _asNonSentinelEntry() {
+    return this;
+  }
+}
+
+/// A sentinel in a double linked list is used to manipulate the list
+/// at both ends.
+/// A double linked list has exactly one sentinel,
+/// which is the only entry when the list is constructed.
+/// Initially, a sentinel has its next and previous entry point to itself.
+/// A sentinel does not box any user element.
+class _DoubleLinkedQueueSentinel<E> extends _DoubleLinkedQueueEntry<E> {
+  _DoubleLinkedQueueSentinel(DoubleLinkedQueue<E> queue) : super(null, queue) {
+    _previousLink = this;
+    _nextLink = this;
+  }
+
+  DoubleLinkedQueueEntry<E> _asNonSentinelEntry() {
+    return null;
+  }
+
+  /// Hit by, e.g., [DoubleLinkedQueue.removeFirst] if the queue is empty.
+  E _remove() {
+    throw IterableElementError.noElement();
+  }
+
+  /// Hit by, e.g., [DoubleLinkedQueue.first] if the queue is empty.
+  E get _element {
+    throw IterableElementError.noElement();
+  }
+}
+
+/// A [Queue] implementation based on a double-linked list.
+///
+/// Allows constant time add, remove-at-ends and peek operations.
+class DoubleLinkedQueue<E> extends Iterable<E> implements Queue<E> {
+  _DoubleLinkedQueueSentinel<E> _sentinel;
+  int _elementCount = 0;
+
+  DoubleLinkedQueue() {
+    _sentinel = _DoubleLinkedQueueSentinel<E>(this);
+  }
+
+  /// Creates a double-linked queue containing all [elements].
+  ///
+  /// The element order in the queue is as if the elements were added using
+  /// [addLast] in the order provided by [elements.iterator].
+  ///
+  /// All the [elements] should be instances of [E].
+  /// The `elements` iterable itself may have any element type, so this
+  /// constructor can be used to down-cast a `Queue`, for example as:
+  /// ```dart
+  /// Queue<SuperType> superQueue = ...;
+  /// Queue<SubType> subQueue =
+  ///     new DoubleLinkedQueue<SubType>.from(superQueue.whereType<SubType>());
+  /// ```
+  factory DoubleLinkedQueue.from(Iterable elements) {
+    Queue<E> list = DoubleLinkedQueue<E>();
+    for (final e in elements) {
+      list.addLast(e);
+    }
+    return list;
+  }
+
+  /// Creates a double-linked queue from [elements].
+  ///
+  /// The element order in the queue is as if the elements were added using
+  /// [addLast] in the order provided by [elements.iterator].
+  factory DoubleLinkedQueue.of(Iterable<E> elements) =>
+      DoubleLinkedQueue<E>()..addAll(elements);
+
+  Queue<R> cast<R>() => Queue.castFrom<E, R>(this);
+  int get length => _elementCount;
+
+  void addLast(E value) {
+    _sentinel._prepend(value);
+    _elementCount++;
+  }
+
+  void addFirst(E value) {
+    _sentinel._append(value);
+    _elementCount++;
+  }
+
+  void add(E value) {
+    _sentinel._prepend(value);
+    _elementCount++;
+  }
+
+  void addAll(Iterable<E> iterable) {
+    for (final E value in iterable) {
+      _sentinel._prepend(value);
+      _elementCount++;
+    }
+  }
+
+  E removeLast() {
+    _DoubleLinkedQueueEntry<E> lastEntry = _sentinel._previousLink;
+    E result = lastEntry._remove();
+    _elementCount--;
+    return result;
+  }
+
+  E removeFirst() {
+    _DoubleLinkedQueueEntry<E> firstEntry = _sentinel._nextLink;
+    E result = firstEntry._remove();
+    _elementCount--;
+    return result;
+  }
+
+  bool remove(Object o) {
+    _DoubleLinkedQueueEntry<E> entry = _sentinel._nextLink;
+    while (!identical(entry, _sentinel)) {
+      bool equals = (entry._element == o);
+      if (!identical(this, entry._queue)) {
+        // Entry must still be in the queue.
+        throw ConcurrentModificationError(this);
+      }
+      if (equals) {
+        entry._remove();
+        _elementCount--;
+        return true;
+      }
+      entry = entry._nextLink;
+    }
+    return false;
+  }
+
+  void _filter(bool test(E element), bool removeMatching) {
+    _DoubleLinkedQueueEntry<E> entry = _sentinel._nextLink;
+    while (!identical(entry, _sentinel)) {
+      bool matches = test(entry._element);
+      if (!identical(this, entry._queue)) {
+        // Entry must still be in the queue.
+        throw ConcurrentModificationError(this);
+      }
+      _DoubleLinkedQueueEntry<E> next = entry._nextLink; // Cannot be null.
+      if (identical(removeMatching, matches)) {
+        entry._remove();
+        _elementCount--;
+      }
+      entry = next;
+    }
+  }
+
+  void removeWhere(bool test(E element)) {
+    _filter(test, true);
+  }
+
+  void retainWhere(bool test(E element)) {
+    _filter(test, false);
+  }
+
+  E get first {
+    _DoubleLinkedQueueEntry<E> firstEntry = _sentinel._nextLink;
+    return firstEntry._element;
+  }
+
+  E get last {
+    _DoubleLinkedQueueEntry<E> lastEntry = _sentinel._previousLink;
+    return lastEntry._element;
+  }
+
+  E get single {
+    // Note that this throws correctly if the queue is empty
+    // because reading the element of the sentinel throws.
+    if (identical(_sentinel._nextLink, _sentinel._previousLink)) {
+      _DoubleLinkedQueueEntry<E> entry = _sentinel._nextLink;
+      return entry._element;
+    }
+    throw IterableElementError.tooMany();
+  }
+
+  /// The entry object of the first element in the queue.
+  ///
+  /// Each element of the queue has an associated [DoubleLinkedQueueEntry].
+  /// Returns the entry object corresponding to the first element of the queue.
+  ///
+  /// The entry objects can also be accessed using [lastEntry],
+  /// and they can be iterated using [DoubleLinkedQueueEntry.nextEntry()] and
+  /// [DoubleLinkedQueueEntry.previousEntry()].
+  DoubleLinkedQueueEntry<E> firstEntry() {
+    return _sentinel.nextEntry();
+  }
+
+  /// The entry object of the last element in the queue.
+  ///
+  /// Each element of the queue has an associated [DoubleLinkedQueueEntry].
+  /// Returns the entry object corresponding to the last element of the queue.
+  ///
+  /// The entry objects can also be accessed using [firstEntry],
+  /// and they can be iterated using [DoubleLinkedQueueEntry.nextEntry()] and
+  /// [DoubleLinkedQueueEntry.previousEntry()].
+  DoubleLinkedQueueEntry<E> lastEntry() {
+    return _sentinel.previousEntry();
+  }
+
+  bool get isEmpty {
+    return (identical(_sentinel._nextLink, _sentinel));
+  }
+
+  void clear() {
+    _sentinel._nextLink = _sentinel;
+    _sentinel._previousLink = _sentinel;
+    _elementCount = 0;
+  }
+
+  /// Calls [action] for each entry object of this double-linked queue.
+  ///
+  /// Each element of the queue has an associated [DoubleLinkedQueueEntry].
+  /// This method iterates the entry objects from first to last and calls
+  /// [action] with each object in turn.
+  ///
+  /// The entry objects can also be accessed using [firstEntry] and [lastEntry],
+  /// and iterated using [DoubleLinkedQueueEntry.nextEntry()] and
+  /// [DoubleLinkedQueueEntry.previousEntry()].
+  ///
+  /// The [action] function can use methods on [DoubleLinkedQueueEntry] to
+  /// remove the entry or it can insert elements before or after then entry.
+  /// If the current entry is removed, iteration continues with the entry that
+  /// was following the current entry when [action] was called. Any elements
+  /// inserted after the current element before it is removed will not be
+  /// visited by the iteration.
+  void forEachEntry(void action(DoubleLinkedQueueEntry<E> element)) {
+    _DoubleLinkedQueueEntry<E> entry = _sentinel._nextLink;
+    while (!identical(entry, _sentinel)) {
+      _DoubleLinkedQueueElement<E> element = entry;
+      _DoubleLinkedQueueEntry<E> next = element._nextLink;
+      // Remember both entry and entry._nextLink.
+      // If someone calls `element.remove()` we continue from `next`.
+      // Otherwise we use the value of entry._nextLink which may have been
+      // updated.
+      action(element);
+      if (identical(this, entry._queue)) {
+        next = entry._nextLink;
+      } else if (!identical(this, next._queue)) {
+        throw ConcurrentModificationError(this);
+      }
+      entry = next;
+    }
+  }
+
+  _DoubleLinkedQueueIterator<E> get iterator {
+    return _DoubleLinkedQueueIterator<E>(_sentinel);
+  }
+
+  String toString() => IterableBase.iterableToFullString(this, '{', '}');
+}
+
+class _DoubleLinkedQueueIterator<E> implements Iterator<E> {
+  _DoubleLinkedQueueSentinel<E> _sentinel;
+  _DoubleLinkedQueueEntry<E> _nextEntry;
+  E _current;
+
+  _DoubleLinkedQueueIterator(_DoubleLinkedQueueSentinel<E> sentinel)
+      : _sentinel = sentinel,
+        _nextEntry = sentinel._nextLink;
+
+  bool moveNext() {
+    if (identical(_nextEntry, _sentinel)) {
+      _current = null;
+      _nextEntry = null;
+      _sentinel = null;
+      return false;
+    }
+    _DoubleLinkedQueueElement<E> elementEntry = _nextEntry;
+    if (!identical(_sentinel._queue, elementEntry._queue)) {
+      throw ConcurrentModificationError(_sentinel._queue);
+    }
+    _current = elementEntry._element;
+    _nextEntry = elementEntry._nextLink;
+    return true;
+  }
+
+  E get current => _current;
+}
+
+/// List based [Queue].
+///
+/// Keeps a cyclic buffer of elements, and grows to a larger buffer when
+/// it fills up. This guarantees constant time peek and remove operations, and
+/// amortized constant time add operations.
+///
+/// The structure is efficient for any queue or stack usage.
+class ListQueue<E> extends ListIterable<E> implements Queue<E> {
+  static const int _INITIAL_CAPACITY = 8;
+  List<E> _table;
+  int _head;
+  int _tail;
+  int _modificationCount = 0;
+
+  /// Create an empty queue.
+  ///
+  /// If [initialCapacity] is given, prepare the queue for at least that many
+  /// elements.
+  ListQueue([int initialCapacity])
+      : _head = 0,
+        _tail = 0 {
+    if (initialCapacity == null || initialCapacity < _INITIAL_CAPACITY) {
+      initialCapacity = _INITIAL_CAPACITY;
+    } else if (!_isPowerOf2(initialCapacity)) {
+      initialCapacity = _nextPowerOf2(initialCapacity);
+    }
+    assert(_isPowerOf2(initialCapacity));
+    _table = List<E>(initialCapacity);
+  }
+
+  /// Create a `ListQueue` containing all [elements].
+  ///
+  /// The elements are added to the queue, as by [addLast], in the order given
+  /// by `elements.iterator`.
+  ///
+  /// All the [elements] should be instances of [E].
+  /// The `elements` iterable itself may have any element type, so this
+  /// constructor can be used to down-cast a `Queue`, for example as:
+  /// ```dart
+  /// Queue<SuperType> superQueue = ...;
+  /// Queue<SubType> subQueue =
+  ///     new ListQueue<SubType>.from(superQueue.whereType<SubType>());
+  /// ```
+  factory ListQueue.from(Iterable elements) {
+    if (elements is List) {
+      int length = elements.length;
+      ListQueue<E> queue = ListQueue<E>(length + 1);
+      assert(queue._table.length > length);
+      for (int i = 0; i < length; i++) {
+        queue._table[i] = elements[i];
+      }
+      queue._tail = length;
+      return queue;
+    } else {
+      int capacity = _INITIAL_CAPACITY;
+      if (elements is EfficientLengthIterable) {
+        capacity = elements.length;
+      }
+      ListQueue<E> result = ListQueue<E>(capacity);
+      for (final element in elements) {
+        result.addLast(element);
+      }
+      return result;
+    }
+  }
+
+  /// Create a `ListQueue` from [elements].
+  ///
+  /// The elements are added to the queue, as by [addLast], in the order given
+  /// by `elements.iterator`.
+  factory ListQueue.of(Iterable<E> elements) =>
+      ListQueue<E>()..addAll(elements);
+
+  // Iterable interface.
+
+  Queue<R> cast<R>() => Queue.castFrom<E, R>(this);
+  Iterator<E> get iterator => _ListQueueIterator<E>(this);
+
+  void forEach(void f(E element)) {
+    int modificationCount = _modificationCount;
+    for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) {
+      f(_table[i]);
+      _checkModification(modificationCount);
+    }
+  }
+
+  bool get isEmpty => _head == _tail;
+
+  int get length => (_tail - _head) & (_table.length - 1);
+
+  E get first {
+    if (_head == _tail) throw IterableElementError.noElement();
+    return _table[_head];
+  }
+
+  E get last {
+    if (_head == _tail) throw IterableElementError.noElement();
+    return _table[(_tail - 1) & (_table.length - 1)];
+  }
+
+  E get single {
+    if (_head == _tail) throw IterableElementError.noElement();
+    if (length > 1) throw IterableElementError.tooMany();
+    return _table[_head];
+  }
+
+  E elementAt(int index) {
+    RangeError.checkValidIndex(index, this);
+    return _table[(_head + index) & (_table.length - 1)];
+  }
+
+  List<E> toList({bool growable = true}) {
+    List<E> list;
+    if (growable) {
+      list = <E>[]..length = length;
+    } else {
+      list = List<E>(length);
+    }
+    _writeToList(list);
+    return list;
+  }
+
+  // Collection interface.
+
+  void add(E value) {
+    _add(value);
+  }
+
+  void addAll(Iterable<E> elements) {
+    if (elements is List<E>) {
+      List<E> list = elements;
+      int addCount = list.length;
+      int length = this.length;
+      if (length + addCount >= _table.length) {
+        _preGrow(length + addCount);
+        // After preGrow, all elements are at the start of the list.
+        _table.setRange(length, length + addCount, list, 0);
+        _tail += addCount;
+      } else {
+        // Adding addCount elements won't reach _head.
+        int endSpace = _table.length - _tail;
+        if (addCount < endSpace) {
+          _table.setRange(_tail, _tail + addCount, list, 0);
+          _tail += addCount;
+        } else {
+          int preSpace = addCount - endSpace;
+          _table.setRange(_tail, _tail + endSpace, list, 0);
+          _table.setRange(0, preSpace, list, endSpace);
+          _tail = preSpace;
+        }
+      }
+      _modificationCount++;
+    } else {
+      for (E element in elements) _add(element);
+    }
+  }
+
+  bool remove(Object value) {
+    for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) {
+      E element = _table[i];
+      if (element == value) {
+        _remove(i);
+        _modificationCount++;
+        return true;
+      }
+    }
+    return false;
+  }
+
+  void _filterWhere(bool test(E element), bool removeMatching) {
+    int modificationCount = _modificationCount;
+    int i = _head;
+    while (i != _tail) {
+      E element = _table[i];
+      bool remove = identical(removeMatching, test(element));
+      _checkModification(modificationCount);
+      if (remove) {
+        i = _remove(i);
+        modificationCount = ++_modificationCount;
+      } else {
+        i = (i + 1) & (_table.length - 1);
+      }
+    }
+  }
+
+  /// Remove all elements matched by [test].
+  ///
+  /// This method is inefficient since it works by repeatedly removing single
+  /// elements, each of which can take linear time.
+  void removeWhere(bool test(E element)) {
+    _filterWhere(test, true);
+  }
+
+  /// Remove all elements not matched by [test].
+  ///
+  /// This method is inefficient since it works by repeatedly removing single
+  /// elements, each of which can take linear time.
+  void retainWhere(bool test(E element)) {
+    _filterWhere(test, false);
+  }
+
+  void clear() {
+    if (_head != _tail) {
+      for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) {
+        _table[i] = null;
+      }
+      _head = _tail = 0;
+      _modificationCount++;
+    }
+  }
+
+  String toString() => IterableBase.iterableToFullString(this, "{", "}");
+
+  // Queue interface.
+
+  void addLast(E value) {
+    _add(value);
+  }
+
+  void addFirst(E value) {
+    _head = (_head - 1) & (_table.length - 1);
+    _table[_head] = value;
+    if (_head == _tail) _grow();
+    _modificationCount++;
+  }
+
+  E removeFirst() {
+    if (_head == _tail) throw IterableElementError.noElement();
+    _modificationCount++;
+    E result = _table[_head];
+    _table[_head] = null;
+    _head = (_head + 1) & (_table.length - 1);
+    return result;
+  }
+
+  E removeLast() {
+    if (_head == _tail) throw IterableElementError.noElement();
+    _modificationCount++;
+    _tail = (_tail - 1) & (_table.length - 1);
+    E result = _table[_tail];
+    _table[_tail] = null;
+    return result;
+  }
+
+  // Internal helper functions.
+
+  /// Whether [number] is a power of two.
+  ///
+  /// Only works for positive numbers.
+  static bool _isPowerOf2(int number) => (number & (number - 1)) == 0;
+
+  /// Rounds [number] up to the nearest power of 2.
+  ///
+  /// If [number] is a power of 2 already, it is returned.
+  ///
+  /// Only works for positive numbers.
+  static int _nextPowerOf2(int number) {
+    assert(number > 0);
+    number = (number << 1) - 1;
+    for (;;) {
+      int nextNumber = number & (number - 1);
+      if (nextNumber == 0) return number;
+      number = nextNumber;
+    }
+  }
+
+  /// Check if the queue has been modified during iteration.
+  void _checkModification(int expectedModificationCount) {
+    if (expectedModificationCount != _modificationCount) {
+      throw ConcurrentModificationError(this);
+    }
+  }
+
+  /// Adds element at end of queue. Used by both [add] and [addAll].
+  void _add(E element) {
+    _table[_tail] = element;
+    _tail = (_tail + 1) & (_table.length - 1);
+    if (_head == _tail) _grow();
+    _modificationCount++;
+  }
+
+  /// Removes the element at [offset] into [_table].
+  ///
+  /// Removal is performed by linearly moving elements either before or after
+  /// [offset] by one position.
+  ///
+  /// Returns the new offset of the following element. This may be the same
+  /// offset or the following offset depending on how elements are moved
+  /// to fill the hole.
+  int _remove(int offset) {
+    int mask = _table.length - 1;
+    int startDistance = (offset - _head) & mask;
+    int endDistance = (_tail - offset) & mask;
+    if (startDistance < endDistance) {
+      // Closest to start.
+      int i = offset;
+      while (i != _head) {
+        int prevOffset = (i - 1) & mask;
+        _table[i] = _table[prevOffset];
+        i = prevOffset;
+      }
+      _table[_head] = null;
+      _head = (_head + 1) & mask;
+      return (offset + 1) & mask;
+    } else {
+      _tail = (_tail - 1) & mask;
+      int i = offset;
+      while (i != _tail) {
+        int nextOffset = (i + 1) & mask;
+        _table[i] = _table[nextOffset];
+        i = nextOffset;
+      }
+      _table[_tail] = null;
+      return offset;
+    }
+  }
+
+  /// Grow the table when full.
+  void _grow() {
+    List<E> newTable = List<E>(_table.length * 2);
+    int split = _table.length - _head;
+    newTable.setRange(0, split, _table, _head);
+    newTable.setRange(split, split + _head, _table, 0);
+    _head = 0;
+    _tail = _table.length;
+    _table = newTable;
+  }
+
+  int _writeToList(List<E> target) {
+    assert(target.length >= length);
+    if (_head <= _tail) {
+      int length = _tail - _head;
+      target.setRange(0, length, _table, _head);
+      return length;
+    } else {
+      int firstPartSize = _table.length - _head;
+      target.setRange(0, firstPartSize, _table, _head);
+      target.setRange(firstPartSize, firstPartSize + _tail, _table, 0);
+      return _tail + firstPartSize;
+    }
+  }
+
+  /// Grows the table even if it is not full.
+  void _preGrow(int newElementCount) {
+    assert(newElementCount >= length);
+
+    // Add some extra room to ensure that there's room for more elements after
+    // expansion.
+    newElementCount += newElementCount >> 1;
+    int newCapacity = _nextPowerOf2(newElementCount);
+    List<E> newTable = List<E>(newCapacity);
+    _tail = _writeToList(newTable);
+    _table = newTable;
+    _head = 0;
+  }
+}
+
+/// Iterator for a [ListQueue].
+///
+/// Considers any add or remove operation a concurrent modification.
+class _ListQueueIterator<E> implements Iterator<E> {
+  final ListQueue<E> _queue;
+  final int _end;
+  final int _modificationCount;
+  int _position;
+  E _current;
+
+  _ListQueueIterator(ListQueue<E> queue)
+      : _queue = queue,
+        _end = queue._tail,
+        _modificationCount = queue._modificationCount,
+        _position = queue._head;
+
+  E get current => _current;
+
+  bool moveNext() {
+    _queue._checkModification(_modificationCount);
+    if (_position == _end) {
+      _current = null;
+      return false;
+    }
+    _current = _queue._table[_position];
+    _position = (_position + 1) & (_queue._table.length - 1);
+    return true;
+  }
+}
diff --git a/sdk_nnbd/lib/collection/set.dart b/sdk_nnbd/lib/collection/set.dart
new file mode 100644
index 0000000..7508b23
--- /dev/null
+++ b/sdk_nnbd/lib/collection/set.dart
@@ -0,0 +1,630 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Base implementations of [Set].
+part of dart.collection;
+
+/// Mixin implementation of [Set].
+///
+/// This class provides a base implementation of a `Set` that depends only
+/// on the abstract members: [add], [contains], [lookup], [remove],
+/// [iterator], [length] and [toSet].
+///
+/// Some of the methods assume that `toSet` creates a modifiable set.
+/// If using this mixin for an unmodifiable set,
+/// where `toSet` should return an unmodifiable set,
+/// it's necessary to reimplement
+/// [retainAll], [union], [intersection] and [difference].
+///
+/// Implementations of `Set` using this mixin should consider also implementing
+/// `clear` in constant time. The default implementation works by removing every
+/// element.
+abstract class SetMixin<E> implements Set<E> {
+  // This class reimplements all of [IterableMixin].
+  // If/when Dart mixins get more powerful, we should just create a single
+  // Mixin class from IterableMixin and the new methods of this class.
+
+  bool add(E value);
+
+  bool contains(Object element);
+
+  E lookup(Object element);
+
+  bool remove(Object value);
+
+  Iterator<E> get iterator;
+
+  Set<E> toSet();
+
+  int get length;
+
+  bool get isEmpty => length == 0;
+
+  bool get isNotEmpty => length != 0;
+
+  Set<R> cast<R>() => Set.castFrom<E, R>(this);
+  Iterable<E> followedBy(Iterable<E> other) =>
+      FollowedByIterable<E>.firstEfficient(this, other);
+
+  Iterable<T> whereType<T>() => WhereTypeIterable<T>(this);
+
+  void clear() {
+    removeAll(toList());
+  }
+
+  void addAll(Iterable<E> elements) {
+    for (E element in elements) add(element);
+  }
+
+  void removeAll(Iterable<Object> elements) {
+    for (Object element in elements) remove(element);
+  }
+
+  void retainAll(Iterable<Object> elements) {
+    // Create a copy of the set, remove all of elements from the copy,
+    // then remove all remaining elements in copy from this.
+    Set<E> toRemove = toSet();
+    for (Object o in elements) {
+      toRemove.remove(o);
+    }
+    removeAll(toRemove);
+  }
+
+  void removeWhere(bool test(E element)) {
+    List toRemove = [];
+    for (E element in this) {
+      if (test(element)) toRemove.add(element);
+    }
+    removeAll(toRemove);
+  }
+
+  void retainWhere(bool test(E element)) {
+    List toRemove = [];
+    for (E element in this) {
+      if (!test(element)) toRemove.add(element);
+    }
+    removeAll(toRemove);
+  }
+
+  bool containsAll(Iterable<Object> other) {
+    for (Object o in other) {
+      if (!contains(o)) return false;
+    }
+    return true;
+  }
+
+  Set<E> union(Set<E> other) {
+    return toSet()..addAll(other);
+  }
+
+  Set<E> intersection(Set<Object> other) {
+    Set<E> result = toSet();
+    for (E element in this) {
+      if (!other.contains(element)) result.remove(element);
+    }
+    return result;
+  }
+
+  Set<E> difference(Set<Object> other) {
+    Set<E> result = toSet();
+    for (E element in this) {
+      if (other.contains(element)) result.remove(element);
+    }
+    return result;
+  }
+
+  List<E> toList({bool growable = true}) {
+    List<E> result = growable ? (<E>[]..length = length) : List<E>(length);
+    int i = 0;
+    for (E element in this) result[i++] = element;
+    return result;
+  }
+
+  Iterable<T> map<T>(T f(E element)) =>
+      EfficientLengthMappedIterable<E, T>(this, f);
+
+  E get single {
+    if (length > 1) throw IterableElementError.tooMany();
+    Iterator<E> it = iterator;
+    if (!it.moveNext()) throw IterableElementError.noElement();
+    E result = it.current;
+    return result;
+  }
+
+  String toString() => IterableBase.iterableToFullString(this, '{', '}');
+
+  // Copied from IterableMixin.
+  // Should be inherited if we had multi-level mixins.
+
+  Iterable<E> where(bool f(E element)) => WhereIterable<E>(this, f);
+
+  Iterable<T> expand<T>(Iterable<T> f(E element)) =>
+      ExpandIterable<E, T>(this, f);
+
+  void forEach(void f(E element)) {
+    for (E element in this) f(element);
+  }
+
+  E reduce(E combine(E value, E element)) {
+    Iterator<E> iterator = this.iterator;
+    if (!iterator.moveNext()) {
+      throw IterableElementError.noElement();
+    }
+    E value = iterator.current;
+    while (iterator.moveNext()) {
+      value = combine(value, iterator.current);
+    }
+    return value;
+  }
+
+  T fold<T>(T initialValue, T combine(T previousValue, E element)) {
+    var value = initialValue;
+    for (E element in this) value = combine(value, element);
+    return value;
+  }
+
+  bool every(bool f(E element)) {
+    for (E element in this) {
+      if (!f(element)) return false;
+    }
+    return true;
+  }
+
+  String join([String separator = ""]) {
+    Iterator<E> iterator = this.iterator;
+    if (!iterator.moveNext()) return "";
+    StringBuffer buffer = StringBuffer();
+    if (separator == null || separator == "") {
+      do {
+        buffer.write(iterator.current);
+      } while (iterator.moveNext());
+    } else {
+      buffer.write(iterator.current);
+      while (iterator.moveNext()) {
+        buffer.write(separator);
+        buffer.write(iterator.current);
+      }
+    }
+    return buffer.toString();
+  }
+
+  bool any(bool test(E element)) {
+    for (E element in this) {
+      if (test(element)) return true;
+    }
+    return false;
+  }
+
+  Iterable<E> take(int n) {
+    return TakeIterable<E>(this, n);
+  }
+
+  Iterable<E> takeWhile(bool test(E value)) {
+    return TakeWhileIterable<E>(this, test);
+  }
+
+  Iterable<E> skip(int n) {
+    return SkipIterable<E>(this, n);
+  }
+
+  Iterable<E> skipWhile(bool test(E value)) {
+    return SkipWhileIterable<E>(this, test);
+  }
+
+  E get first {
+    Iterator<E> it = iterator;
+    if (!it.moveNext()) {
+      throw IterableElementError.noElement();
+    }
+    return it.current;
+  }
+
+  E get last {
+    Iterator<E> it = iterator;
+    if (!it.moveNext()) {
+      throw IterableElementError.noElement();
+    }
+    E result;
+    do {
+      result = it.current;
+    } while (it.moveNext());
+    return result;
+  }
+
+  E firstWhere(bool test(E value), {E orElse()}) {
+    for (E element in this) {
+      if (test(element)) return element;
+    }
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E lastWhere(bool test(E value), {E orElse()}) {
+    E result;
+    bool foundMatching = false;
+    for (E element in this) {
+      if (test(element)) {
+        result = element;
+        foundMatching = true;
+      }
+    }
+    if (foundMatching) return result;
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E singleWhere(bool test(E value), {E orElse()}) {
+    E result;
+    bool foundMatching = false;
+    for (E element in this) {
+      if (test(element)) {
+        if (foundMatching) {
+          throw IterableElementError.tooMany();
+        }
+        result = element;
+        foundMatching = true;
+      }
+    }
+    if (foundMatching) return result;
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E elementAt(int index) {
+    ArgumentError.checkNotNull(index, "index");
+    RangeError.checkNotNegative(index, "index");
+    int elementIndex = 0;
+    for (E element in this) {
+      if (index == elementIndex) return element;
+      elementIndex++;
+    }
+    throw RangeError.index(index, this, "index", null, elementIndex);
+  }
+}
+
+/// Base implementation of [Set].
+///
+/// This class provides a base implementation of a `Set` that depends only
+/// on the abstract members: [add], [contains], [lookup], [remove],
+/// [iterator], [length] and [toSet].
+///
+/// Some of the methods assume that `toSet` creates a modifiable set.
+/// If using this base class for an unmodifiable set,
+/// where `toSet` should return an unmodifiable set,
+/// it's necessary to reimplement
+/// [retainAll], [union], [intersection] and [difference].
+///
+/// Implementations of `Set` using this base should consider also implementing
+/// `clear` in constant time. The default implementation works by removing every
+/// element.
+abstract class SetBase<E> extends Object with SetMixin<E> {
+  /// Convert a `Set` to a string as `{each, element, as, string}`.
+  ///
+  /// Handles circular references where converting one of the elements
+  /// to a string ends up converting [set] to a string again.
+  static String setToString(Set set) =>
+      IterableBase.iterableToFullString(set, '{', '}');
+}
+
+/// Common internal implementation of some [Set] methods.
+// TODO(35548): Make this mix-in SetMixin, by adding `with SetMixin<E>`
+// and removing the copied members below,
+// when analyzer supports const constructors for mixin applications.
+abstract class _SetBase<E> implements Set<E> {
+  // The following two methods override the ones in SetBase.
+  // It's possible to be more efficient if we have a way to create an empty
+  // set of the correct type.
+  const _SetBase();
+
+  Set<E> _newSet();
+
+  Set<R> _newSimilarSet<R>();
+
+  Set<R> cast<R>() => Set.castFrom<E, R>(this, newSet: _newSimilarSet);
+
+  Set<E> difference(Set<Object> other) {
+    Set<E> result = _newSet();
+    for (var element in this) {
+      if (!other.contains(element)) result.add(element);
+    }
+    return result;
+  }
+
+  Set<E> intersection(Set<Object> other) {
+    Set<E> result = _newSet();
+    for (var element in this) {
+      if (other.contains(element)) result.add(element);
+    }
+    return result;
+  }
+
+  // Subclasses can optimize this further.
+  Set<E> toSet() => _newSet()..addAll(this);
+
+  /// TODO(35548): Remove the following declarations again when the analyzer
+  /// supports mixins with const constructors, and mix in `SetMixin` instead.
+
+  bool get isEmpty => length == 0;
+
+  bool get isNotEmpty => length != 0;
+
+  Iterable<E> followedBy(Iterable<E> other) =>
+      FollowedByIterable<E>.firstEfficient(this, other);
+
+  Iterable<T> whereType<T>() => WhereTypeIterable<T>(this);
+
+  void clear() {
+    removeAll(toList());
+  }
+
+  void addAll(Iterable<E> elements) {
+    for (E element in elements) add(element);
+  }
+
+  void removeAll(Iterable<Object> elements) {
+    for (Object element in elements) remove(element);
+  }
+
+  void retainAll(Iterable<Object> elements) {
+    // Create a copy of the set, remove all of elements from the copy,
+    // then remove all remaining elements in copy from this.
+    Set<E> toRemove = toSet();
+    for (Object o in elements) {
+      toRemove.remove(o);
+    }
+    removeAll(toRemove);
+  }
+
+  void removeWhere(bool test(E element)) {
+    List toRemove = [];
+    for (E element in this) {
+      if (test(element)) toRemove.add(element);
+    }
+    removeAll(toRemove);
+  }
+
+  void retainWhere(bool test(E element)) {
+    List toRemove = [];
+    for (E element in this) {
+      if (!test(element)) toRemove.add(element);
+    }
+    removeAll(toRemove);
+  }
+
+  bool containsAll(Iterable<Object> other) {
+    for (Object o in other) {
+      if (!contains(o)) return false;
+    }
+    return true;
+  }
+
+  Set<E> union(Set<E> other) {
+    return toSet()..addAll(other);
+  }
+
+  List<E> toList({bool growable = true}) {
+    List<E> result = growable ? (<E>[]..length = length) : List<E>(length);
+    int i = 0;
+    for (E element in this) result[i++] = element;
+    return result;
+  }
+
+  Iterable<T> map<T>(T f(E element)) =>
+      EfficientLengthMappedIterable<E, T>(this, f);
+
+  E get single {
+    if (length > 1) throw IterableElementError.tooMany();
+    Iterator<E> it = iterator;
+    if (!it.moveNext()) throw IterableElementError.noElement();
+    E result = it.current;
+    return result;
+  }
+
+  String toString() => IterableBase.iterableToFullString(this, '{', '}');
+
+  Iterable<E> where(bool f(E element)) => WhereIterable<E>(this, f);
+
+  Iterable<T> expand<T>(Iterable<T> f(E element)) =>
+      ExpandIterable<E, T>(this, f);
+
+  void forEach(void f(E element)) {
+    for (E element in this) f(element);
+  }
+
+  E reduce(E combine(E value, E element)) {
+    Iterator<E> iterator = this.iterator;
+    if (!iterator.moveNext()) {
+      throw IterableElementError.noElement();
+    }
+    E value = iterator.current;
+    while (iterator.moveNext()) {
+      value = combine(value, iterator.current);
+    }
+    return value;
+  }
+
+  T fold<T>(T initialValue, T combine(T previousValue, E element)) {
+    var value = initialValue;
+    for (E element in this) value = combine(value, element);
+    return value;
+  }
+
+  bool every(bool f(E element)) {
+    for (E element in this) {
+      if (!f(element)) return false;
+    }
+    return true;
+  }
+
+  String join([String separator = ""]) {
+    Iterator<E> iterator = this.iterator;
+    if (!iterator.moveNext()) return "";
+    StringBuffer buffer = StringBuffer();
+    if (separator == null || separator == "") {
+      do {
+        buffer.write(iterator.current);
+      } while (iterator.moveNext());
+    } else {
+      buffer.write(iterator.current);
+      while (iterator.moveNext()) {
+        buffer.write(separator);
+        buffer.write(iterator.current);
+      }
+    }
+    return buffer.toString();
+  }
+
+  bool any(bool test(E element)) {
+    for (E element in this) {
+      if (test(element)) return true;
+    }
+    return false;
+  }
+
+  Iterable<E> take(int n) {
+    return TakeIterable<E>(this, n);
+  }
+
+  Iterable<E> takeWhile(bool test(E value)) {
+    return TakeWhileIterable<E>(this, test);
+  }
+
+  Iterable<E> skip(int n) {
+    return SkipIterable<E>(this, n);
+  }
+
+  Iterable<E> skipWhile(bool test(E value)) {
+    return SkipWhileIterable<E>(this, test);
+  }
+
+  E get first {
+    Iterator<E> it = iterator;
+    if (!it.moveNext()) {
+      throw IterableElementError.noElement();
+    }
+    return it.current;
+  }
+
+  E get last {
+    Iterator<E> it = iterator;
+    if (!it.moveNext()) {
+      throw IterableElementError.noElement();
+    }
+    E result;
+    do {
+      result = it.current;
+    } while (it.moveNext());
+    return result;
+  }
+
+  E firstWhere(bool test(E value), {E orElse()}) {
+    for (E element in this) {
+      if (test(element)) return element;
+    }
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E lastWhere(bool test(E value), {E orElse()}) {
+    E result;
+    bool foundMatching = false;
+    for (E element in this) {
+      if (test(element)) {
+        result = element;
+        foundMatching = true;
+      }
+    }
+    if (foundMatching) return result;
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E singleWhere(bool test(E value), {E orElse()}) {
+    E result;
+    bool foundMatching = false;
+    for (E element in this) {
+      if (test(element)) {
+        if (foundMatching) {
+          throw IterableElementError.tooMany();
+        }
+        result = element;
+        foundMatching = true;
+      }
+    }
+    if (foundMatching) return result;
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E elementAt(int index) {
+    ArgumentError.checkNotNull(index, "index");
+    RangeError.checkNotNegative(index, "index");
+    int elementIndex = 0;
+    for (E element in this) {
+      if (index == elementIndex) return element;
+      elementIndex++;
+    }
+    throw RangeError.index(index, this, "index", null, elementIndex);
+  }
+}
+
+/// Class used to implement const sets.
+class _UnmodifiableSet<E> extends _SetBase<E> {
+  final Map<E, Null> _map;
+
+  const _UnmodifiableSet(this._map);
+
+  Set<E> _newSet() => LinkedHashSet<E>();
+
+  Set<R> _newSimilarSet<R>() => LinkedHashSet<R>();
+
+  // Lookups use map methods.
+
+  bool contains(Object element) => _map.containsKey(element);
+
+  Iterator<E> get iterator => _map.keys.iterator;
+
+  int get length => _map.length;
+
+  E lookup(Object element) {
+    for (var key in _map.keys) {
+      if (key == element) return key;
+    }
+    return null;
+  }
+
+  // Mutating methods throw.
+
+  bool add(E value) {
+    throw UnsupportedError("Cannot change unmodifiable set");
+  }
+
+  void clear() {
+    throw UnsupportedError("Cannot change unmodifiable set");
+  }
+
+  void addAll(Iterable<E> elements) {
+    throw UnsupportedError("Cannot change unmodifiable set");
+  }
+
+  void removeAll(Iterable<Object> elements) {
+    throw UnsupportedError("Cannot change unmodifiable set");
+  }
+
+  void retainAll(Iterable<Object> elements) {
+    throw UnsupportedError("Cannot change unmodifiable set");
+  }
+
+  void removeWhere(bool test(E element)) {
+    throw UnsupportedError("Cannot change unmodifiable set");
+  }
+
+  void retainWhere(bool test(E element)) {
+    throw UnsupportedError("Cannot change unmodifiable set");
+  }
+
+  bool remove(Object value) {
+    throw UnsupportedError("Cannot change unmodifiable set");
+  }
+}
diff --git a/sdk_nnbd/lib/collection/splay_tree.dart b/sdk_nnbd/lib/collection/splay_tree.dart
new file mode 100644
index 0000000..5f71934
--- /dev/null
+++ b/sdk_nnbd/lib/collection/splay_tree.dart
@@ -0,0 +1,831 @@
+// Copyright (c) 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 dart.collection;
+
+typedef _Predicate<T> = bool Function(T value);
+
+/// A node in a splay tree. It holds the sorting key and the left
+/// and right children in the tree.
+class _SplayTreeNode<K> {
+  final K key;
+  _SplayTreeNode<K> left;
+  _SplayTreeNode<K> right;
+
+  _SplayTreeNode(this.key);
+}
+
+/// A node in a splay tree based map.
+///
+/// A [_SplayTreeNode] that also contains a value
+class _SplayTreeMapNode<K, V> extends _SplayTreeNode<K> {
+  V value;
+  _SplayTreeMapNode(K key, this.value) : super(key);
+}
+
+/// A splay tree is a self-balancing binary search tree.
+///
+/// It has the additional property that recently accessed elements
+/// are quick to access again.
+/// It performs basic operations such as insertion, look-up and
+/// removal, in O(log(n)) amortized time.
+abstract class _SplayTree<K, Node extends _SplayTreeNode<K>> {
+  // The root node of the splay tree. It will contain either the last
+  // element inserted or the last element looked up.
+  Node get _root;
+  set _root(Node newValue);
+
+  // The dummy node used when performing a splay on the tree. Reusing it
+  // avoids allocating a node each time a splay is performed.
+  Node get _dummy;
+
+  // Number of elements in the splay tree.
+  int _count = 0;
+
+  /// Counter incremented whenever the keys in the map changes.
+  ///
+  /// Used to detect concurrent modifications.
+  int _modificationCount = 0;
+
+  /// Counter incremented whenever the tree structure changes.
+  ///
+  /// Used to detect that an in-place traversal cannot use
+  /// cached information that relies on the tree structure.
+  int _splayCount = 0;
+
+  /// The comparator that is used for this splay tree.
+  Comparator<K> get _comparator;
+
+  /// The predicate to determine that a given object is a valid key.
+  _Predicate get _validKey;
+
+  /// Comparison used to compare keys.
+  int _compare(K key1, K key2);
+
+  /// Perform the splay operation for the given key. Moves the node with
+  /// the given key to the top of the tree.  If no node has the given
+  /// key, the last node on the search path is moved to the top of the
+  /// tree. This is the simplified top-down splaying algorithm from:
+  /// "Self-adjusting Binary Search Trees" by Sleator and Tarjan.
+  ///
+  /// Returns the result of comparing the new root of the tree to [key].
+  /// Returns -1 if the table is empty.
+  int _splay(K key) {
+    if (_root == null) return -1;
+
+    // The right child of the dummy node will hold
+    // the L tree of the algorithm.  The left child of the dummy node
+    // will hold the R tree of the algorithm.  Using a dummy node, left
+    // and right will always be nodes and we avoid special cases.
+    Node left = _dummy;
+    Node right = _dummy;
+    Node current = _root;
+    int comp;
+    while (true) {
+      comp = _compare(current.key, key);
+      if (comp > 0) {
+        if (current.left == null) break;
+        comp = _compare(current.left.key, key);
+        if (comp > 0) {
+          // Rotate right.
+          _SplayTreeNode<K> tmp = current.left;
+          current.left = tmp.right;
+          tmp.right = current;
+          current = tmp;
+          if (current.left == null) break;
+        }
+        // Link right.
+        right.left = current;
+        right = current;
+        current = current.left;
+      } else if (comp < 0) {
+        if (current.right == null) break;
+        comp = _compare(current.right.key, key);
+        if (comp < 0) {
+          // Rotate left.
+          Node tmp = current.right;
+          current.right = tmp.left;
+          tmp.left = current;
+          current = tmp;
+          if (current.right == null) break;
+        }
+        // Link left.
+        left.right = current;
+        left = current;
+        current = current.right;
+      } else {
+        break;
+      }
+    }
+    // Assemble.
+    left.right = current.left;
+    right.left = current.right;
+    current.left = _dummy.right;
+    current.right = _dummy.left;
+    _root = current;
+
+    _dummy.right = null;
+    _dummy.left = null;
+    _splayCount++;
+    return comp;
+  }
+
+  // Emulates splaying with a key that is smaller than any in the subtree
+  // anchored at [node].
+  // and that node is returned. It should replace the reference to [node]
+  // in any parent tree or root pointer.
+  external Node _splayMin(Node node);
+
+  // Emulates splaying with a key that is greater than any in the subtree
+  // anchored at [node].
+  // After this, the largest element in the tree is the root of the subtree,
+  // and that node is returned. It should replace the reference to [node]
+  // in any parent tree or root pointer.
+  external Node _splayMax(Node node);
+
+  Node _remove(K key) {
+    if (_root == null) return null;
+    int comp = _splay(key);
+    if (comp != 0) return null;
+    Node result = _root;
+    _count--;
+    // assert(_count >= 0);
+    if (_root.left == null) {
+      _root = _root.right;
+    } else {
+      Node right = _root.right;
+      // Splay to make sure that the new root has an empty right child.
+      _root = _splayMax(_root.left);
+      // Insert the original right child as the right child of the new
+      // root.
+      _root.right = right;
+    }
+    _modificationCount++;
+    return result;
+  }
+
+  /// Adds a new root node with the given [key] or [value].
+  ///
+  /// The [comp] value is the result of comparing the existing root's key
+  /// with key.
+  void _addNewRoot(Node node, int comp) {
+    _count++;
+    _modificationCount++;
+    if (_root == null) {
+      _root = node;
+      return;
+    }
+    // assert(_count >= 0);
+    if (comp < 0) {
+      node.left = _root;
+      node.right = _root.right;
+      _root.right = null;
+    } else {
+      node.right = _root;
+      node.left = _root.left;
+      _root.left = null;
+    }
+    _root = node;
+  }
+
+  Node get _first {
+    if (_root == null) return null;
+    _root = _splayMin(_root);
+    return _root;
+  }
+
+  Node get _last {
+    if (_root == null) return null;
+    _root = _splayMax(_root);
+    return _root;
+  }
+
+  void _clear() {
+    _root = null;
+    _count = 0;
+    _modificationCount++;
+  }
+}
+
+class _TypeTest<T> {
+  bool test(v) => v is T;
+}
+
+int _dynamicCompare(dynamic a, dynamic b) => Comparable.compare(a, b);
+
+Comparator<K> _defaultCompare<K>() {
+  // If K <: Comparable, then we can just use Comparable.compare
+  // with no casts.
+  Object compare = Comparable.compare;
+  if (compare is Comparator<K>) {
+    return compare;
+  }
+  // Otherwise wrap and cast the arguments on each call.
+  return _dynamicCompare;
+}
+
+/// A [Map] of objects that can be ordered relative to each other.
+///
+/// The map is based on a self-balancing binary tree. It allows most operations
+/// in amortized logarithmic time.
+///
+/// Keys of the map are compared using the `compare` function passed in
+/// the constructor, both for ordering and for equality.
+/// If the map contains only the key `a`, then `map.containsKey(b)`
+/// will return `true` if and only if `compare(a, b) == 0`,
+/// and the value of `a == b` is not even checked.
+/// If the compare function is omitted, the objects are assumed to be
+/// [Comparable], and are compared using their [Comparable.compareTo] method.
+/// Non-comparable objects (including `null`) will not work as keys
+/// in that case.
+///
+/// To allow calling [operator []], [remove] or [containsKey] with objects
+/// that are not supported by the `compare` function, an extra `isValidKey`
+/// predicate function can be supplied. This function is tested before
+/// using the `compare` function on an argument value that may not be a [K]
+/// value. If omitted, the `isValidKey` function defaults to testing if the
+/// value is a [K].
+class SplayTreeMap<K, V> extends _SplayTree<K, _SplayTreeMapNode<K, V>>
+    with MapMixin<K, V> {
+  _SplayTreeMapNode<K, V> _root;
+  final _SplayTreeMapNode<K, V> _dummy = _SplayTreeMapNode<K, V>(null, null);
+
+  Comparator<K> _comparator;
+  _Predicate _validKey;
+
+  SplayTreeMap([int compare(K key1, K key2), bool isValidKey(potentialKey)])
+      : _comparator = compare ?? _defaultCompare<K>(),
+        _validKey = isValidKey ?? ((v) => v is K);
+
+  /// Creates a [SplayTreeMap] that contains all key/value pairs of [other].
+  ///
+  /// The keys must all be instances of [K] and the values of [V].
+  /// The [other] map itself can have any type.
+  factory SplayTreeMap.from(Map other,
+      [int compare(K key1, K key2), bool isValidKey(potentialKey)]) {
+    SplayTreeMap<K, V> result = SplayTreeMap<K, V>(compare, isValidKey);
+    other.forEach((k, v) {
+      result[k] = v;
+    });
+    return result;
+  }
+
+  /// Creates a [SplayTreeMap] that contains all key/value pairs of [other].
+  factory SplayTreeMap.of(Map<K, V> other,
+          [int compare(K key1, K key2), bool isValidKey(potentialKey)]) =>
+      SplayTreeMap<K, V>(compare, isValidKey)..addAll(other);
+
+  /// Creates a [SplayTreeMap] where the keys and values are computed from the
+  /// [iterable].
+  ///
+  /// For each element of the [iterable] this constructor computes a key/value
+  /// pair, by applying [key] and [value] respectively.
+  ///
+  /// The keys of the key/value pairs do not need to be unique. The last
+  /// occurrence of a key will simply overwrite any previous value.
+  ///
+  /// If no functions are specified for [key] and [value] the default is to
+  /// use the iterable value itself.
+  factory SplayTreeMap.fromIterable(Iterable iterable,
+      {K key(element),
+      V value(element),
+      int compare(K key1, K key2),
+      bool isValidKey(potentialKey)}) {
+    SplayTreeMap<K, V> map = SplayTreeMap<K, V>(compare, isValidKey);
+    MapBase._fillMapWithMappedIterable(map, iterable, key, value);
+    return map;
+  }
+
+  /// Creates a [SplayTreeMap] associating the given [keys] to [values].
+  ///
+  /// This constructor iterates over [keys] and [values] and maps each element
+  /// of [keys] to the corresponding element of [values].
+  ///
+  /// If [keys] contains the same object multiple times, the last occurrence
+  /// overwrites the previous value.
+  ///
+  /// It is an error if the two [Iterable]s don't have the same length.
+  factory SplayTreeMap.fromIterables(Iterable<K> keys, Iterable<V> values,
+      [int compare(K key1, K key2), bool isValidKey(potentialKey)]) {
+    SplayTreeMap<K, V> map = SplayTreeMap<K, V>(compare, isValidKey);
+    MapBase._fillMapWithIterables(map, keys, values);
+    return map;
+  }
+
+  int _compare(K key1, K key2) => _comparator(key1, key2);
+
+  SplayTreeMap._internal();
+
+  V operator [](Object key) {
+    if (!_validKey(key)) return null;
+    if (_root != null) {
+      int comp = _splay(key);
+      if (comp == 0) {
+        return _root.value;
+      }
+    }
+    return null;
+  }
+
+  V remove(Object key) {
+    if (!_validKey(key)) return null;
+    _SplayTreeMapNode<K, V> mapRoot = _remove(key);
+    if (mapRoot != null) return mapRoot.value;
+    return null;
+  }
+
+  void operator []=(K key, V value) {
+    if (key == null) throw ArgumentError(key);
+    // Splay on the key to move the last node on the search path for
+    // the key to the root of the tree.
+    int comp = _splay(key);
+    if (comp == 0) {
+      _root.value = value;
+      return;
+    }
+    _addNewRoot(_SplayTreeMapNode(key, value), comp);
+  }
+
+  V putIfAbsent(K key, V ifAbsent()) {
+    if (key == null) throw ArgumentError(key);
+    int comp = _splay(key);
+    if (comp == 0) {
+      return _root.value;
+    }
+    int modificationCount = _modificationCount;
+    int splayCount = _splayCount;
+    V value = ifAbsent();
+    if (modificationCount != _modificationCount) {
+      throw ConcurrentModificationError(this);
+    }
+    if (splayCount != _splayCount) {
+      comp = _splay(key);
+      // Key is still not there, otherwise _modificationCount would be changed.
+      assert(comp != 0);
+    }
+    _addNewRoot(_SplayTreeMapNode(key, value), comp);
+    return value;
+  }
+
+  void addAll(Map<K, V> other) {
+    other.forEach((K key, V value) {
+      this[key] = value;
+    });
+  }
+
+  bool get isEmpty {
+    return (_root == null);
+  }
+
+  bool get isNotEmpty => !isEmpty;
+
+  void forEach(void f(K key, V value)) {
+    Iterator<_SplayTreeNode<K>> nodes = _SplayTreeNodeIterator<K>(this);
+    while (nodes.moveNext()) {
+      _SplayTreeMapNode<K, V> node = nodes.current;
+      f(node.key, node.value);
+    }
+  }
+
+  int get length {
+    return _count;
+  }
+
+  void clear() {
+    _clear();
+  }
+
+  bool containsKey(Object key) {
+    return _validKey(key) && _splay(key) == 0;
+  }
+
+  bool containsValue(Object value) {
+    int initialSplayCount = _splayCount;
+    bool visit(_SplayTreeMapNode node) {
+      while (node != null) {
+        if (node.value == value) return true;
+        if (initialSplayCount != _splayCount) {
+          throw ConcurrentModificationError(this);
+        }
+        if (node.right != null && visit(node.right)) return true;
+        node = node.left;
+      }
+      return false;
+    }
+
+    return visit(_root);
+  }
+
+  Iterable<K> get keys => _SplayTreeKeyIterable<K>(this);
+
+  Iterable<V> get values => _SplayTreeValueIterable<K, V>(this);
+
+  /// Get the first key in the map. Returns [:null:] if the map is empty.
+  K firstKey() {
+    if (_root == null) return null;
+    return _first.key;
+  }
+
+  /// Get the last key in the map. Returns [:null:] if the map is empty.
+  K lastKey() {
+    if (_root == null) return null;
+    return _last.key;
+  }
+
+  /// Get the last key in the map that is strictly smaller than [key]. Returns
+  /// [:null:] if no key was not found.
+  K lastKeyBefore(K key) {
+    if (key == null) throw ArgumentError(key);
+    if (_root == null) return null;
+    int comp = _splay(key);
+    if (comp < 0) return _root.key;
+    _SplayTreeNode<K> node = _root.left;
+    if (node == null) return null;
+    while (node.right != null) {
+      node = node.right;
+    }
+    return node.key;
+  }
+
+  /// Get the first key in the map that is strictly larger than [key]. Returns
+  /// [:null:] if no key was not found.
+  K firstKeyAfter(K key) {
+    if (key == null) throw ArgumentError(key);
+    if (_root == null) return null;
+    int comp = _splay(key);
+    if (comp > 0) return _root.key;
+    _SplayTreeNode<K> node = _root.right;
+    if (node == null) return null;
+    while (node.left != null) {
+      node = node.left;
+    }
+    return node.key;
+  }
+}
+
+abstract class _SplayTreeIterator<K, T> implements Iterator<T> {
+  final _SplayTree<K, _SplayTreeNode<K>> _tree;
+
+  /// Worklist of nodes to visit.
+  ///
+  /// These nodes have been passed over on the way down in a
+  /// depth-first left-to-right traversal. Visiting each node,
+  /// and their right subtrees will visit the remainder of
+  /// the nodes of a full traversal.
+  ///
+  /// Only valid as long as the original tree isn't reordered.
+  final List<_SplayTreeNode<K>> _workList = <_SplayTreeNode<K>>[];
+
+  /// Original modification counter of [_tree].
+  ///
+  /// Incremented on [_tree] when a key is added or removed.
+  /// If it changes, iteration is aborted.
+  ///
+  /// Not final because some iterators may modify the tree knowingly,
+  /// and they update the modification count in that case.
+  int _modificationCount;
+
+  /// Count of splay operations on [_tree] when [_workList] was built.
+  ///
+  /// If the splay count on [_tree] increases, [_workList] becomes invalid.
+  int _splayCount;
+
+  /// Current node.
+  _SplayTreeNode<K> _currentNode;
+
+  _SplayTreeIterator(_SplayTree<K, _SplayTreeNode<K>> tree)
+      : _tree = tree,
+        _modificationCount = tree._modificationCount,
+        _splayCount = tree._splayCount {
+    _findLeftMostDescendent(tree._root);
+  }
+
+  _SplayTreeIterator.startAt(_SplayTree<K, _SplayTreeNode<K>> tree, K startKey)
+      : _tree = tree,
+        _modificationCount = tree._modificationCount {
+    if (tree._root == null) return;
+    int compare = tree._splay(startKey);
+    _splayCount = tree._splayCount;
+    if (compare < 0) {
+      // Don't include the root, start at the next element after the root.
+      _findLeftMostDescendent(tree._root.right);
+    } else {
+      _workList.add(tree._root);
+    }
+  }
+
+  T get current {
+    if (_currentNode == null) return null;
+    return _getValue(_currentNode);
+  }
+
+  void _findLeftMostDescendent(_SplayTreeNode<K> node) {
+    while (node != null) {
+      _workList.add(node);
+      node = node.left;
+    }
+  }
+
+  /// Called when the tree structure of the tree has changed.
+  ///
+  /// This can be caused by a splay operation.
+  /// If the key-set changes, iteration is aborted before getting
+  /// here, so we know that the keys are the same as before, it's
+  /// only the tree that has been reordered.
+  void _rebuildWorkList(_SplayTreeNode<K> currentNode) {
+    assert(_workList.isNotEmpty);
+    _workList.clear();
+    if (currentNode == null) {
+      _findLeftMostDescendent(_tree._root);
+    } else {
+      _tree._splay(currentNode.key);
+      _findLeftMostDescendent(_tree._root.right);
+      assert(_workList.isNotEmpty);
+    }
+  }
+
+  bool moveNext() {
+    if (_modificationCount != _tree._modificationCount) {
+      throw ConcurrentModificationError(_tree);
+    }
+    // Picks the next element in the worklist as current.
+    // Updates the worklist with the left-most path of the current node's
+    // right-hand child.
+    // If the worklist is no longer valid (after a splay), it is rebuild
+    // from scratch.
+    if (_workList.isEmpty) {
+      _currentNode = null;
+      return false;
+    }
+    if (_tree._splayCount != _splayCount && _currentNode != null) {
+      _rebuildWorkList(_currentNode);
+    }
+    _currentNode = _workList.removeLast();
+    _findLeftMostDescendent(_currentNode.right);
+    return true;
+  }
+
+  T _getValue(_SplayTreeNode<K> node);
+}
+
+class _SplayTreeKeyIterable<K> extends EfficientLengthIterable<K> {
+  _SplayTree<K, _SplayTreeNode<K>> _tree;
+  _SplayTreeKeyIterable(this._tree);
+  int get length => _tree._count;
+  bool get isEmpty => _tree._count == 0;
+  Iterator<K> get iterator => _SplayTreeKeyIterator<K>(_tree);
+
+  Set<K> toSet() {
+    SplayTreeSet<K> set = SplayTreeSet<K>(_tree._comparator, _tree._validKey);
+    set._count = _tree._count;
+    set._root = set._copyNode(_tree._root);
+    return set;
+  }
+}
+
+class _SplayTreeValueIterable<K, V> extends EfficientLengthIterable<V> {
+  SplayTreeMap<K, V> _map;
+  _SplayTreeValueIterable(this._map);
+  int get length => _map._count;
+  bool get isEmpty => _map._count == 0;
+  Iterator<V> get iterator => _SplayTreeValueIterator<K, V>(_map);
+}
+
+class _SplayTreeKeyIterator<K> extends _SplayTreeIterator<K, K> {
+  _SplayTreeKeyIterator(_SplayTree<K, _SplayTreeNode<K>> map) : super(map);
+  K _getValue(_SplayTreeNode<K> node) => node.key;
+}
+
+class _SplayTreeValueIterator<K, V> extends _SplayTreeIterator<K, V> {
+  _SplayTreeValueIterator(SplayTreeMap<K, V> map) : super(map);
+  V _getValue(_SplayTreeNode<K> node) {
+    _SplayTreeMapNode<K, V> mapNode = node;
+    return mapNode.value;
+  }
+}
+
+class _SplayTreeNodeIterator<K>
+    extends _SplayTreeIterator<K, _SplayTreeNode<K>> {
+  _SplayTreeNodeIterator(_SplayTree<K, _SplayTreeNode<K>> tree) : super(tree);
+  _SplayTreeNodeIterator.startAt(
+      _SplayTree<K, _SplayTreeNode<K>> tree, K startKey)
+      : super.startAt(tree, startKey);
+  _SplayTreeNode<K> _getValue(_SplayTreeNode<K> node) => node;
+}
+
+/// A [Set] of objects that can be ordered relative to each other.
+///
+/// The set is based on a self-balancing binary tree. It allows most operations
+/// in amortized logarithmic time.
+///
+/// Elements of the set are compared using the `compare` function passed in
+/// the constructor, both for ordering and for equality.
+/// If the set contains only an object `a`, then `set.contains(b)`
+/// will return `true` if and only if `compare(a, b) == 0`,
+/// and the value of `a == b` is not even checked.
+/// If the compare function is omitted, the objects are assumed to be
+/// [Comparable], and are compared using their [Comparable.compareTo] method.
+/// Non-comparable objects (including `null`) will not work as an element
+/// in that case.
+class SplayTreeSet<E> extends _SplayTree<E, _SplayTreeNode<E>>
+    with IterableMixin<E>, SetMixin<E> {
+  _SplayTreeNode<E> _root;
+  final _SplayTreeNode<E> _dummy = _SplayTreeNode<E>(null);
+
+  Comparator<E> _comparator;
+  _Predicate _validKey;
+
+  /// Create a new [SplayTreeSet] with the given compare function.
+  ///
+  /// If the [compare] function is omitted, it defaults to [Comparable.compare],
+  /// and the elements must be comparable.
+  ///
+  /// A provided `compare` function may not work on all objects. It may not even
+  /// work on all `E` instances.
+  ///
+  /// For operations that add elements to the set, the user is supposed to not
+  /// pass in objects that doesn't work with the compare function.
+  ///
+  /// The methods [contains], [remove], [lookup], [removeAll] or [retainAll]
+  /// are typed to accept any object(s), and the [isValidKey] test can used to
+  /// filter those objects before handing them to the `compare` function.
+  ///
+  /// If [isValidKey] is provided, only values satisfying `isValidKey(other)`
+  /// are compared using the `compare` method in the methods mentioned above.
+  /// If the `isValidKey` function returns false for an object, it is assumed to
+  /// not be in the set.
+  ///
+  /// If omitted, the `isValidKey` function defaults to checking against the
+  /// type parameter: `other is E`.
+  SplayTreeSet([int compare(E key1, E key2), bool isValidKey(potentialKey)])
+      : _comparator = compare ?? _defaultCompare<E>(),
+        _validKey = isValidKey ?? ((v) => v is E);
+
+  /// Creates a [SplayTreeSet] that contains all [elements].
+  ///
+  /// The set works as if created by `new SplayTreeSet<E>(compare, isValidKey)`.
+  ///
+  /// All the [elements] should be instances of [E] and valid arguments to
+  /// [compare].
+  /// The `elements` iterable itself may have any element type, so this
+  /// constructor can be used to down-cast a `Set`, for example as:
+  /// ```dart
+  /// Set<SuperType> superSet = ...;
+  /// Set<SubType> subSet =
+  ///     new SplayTreeSet<SubType>.from(superSet.whereType<SubType>());
+  /// ```
+  factory SplayTreeSet.from(Iterable elements,
+      [int compare(E key1, E key2), bool isValidKey(potentialKey)]) {
+    SplayTreeSet<E> result = SplayTreeSet<E>(compare, isValidKey);
+    for (final element in elements) {
+      E e = element;
+      result.add(e);
+    }
+    return result;
+  }
+
+  /// Creates a [SplayTreeSet] from [elements].
+  ///
+  /// The set works as if created by `new SplayTreeSet<E>(compare, isValidKey)`.
+  ///
+  /// All the [elements] should be valid as arguments to the [compare] function.
+  factory SplayTreeSet.of(Iterable<E> elements,
+          [int compare(E key1, E key2), bool isValidKey(potentialKey)]) =>
+      SplayTreeSet(compare, isValidKey)..addAll(elements);
+
+  Set<T> _newSet<T>() =>
+      SplayTreeSet<T>((T a, T b) => _comparator(a as E, b as E), _validKey);
+
+  Set<R> cast<R>() => Set.castFrom<E, R>(this, newSet: _newSet);
+  int _compare(E e1, E e2) => _comparator(e1, e2);
+
+  // From Iterable.
+
+  Iterator<E> get iterator => _SplayTreeKeyIterator<E>(this);
+
+  int get length => _count;
+  bool get isEmpty => _root == null;
+  bool get isNotEmpty => _root != null;
+
+  E get first {
+    if (_count == 0) throw IterableElementError.noElement();
+    return _first.key;
+  }
+
+  E get last {
+    if (_count == 0) throw IterableElementError.noElement();
+    return _last.key;
+  }
+
+  E get single {
+    if (_count == 0) throw IterableElementError.noElement();
+    if (_count > 1) throw IterableElementError.tooMany();
+    return _root.key;
+  }
+
+  // From Set.
+  bool contains(Object element) {
+    return _validKey(element) && _splay(element) == 0;
+  }
+
+  bool add(E element) {
+    int compare = _splay(element);
+    if (compare == 0) return false;
+    _addNewRoot(_SplayTreeNode(element), compare);
+    return true;
+  }
+
+  bool remove(Object object) {
+    if (!_validKey(object)) return false;
+    return _remove(object) != null;
+  }
+
+  void addAll(Iterable<E> elements) {
+    for (E element in elements) {
+      int compare = _splay(element);
+      if (compare != 0) {
+        _addNewRoot(_SplayTreeNode(element), compare);
+      }
+    }
+  }
+
+  void removeAll(Iterable<Object> elements) {
+    for (Object element in elements) {
+      if (_validKey(element)) _remove(element);
+    }
+  }
+
+  void retainAll(Iterable<Object> elements) {
+    // Build a set with the same sense of equality as this set.
+    SplayTreeSet<E> retainSet = SplayTreeSet<E>(_comparator, _validKey);
+    int modificationCount = _modificationCount;
+    for (Object object in elements) {
+      if (modificationCount != _modificationCount) {
+        // The iterator should not have side effects.
+        throw ConcurrentModificationError(this);
+      }
+      // Equivalent to this.contains(object).
+      if (_validKey(object) && _splay(object) == 0) {
+        retainSet.add(_root.key);
+      }
+    }
+    // Take over the elements from the retained set, if it differs.
+    if (retainSet._count != _count) {
+      _root = retainSet._root;
+      _count = retainSet._count;
+      _modificationCount++;
+    }
+  }
+
+  E lookup(Object object) {
+    if (!_validKey(object)) return null;
+    int comp = _splay(object);
+    if (comp != 0) return null;
+    return _root.key;
+  }
+
+  Set<E> intersection(Set<Object> other) {
+    Set<E> result = SplayTreeSet<E>(_comparator, _validKey);
+    for (E element in this) {
+      if (other.contains(element)) result.add(element);
+    }
+    return result;
+  }
+
+  Set<E> difference(Set<Object> other) {
+    Set<E> result = SplayTreeSet<E>(_comparator, _validKey);
+    for (E element in this) {
+      if (!other.contains(element)) result.add(element);
+    }
+    return result;
+  }
+
+  Set<E> union(Set<E> other) {
+    return _clone()..addAll(other);
+  }
+
+  SplayTreeSet<E> _clone() {
+    var set = SplayTreeSet<E>(_comparator, _validKey);
+    set._count = _count;
+    set._root = _copyNode(_root);
+    return set;
+  }
+
+  // Copies the structure of a SplayTree into a new similar structure.
+  // Works on _SplayTreeMapNode as well, but only copies the keys,
+  _SplayTreeNode<E> _copyNode(_SplayTreeNode<E> node) {
+    if (node == null) return null;
+    return _SplayTreeNode<E>(node.key)
+      ..left = _copyNode(node.left)
+      ..right = _copyNode(node.right);
+  }
+
+  void clear() {
+    _clear();
+  }
+
+  Set<E> toSet() => _clone();
+
+  String toString() => IterableBase.iterableToFullString(this, '{', '}');
+}
diff --git a/sdk_nnbd/lib/convert/ascii.dart b/sdk_nnbd/lib/convert/ascii.dart
new file mode 100644
index 0000000..35105ac
--- /dev/null
+++ b/sdk_nnbd/lib/convert/ascii.dart
@@ -0,0 +1,287 @@
+// 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 dart.convert;
+
+/// An instance of the default implementation of the [AsciiCodec].
+///
+/// This instance provides a convenient access to the most common ASCII
+/// use cases.
+///
+/// Examples:
+/// ```dart
+/// var encoded = ascii.encode("This is ASCII!");
+/// var decoded = ascii.decode([0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73,
+///                             0x20, 0x41, 0x53, 0x43, 0x49, 0x49, 0x21]);
+/// ```
+const AsciiCodec ascii = AsciiCodec();
+
+const int _asciiMask = 0x7F;
+
+/// An [AsciiCodec] allows encoding strings as ASCII bytes
+/// and decoding ASCII bytes to strings.
+class AsciiCodec extends Encoding {
+  final bool _allowInvalid;
+
+  /// Instantiates a new [AsciiCodec].
+  ///
+  /// If [allowInvalid] is true, the [decode] method and the converter
+  /// returned by [decoder] will default to allowing invalid values.
+  /// If allowing invalid values, the values will be decoded into the Unicode
+  /// Replacement character (U+FFFD). If not, an exception will be thrown.
+  /// Calls to the [decode] method can choose to override this default.
+  ///
+  /// Encoders will not accept invalid (non ASCII) characters.
+  const AsciiCodec({bool allowInvalid = false}) : _allowInvalid = allowInvalid;
+
+  /// The name of this codec, "us-ascii".
+  String get name => "us-ascii";
+
+  Uint8List encode(String source) => encoder.convert(source);
+
+  /// Decodes the ASCII [bytes] (a list of unsigned 7-bit integers) to the
+  /// corresponding string.
+  ///
+  /// If [bytes] contains values that are not in the range 0 .. 127, the decoder
+  /// will eventually throw a [FormatException].
+  ///
+  /// If [allowInvalid] is not provided, it defaults to the value used to create
+  /// this [AsciiCodec].
+  String decode(List<int> bytes, {bool allowInvalid}) {
+    allowInvalid ??= _allowInvalid;
+    if (allowInvalid) {
+      return const AsciiDecoder(allowInvalid: true).convert(bytes);
+    } else {
+      return const AsciiDecoder(allowInvalid: false).convert(bytes);
+    }
+  }
+
+  AsciiEncoder get encoder => const AsciiEncoder();
+
+  AsciiDecoder get decoder => _allowInvalid
+      ? const AsciiDecoder(allowInvalid: true)
+      : const AsciiDecoder(allowInvalid: false);
+}
+
+// Superclass for [AsciiEncoder] and [Latin1Encoder].
+// Generalizes common operations that only differ by a mask;
+class _UnicodeSubsetEncoder extends Converter<String, List<int>> {
+  final int _subsetMask;
+
+  const _UnicodeSubsetEncoder(this._subsetMask);
+
+  /// Converts the [String] into a list of its code units.
+  ///
+  /// If [start] and [end] are provided, only the substring
+  /// `string.substring(start, end)` is used as input to the conversion.
+  Uint8List convert(String string, [int start = 0, int end]) {
+    var stringLength = string.length;
+    end = RangeError.checkValidRange(start, end, stringLength);
+    var length = end - start;
+    var result = Uint8List(length);
+    for (var i = 0; i < length; i++) {
+      var codeUnit = string.codeUnitAt(start + i);
+      if ((codeUnit & ~_subsetMask) != 0) {
+        throw ArgumentError.value(
+            string, "string", "Contains invalid characters.");
+      }
+      result[i] = codeUnit;
+    }
+    return result;
+  }
+
+  /// Starts a chunked conversion.
+  ///
+  /// The converter works more efficiently if the given [sink] is a
+  /// [ByteConversionSink].
+  StringConversionSink startChunkedConversion(Sink<List<int>> sink) {
+    return _UnicodeSubsetEncoderSink(_subsetMask,
+        sink is ByteConversionSink ? sink : ByteConversionSink.from(sink));
+  }
+
+  // Override the base-class' bind, to provide a better type.
+  Stream<List<int>> bind(Stream<String> stream) => super.bind(stream);
+}
+
+/// This class converts strings of only ASCII characters to bytes.
+class AsciiEncoder extends _UnicodeSubsetEncoder {
+  const AsciiEncoder() : super(_asciiMask);
+}
+
+/// This class encodes chunked strings to bytes (unsigned 8-bit
+/// integers).
+class _UnicodeSubsetEncoderSink extends StringConversionSinkBase {
+  final ByteConversionSink _sink;
+  final int _subsetMask;
+
+  _UnicodeSubsetEncoderSink(this._subsetMask, this._sink);
+
+  void close() {
+    _sink.close();
+  }
+
+  void addSlice(String source, int start, int end, bool isLast) {
+    RangeError.checkValidRange(start, end, source.length);
+    for (var i = start; i < end; i++) {
+      var codeUnit = source.codeUnitAt(i);
+      if ((codeUnit & ~_subsetMask) != 0) {
+        throw ArgumentError(
+            "Source contains invalid character with code point: $codeUnit.");
+      }
+    }
+    _sink.add(source.codeUnits.sublist(start, end));
+    if (isLast) {
+      close();
+    }
+  }
+}
+
+/// This class converts Latin-1 bytes (lists of unsigned 8-bit integers)
+/// to a string.
+abstract class _UnicodeSubsetDecoder extends Converter<List<int>, String> {
+  final bool _allowInvalid;
+  final int _subsetMask;
+
+  /// Instantiates a new decoder.
+  ///
+  /// The [_allowInvalid] argument defines how [convert] deals
+  /// with invalid bytes.
+  ///
+  /// The [_subsetMask] argument is a bit mask used to define the subset
+  /// of Unicode being decoded. Use [_LATIN1_MASK] for Latin-1 (8-bit) or
+  /// [_asciiMask] for ASCII (7-bit).
+  ///
+  /// If [_allowInvalid] is `true`, [convert] replaces invalid bytes with the
+  /// Unicode Replacement character `U+FFFD` (�).
+  /// Otherwise it throws a [FormatException].
+  const _UnicodeSubsetDecoder(this._allowInvalid, this._subsetMask);
+
+  /// Converts the [bytes] (a list of unsigned 7- or 8-bit integers) to the
+  /// corresponding string.
+  ///
+  /// If [start] and [end] are provided, only the sub-list of bytes from
+  /// `start` to `end` (`end` not inclusive) is used as input to the conversion.
+  String convert(List<int> bytes, [int start = 0, int end]) {
+    var byteCount = bytes.length;
+    RangeError.checkValidRange(start, end, byteCount);
+    end ??= byteCount;
+
+    for (var i = start; i < end; i++) {
+      var byte = bytes[i];
+      if ((byte & ~_subsetMask) != 0) {
+        if (!_allowInvalid) {
+          throw FormatException("Invalid value in input: $byte");
+        }
+        return _convertInvalid(bytes, start, end);
+      }
+    }
+    return String.fromCharCodes(bytes, start, end);
+  }
+
+  String _convertInvalid(List<int> bytes, int start, int end) {
+    var buffer = StringBuffer();
+    for (var i = start; i < end; i++) {
+      var value = bytes[i];
+      if ((value & ~_subsetMask) != 0) value = 0xFFFD;
+      buffer.writeCharCode(value);
+    }
+    return buffer.toString();
+  }
+
+  /// Starts a chunked conversion.
+  ///
+  /// The converter works more efficiently if the given [sink] is a
+  /// [StringConversionSink].
+  ByteConversionSink startChunkedConversion(Sink<String> sink);
+
+  // Override the base-class's bind, to provide a better type.
+  Stream<String> bind(Stream<List<int>> stream) => super.bind(stream);
+}
+
+class AsciiDecoder extends _UnicodeSubsetDecoder {
+  const AsciiDecoder({bool allowInvalid = false})
+      : super(allowInvalid, _asciiMask);
+
+  /// Starts a chunked conversion.
+  ///
+  /// The converter works more efficiently if the given [sink] is a
+  /// [StringConversionSink].
+  ByteConversionSink startChunkedConversion(Sink<String> sink) {
+    StringConversionSink stringSink;
+    if (sink is StringConversionSink) {
+      stringSink = sink;
+    } else {
+      stringSink = StringConversionSink.from(sink);
+    }
+    // TODO(lrn): Use asUtf16Sink when it becomes available. It
+    // works just as well, is likely to have less decoding overhead,
+    // and make adding U+FFFD easier.
+    // At that time, merge this with _Latin1DecoderSink;
+    if (_allowInvalid) {
+      return _ErrorHandlingAsciiDecoderSink(stringSink.asUtf8Sink(false));
+    } else {
+      return _SimpleAsciiDecoderSink(stringSink);
+    }
+  }
+}
+
+class _ErrorHandlingAsciiDecoderSink extends ByteConversionSinkBase {
+  ByteConversionSink _utf8Sink;
+  _ErrorHandlingAsciiDecoderSink(this._utf8Sink);
+
+  void close() {
+    _utf8Sink.close();
+  }
+
+  void add(List<int> source) {
+    addSlice(source, 0, source.length, false);
+  }
+
+  void addSlice(List<int> source, int start, int end, bool isLast) {
+    RangeError.checkValidRange(start, end, source.length);
+    for (var i = start; i < end; i++) {
+      if ((source[i] & ~_asciiMask) != 0) {
+        if (i > start) _utf8Sink.addSlice(source, start, i, false);
+        // Add UTF-8 encoding of U+FFFD.
+        _utf8Sink.add(const <int>[0xEF, 0xBF, 0xBD]);
+        start = i + 1;
+      }
+    }
+    if (start < end) {
+      _utf8Sink.addSlice(source, start, end, isLast);
+    } else if (isLast) {
+      close();
+    }
+  }
+}
+
+class _SimpleAsciiDecoderSink extends ByteConversionSinkBase {
+  Sink _sink;
+  _SimpleAsciiDecoderSink(this._sink);
+
+  void close() {
+    _sink.close();
+  }
+
+  void add(List<int> source) {
+    for (var i = 0; i < source.length; i++) {
+      if ((source[i] & ~_asciiMask) != 0) {
+        throw FormatException("Source contains non-ASCII bytes.");
+      }
+    }
+    _sink.add(String.fromCharCodes(source));
+  }
+
+  void addSlice(List<int> source, int start, int end, bool isLast) {
+    final length = source.length;
+    RangeError.checkValidRange(start, end, length);
+    if (start < end) {
+      if (start != 0 || end != length) {
+        source = source.sublist(start, end);
+      }
+      add(source);
+    }
+    if (isLast) close();
+  }
+}
diff --git a/sdk_nnbd/lib/convert/base64.dart b/sdk_nnbd/lib/convert/base64.dart
new file mode 100644
index 0000000..ce522be
--- /dev/null
+++ b/sdk_nnbd/lib/convert/base64.dart
@@ -0,0 +1,854 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.convert;
+
+/// A [base64](https://tools.ietf.org/html/rfc4648) encoder and decoder.
+///
+/// It encodes using the default base64 alphabet,
+/// decodes using both the base64 and base64url alphabets,
+/// does not allow invalid characters and requires padding.
+///
+/// Examples:
+///
+///     var encoded = base64.encode([0x62, 0x6c, 0xc3, 0xa5, 0x62, 0xc3, 0xa6,
+///                                  0x72, 0x67, 0x72, 0xc3, 0xb8, 0x64]);
+///     var decoded = base64.decode("YmzDpWLDpnJncsO4ZAo=");
+///
+/// The top-level [base64Encode] and [base64Decode] functions may be used
+/// instead if a local variable shadows the [base64] constant.
+const Base64Codec base64 = Base64Codec();
+
+/// A [base64url](https://tools.ietf.org/html/rfc4648) encoder and decoder.
+///
+/// It encodes and decodes using the base64url alphabet,
+/// decodes using both the base64 and base64url alphabets,
+/// does not allow invalid characters and requires padding.
+///
+/// Examples:
+///
+///     var encoded = base64Url.encode([0x62, 0x6c, 0xc3, 0xa5, 0x62, 0xc3, 0xa6,
+///                                     0x72, 0x67, 0x72, 0xc3, 0xb8, 0x64]);
+///     var decoded = base64Url.decode("YmzDpWLDpnJncsO4ZAo=");
+const Base64Codec base64Url = Base64Codec.urlSafe();
+
+/// Encodes [bytes] using [base64](https://tools.ietf.org/html/rfc4648) encoding.
+///
+/// Shorthand for [base64.encode]. Useful if a local variable shadows the global
+/// [base64] constant.
+String base64Encode(List<int> bytes) => base64.encode(bytes);
+
+/// Encodes [bytes] using [base64url](https://tools.ietf.org/html/rfc4648) encoding.
+///
+/// Shorthand for [base64url.encode].
+String base64UrlEncode(List<int> bytes) => base64Url.encode(bytes);
+
+/// Decodes [base64](https://tools.ietf.org/html/rfc4648) or [base64url](https://tools.ietf.org/html/rfc4648) encoded bytes.
+///
+/// Shorthand for [base64.decode]. Useful if a local variable shadows the
+/// global [base64] constant.
+Uint8List base64Decode(String source) => base64.decode(source);
+
+// Constants used in more than one class.
+const int _paddingChar = 0x3d; // '='.
+
+/// A [base64](https://tools.ietf.org/html/rfc4648) encoder and decoder.
+///
+/// A [Base64Codec] allows base64 encoding bytes into ASCII strings and
+/// decoding valid encodings back to bytes.
+///
+/// This implementation only handles the simplest RFC 4648 base64 and base64url
+/// encodings.
+/// It does not allow invalid characters when decoding and it requires,
+/// and generates, padding so that the input is always a multiple of four
+/// characters.
+class Base64Codec extends Codec<List<int>, String> {
+  final Base64Encoder _encoder;
+  const Base64Codec() : _encoder = const Base64Encoder();
+  const Base64Codec.urlSafe() : _encoder = const Base64Encoder.urlSafe();
+
+  Base64Encoder get encoder => _encoder;
+
+  Base64Decoder get decoder => const Base64Decoder();
+
+  /// Decodes [encoded].
+  ///
+  /// The input is decoded as if by `decoder.convert`.
+  ///
+  /// The returned [Uint8List] contains exactly the decoded bytes,
+  /// so the [Uint8List.length] is precisely the number of decoded bytes.
+  /// The [Uint8List.buffer] may be larger than the decoded bytes.
+  Uint8List decode(String encoded) => decoder.convert(encoded);
+
+  /// Validates and normalizes the base64 encoded data in [source].
+  ///
+  /// Only acts on the substring from [start] to [end], with [end]
+  /// defaulting to the end of the string.
+  ///
+  /// Normalization will:
+  /// * Unescape any `%`-escapes.
+  /// * Only allow valid characters (`A`-`Z`, `a`-`z`, `0`-`9`, `/` and `+`).
+  /// * Normalize a `_` or `-` character to `/` or `+`.
+  /// * Validate that existing padding (trailing `=` characters) is correct.
+  /// * If no padding exists, add correct padding if necessary and possible.
+  /// * Validate that the length is correct (a multiple of four).
+  String normalize(String source, [int start = 0, int end]) {
+    end = RangeError.checkValidRange(start, end, source.length);
+    const percent = 0x25;
+    const equals = 0x3d;
+    StringBuffer buffer;
+    var sliceStart = start;
+    var alphabet = _Base64Encoder._base64Alphabet;
+    var inverseAlphabet = _Base64Decoder._inverseAlphabet;
+    var firstPadding = -1;
+    var firstPaddingSourceIndex = -1;
+    var paddingCount = 0;
+    for (var i = start; i < end;) {
+      var sliceEnd = i;
+      var char = source.codeUnitAt(i++);
+      var originalChar = char;
+      // Normalize char, keep originalChar to see if it matches the source.
+      if (char == percent) {
+        if (i + 2 <= end) {
+          char = parseHexByte(source, i); // May be negative.
+          i += 2;
+          // We know that %25 isn't valid, but our table considers it
+          // a potential padding start, so skip the checks.
+          if (char == percent) char = -1;
+        } else {
+          // An invalid HEX escape (too short).
+          // Just skip past the handling and reach the throw below.
+          char = -1;
+        }
+      }
+      // If char is negative here, hex-decoding failed in some way.
+      if (0 <= char && char <= 127) {
+        var value = inverseAlphabet[char];
+        if (value >= 0) {
+          char = alphabet.codeUnitAt(value);
+          if (char == originalChar) continue;
+        } else if (value == _Base64Decoder._padding) {
+          // We have ruled out percent, so char is '='.
+          if (firstPadding < 0) {
+            // Mark position in normalized output where padding occurs.
+            firstPadding = (buffer?.length ?? 0) + (sliceEnd - sliceStart);
+            firstPaddingSourceIndex = sliceEnd;
+          }
+          paddingCount++;
+          // It could have been an escaped equals (%3D).
+          if (originalChar == equals) continue;
+        }
+        if (value != _Base64Decoder._invalid) {
+          buffer ??= StringBuffer();
+          buffer.write(source.substring(sliceStart, sliceEnd));
+          buffer.writeCharCode(char);
+          sliceStart = i;
+          continue;
+        }
+      }
+      throw FormatException("Invalid base64 data", source, sliceEnd);
+    }
+    if (buffer != null) {
+      buffer.write(source.substring(sliceStart, end));
+      if (firstPadding >= 0) {
+        // There was padding in the source. Check that it is valid:
+        // * result length a multiple of four
+        // * one or two padding characters at the end.
+        _checkPadding(source, firstPaddingSourceIndex, end, firstPadding,
+            paddingCount, buffer.length);
+      } else {
+        // Length of last chunk (1-4 chars) in the encoding.
+        var endLength = ((buffer.length - 1) % 4) + 1;
+        if (endLength == 1) {
+          // The data must have length 0, 2 or 3 modulo 4.
+          throw FormatException("Invalid base64 encoding length ", source, end);
+        }
+        while (endLength < 4) {
+          buffer.write("=");
+          endLength++;
+        }
+      }
+      return source.replaceRange(start, end, buffer.toString());
+    }
+    // Original was already normalized, only check padding.
+    var length = end - start;
+    if (firstPadding >= 0) {
+      _checkPadding(source, firstPaddingSourceIndex, end, firstPadding,
+          paddingCount, length);
+    } else {
+      // No padding given, so add some if needed it.
+      var endLength = length % 4;
+      if (endLength == 1) {
+        // The data must have length 0, 2 or 3 modulo 4.
+        throw FormatException("Invalid base64 encoding length ", source, end);
+      }
+      if (endLength > 1) {
+        // There is no "insertAt" on String, but this works as well.
+        source = source.replaceRange(end, end, (endLength == 2) ? "==" : "=");
+      }
+    }
+    return source;
+  }
+
+  static void _checkPadding(String source, int sourceIndex, int sourceEnd,
+      int firstPadding, int paddingCount, int length) {
+    if (length % 4 != 0) {
+      throw FormatException(
+          "Invalid base64 padding, padded length must be multiple of four, "
+          "is $length",
+          source,
+          sourceEnd);
+    }
+    if (firstPadding + paddingCount != length) {
+      throw FormatException(
+          "Invalid base64 padding, '=' not at the end", source, sourceIndex);
+    }
+    if (paddingCount > 2) {
+      throw FormatException(
+          "Invalid base64 padding, more than two '=' characters",
+          source,
+          sourceIndex);
+    }
+  }
+}
+
+// ------------------------------------------------------------------------
+// Encoder
+// ------------------------------------------------------------------------
+
+/// Base64 and base64url encoding converter.
+///
+/// Encodes lists of bytes using base64 or base64url encoding.
+///
+/// The results are ASCII strings using a restricted alphabet.
+class Base64Encoder extends Converter<List<int>, String> {
+  final bool _urlSafe;
+
+  const Base64Encoder() : _urlSafe = false;
+  const Base64Encoder.urlSafe() : _urlSafe = true;
+
+  String convert(List<int> input) {
+    if (input.isEmpty) return "";
+    var encoder = _Base64Encoder(_urlSafe);
+    var buffer = encoder.encode(input, 0, input.length, true);
+    return String.fromCharCodes(buffer);
+  }
+
+  ByteConversionSink startChunkedConversion(Sink<String> sink) {
+    if (sink is StringConversionSink) {
+      return _Utf8Base64EncoderSink(sink.asUtf8Sink(false), _urlSafe);
+    }
+    return _AsciiBase64EncoderSink(sink, _urlSafe);
+  }
+}
+
+/// Helper class for encoding bytes to base64.
+class _Base64Encoder {
+  /// The RFC 4648 base64 encoding alphabet.
+  static const String _base64Alphabet =
+      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+  /// The RFC 4648 base64url encoding alphabet.
+  static const String _base64UrlAlphabet =
+      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+
+  /// Shift-count to extract the values stored in [_state].
+  static const int _valueShift = 2;
+
+  /// Mask to extract the count value stored in [_state].
+  static const int _countMask = 3;
+
+  static const int _sixBitMask = 0x3F;
+
+  /// Intermediate state between chunks.
+  ///
+  /// Encoding handles three bytes at a time.
+  /// If fewer than three bytes has been seen, this value encodes
+  /// the number of bytes seen (0, 1 or 2) and their values.
+  int _state = 0;
+
+  /// Alphabet used for encoding.
+  final String _alphabet;
+
+  _Base64Encoder(bool urlSafe)
+      : _alphabet = urlSafe ? _base64UrlAlphabet : _base64Alphabet;
+
+  /// Encode count and bits into a value to be stored in [_state].
+  static int _encodeState(int count, int bits) {
+    assert(count <= _countMask);
+    return bits << _valueShift | count;
+  }
+
+  /// Extract bits from encoded state.
+  static int _stateBits(int state) => state >> _valueShift;
+
+  /// Extract count from encoded state.
+  static int _stateCount(int state) => state & _countMask;
+
+  /// Create a [Uint8List] with the provided length.
+  Uint8List createBuffer(int bufferLength) => Uint8List(bufferLength);
+
+  /// Encode [bytes] from [start] to [end] and the bits in [_state].
+  ///
+  /// Returns a [Uint8List] of the ASCII codes of the encoded data.
+  ///
+  /// If the input, including left over [_state] from earlier encodings,
+  /// are not a multiple of three bytes, then the partial state is stored
+  /// back into [_state].
+  /// If [isLast] is true, partial state is encoded in the output instead,
+  /// with the necessary padding.
+  ///
+  /// Returns `null` if there is no output.
+  Uint8List encode(List<int> bytes, int start, int end, bool isLast) {
+    assert(0 <= start);
+    assert(start <= end);
+    assert(bytes == null || end <= bytes.length);
+    var length = end - start;
+
+    var count = _stateCount(_state);
+    var byteCount = (count + length);
+    var fullChunks = byteCount ~/ 3;
+    var partialChunkLength = byteCount - fullChunks * 3;
+    var bufferLength = fullChunks * 4;
+    if (isLast && partialChunkLength > 0) {
+      bufferLength += 4; // Room for padding.
+    }
+    var output = createBuffer(bufferLength);
+    _state =
+        encodeChunk(_alphabet, bytes, start, end, isLast, output, 0, _state);
+    if (bufferLength > 0) return output;
+    // If the input plus the data in state is still less than three bytes,
+    // there may not be any output.
+    return null;
+  }
+
+  static int encodeChunk(String alphabet, List<int> bytes, int start, int end,
+      bool isLast, Uint8List output, int outputIndex, int state) {
+    var bits = _stateBits(state);
+    // Count number of missing bytes in three-byte chunk.
+    var expectedChars = 3 - _stateCount(state);
+
+    // The input must be a list of bytes (integers in the range 0..255).
+    // The value of `byteOr` will be the bitwise or of all the values in
+    // `bytes` and a later check will validate that they were all valid bytes.
+    var byteOr = 0;
+    for (var i = start; i < end; i++) {
+      var byte = bytes[i];
+      byteOr |= byte;
+      bits = ((bits << 8) | byte) & 0xFFFFFF; // Never store more than 24 bits.
+      expectedChars--;
+      if (expectedChars == 0) {
+        output[outputIndex++] = alphabet.codeUnitAt((bits >> 18) & _sixBitMask);
+        output[outputIndex++] = alphabet.codeUnitAt((bits >> 12) & _sixBitMask);
+        output[outputIndex++] = alphabet.codeUnitAt((bits >> 6) & _sixBitMask);
+        output[outputIndex++] = alphabet.codeUnitAt(bits & _sixBitMask);
+        expectedChars = 3;
+        bits = 0;
+      }
+    }
+    if (byteOr >= 0 && byteOr <= 255) {
+      if (isLast && expectedChars < 3) {
+        writeFinalChunk(alphabet, output, outputIndex, 3 - expectedChars, bits);
+        return 0;
+      }
+      return _encodeState(3 - expectedChars, bits);
+    }
+
+    // There was an invalid byte value somewhere in the input - find it!
+    var i = start;
+    while (i < end) {
+      var byte = bytes[i];
+      if (byte < 0 || byte > 255) break;
+      i++;
+    }
+    throw ArgumentError.value(
+        bytes, "Not a byte value at index $i: 0x${bytes[i].toRadixString(16)}");
+  }
+
+  /// Writes a final encoded four-character chunk.
+  ///
+  /// Only used when the [_state] contains a partial (1 or 2 byte)
+  /// input.
+  static void writeFinalChunk(
+      String alphabet, Uint8List output, int outputIndex, int count, int bits) {
+    assert(count > 0);
+    if (count == 1) {
+      output[outputIndex++] = alphabet.codeUnitAt((bits >> 2) & _sixBitMask);
+      output[outputIndex++] = alphabet.codeUnitAt((bits << 4) & _sixBitMask);
+      output[outputIndex++] = _paddingChar;
+      output[outputIndex++] = _paddingChar;
+    } else {
+      assert(count == 2);
+      output[outputIndex++] = alphabet.codeUnitAt((bits >> 10) & _sixBitMask);
+      output[outputIndex++] = alphabet.codeUnitAt((bits >> 4) & _sixBitMask);
+      output[outputIndex++] = alphabet.codeUnitAt((bits << 2) & _sixBitMask);
+      output[outputIndex++] = _paddingChar;
+    }
+  }
+}
+
+class _BufferCachingBase64Encoder extends _Base64Encoder {
+  /// Reused buffer.
+  ///
+  /// When the buffer isn't released to the sink, only used to create another
+  /// value (a string), the buffer can be reused between chunks.
+  Uint8List bufferCache;
+
+  _BufferCachingBase64Encoder(bool urlSafe) : super(urlSafe);
+
+  Uint8List createBuffer(int bufferLength) {
+    if (bufferCache == null || bufferCache.length < bufferLength) {
+      bufferCache = Uint8List(bufferLength);
+    }
+    // Return a view of the buffer, so it has the requested length.
+    return Uint8List.view(bufferCache.buffer, 0, bufferLength);
+  }
+}
+
+abstract class _Base64EncoderSink extends ByteConversionSinkBase {
+  void add(List<int> source) {
+    _add(source, 0, source.length, false);
+  }
+
+  void close() {
+    _add(null, 0, 0, true);
+  }
+
+  void addSlice(List<int> source, int start, int end, bool isLast) {
+    if (end == null) throw ArgumentError.notNull("end");
+    RangeError.checkValidRange(start, end, source.length);
+    _add(source, start, end, isLast);
+  }
+
+  void _add(List<int> source, int start, int end, bool isLast);
+}
+
+class _AsciiBase64EncoderSink extends _Base64EncoderSink {
+  final Sink<String> _sink;
+  final _Base64Encoder _encoder;
+
+  _AsciiBase64EncoderSink(this._sink, bool urlSafe)
+      : _encoder = _BufferCachingBase64Encoder(urlSafe);
+
+  void _add(List<int> source, int start, int end, bool isLast) {
+    var buffer = _encoder.encode(source, start, end, isLast);
+    if (buffer != null) {
+      var string = String.fromCharCodes(buffer);
+      _sink.add(string);
+    }
+    if (isLast) {
+      _sink.close();
+    }
+  }
+}
+
+class _Utf8Base64EncoderSink extends _Base64EncoderSink {
+  final ByteConversionSink _sink;
+  final _Base64Encoder _encoder;
+
+  _Utf8Base64EncoderSink(this._sink, bool urlSafe)
+      : _encoder = _Base64Encoder(urlSafe);
+
+  void _add(List<int> source, int start, int end, bool isLast) {
+    var buffer = _encoder.encode(source, start, end, isLast);
+    if (buffer != null) {
+      _sink.addSlice(buffer, 0, buffer.length, isLast);
+    }
+  }
+}
+
+// ------------------------------------------------------------------------
+// Decoder
+// ------------------------------------------------------------------------
+
+/// Decoder for base64 encoded data.
+///
+/// This decoder accepts both base64 and base64url ("url-safe") encodings.
+///
+/// The encoding is required to be properly padded.
+class Base64Decoder extends Converter<String, List<int>> {
+  const Base64Decoder();
+
+  /// Decodes the characters of [input] from [start] to [end] as base64.
+  ///
+  /// If [start] is omitted, it defaults to the start of [input].
+  /// If [end] is omitted, it defaults to the end of [input].
+  ///
+  /// The returned [Uint8List] contains exactly the decoded bytes,
+  /// so the [Uint8List.length] is precisely the number of decoded bytes.
+  /// The [Uint8List.buffer] may be larger than the decoded bytes.
+  Uint8List convert(String input, [int start = 0, int end]) {
+    end = RangeError.checkValidRange(start, end, input.length);
+    if (start == end) return Uint8List(0);
+    var decoder = _Base64Decoder();
+    var buffer = decoder.decode(input, start, end);
+    decoder.close(input, end);
+    return buffer;
+  }
+
+  StringConversionSink startChunkedConversion(Sink<List<int>> sink) {
+    return _Base64DecoderSink(sink);
+  }
+}
+
+/// Helper class implementing base64 decoding with intermediate state.
+class _Base64Decoder {
+  /// Shift-count to extract the values stored in [_state].
+  static const int _valueShift = 2;
+
+  /// Mask to extract the count value stored in [_state].
+  static const int _countMask = 3;
+
+  /// Invalid character in decoding table.
+  static const int _invalid = -2;
+
+  /// Padding character in decoding table.
+  static const int _padding = -1;
+
+  // Shorthands to make the table more readable.
+  static const int __ = _invalid;
+  static const int _p = _padding;
+
+  /// Mapping from ASCII characters to their index in the base64 alphabet.
+  ///
+  /// Uses [_invalid] for invalid indices and [_padding] for the padding
+  /// character.
+  ///
+  /// Accepts the "URL-safe" alphabet as well (`-` and `_` are the
+  /// 62nd and 63rd alphabet characters), and considers `%` a padding
+  /// character, which must then be followed by `3D`, the percent-escape
+  /// for `=`.
+  static final List<int> _inverseAlphabet = Int8List.fromList([
+    __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, //
+    __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, //
+    __, __, __, __, __, _p, __, __, __, __, __, 62, __, 62, __, 63, //
+    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, __, __, __, _p, __, __, //
+    __, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, //
+    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, __, __, __, __, 63, //
+    __, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, //
+    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, __, __, __, __, __, //
+  ]);
+
+  // Character constants.
+  static const int _char_percent = 0x25; // '%'.
+  static const int _char_3 = 0x33; // '3'.
+  static const int _char_d = 0x64; // 'd'.
+
+  /// Maintains the intermediate state of a partly-decoded input.
+  ///
+  /// Base64 is decoded in chunks of four characters. If a chunk does not
+  /// contain a full block, the decoded bits (six per character) of the
+  /// available characters are stored in [_state] until the next call to
+  /// [_decode] or [_close].
+  ///
+  /// If no padding has been seen, the value is
+  ///   `numberOfCharactersSeen | (decodedBits << 2)`
+  /// where `numberOfCharactersSeen` is between 0 and 3 and decoded bits
+  /// contains six bits per seen character.
+  ///
+  /// If padding has been seen the value is negative. It's the bitwise negation
+  /// of the number of remaining allowed padding characters (always ~0 or ~1).
+  ///
+  /// A state of `0` or `~0` are valid places to end decoding, all other values
+  /// mean that a four-character block has not been completed.
+  int _state = 0;
+
+  /// Encodes [count] and [bits] as a value to be stored in [_state].
+  static int _encodeCharacterState(int count, int bits) {
+    assert(count == (count & _countMask));
+    return (bits << _valueShift | count);
+  }
+
+  /// Extracts count from a [_state] value.
+  static int _stateCount(int state) {
+    assert(state >= 0);
+    return state & _countMask;
+  }
+
+  /// Extracts value bits from a [_state] value.
+  static int _stateBits(int state) {
+    assert(state >= 0);
+    return state >> _valueShift;
+  }
+
+  /// Encodes a number of expected padding characters to be stored in [_state].
+  static int _encodePaddingState(int expectedPadding) {
+    assert(expectedPadding >= 0);
+    assert(expectedPadding <= 5);
+    return -expectedPadding - 1; // ~expectedPadding adapted to dart2js.
+  }
+
+  /// Extracts expected padding character count from a [_state] value.
+  static int _statePadding(int state) {
+    assert(state < 0);
+    return -state - 1; // ~state adapted to dart2js.
+  }
+
+  static bool _hasSeenPadding(int state) => state < 0;
+
+  /// Decodes [input] from [start] to [end].
+  ///
+  /// Returns a [Uint8List] with the decoded bytes.
+  /// If a previous call had an incomplete four-character block, the bits from
+  /// those are included in decoding
+  Uint8List decode(String input, int start, int end) {
+    assert(0 <= start);
+    assert(start <= end);
+    assert(end <= input.length);
+    if (_hasSeenPadding(_state)) {
+      _state = _checkPadding(input, start, end, _state);
+      return null;
+    }
+    if (start == end) return Uint8List(0);
+    var buffer = _allocateBuffer(input, start, end, _state);
+    _state = decodeChunk(input, start, end, buffer, 0, _state);
+    return buffer;
+  }
+
+  /// Checks that [_state] represents a valid decoding.
+  void close(String input, int end) {
+    if (_state < _encodePaddingState(0)) {
+      throw FormatException("Missing padding character", input, end);
+    }
+    if (_state > 0) {
+      throw FormatException(
+          "Invalid length, must be multiple of four", input, end);
+    }
+    _state = _encodePaddingState(0);
+  }
+
+  /// Decodes [input] from [start] to [end].
+  ///
+  /// Includes the state returned by a previous call in the decoding.
+  /// Writes the decoding to [output] at [outIndex], and there must
+  /// be room in the output.
+  static int decodeChunk(String input, int start, int end, Uint8List output,
+      int outIndex, int state) {
+    assert(!_hasSeenPadding(state));
+    const asciiMask = 127;
+    const asciiMax = 127;
+    const eightBitMask = 0xFF;
+    const bitsPerCharacter = 6;
+
+    var bits = _stateBits(state);
+    var count = _stateCount(state);
+    // String contents should be all ASCII.
+    // Instead of checking for each character, we collect the bitwise-or of
+    // all the characters in `charOr` and later validate that all characters
+    // were ASCII.
+    var charOr = 0;
+    for (var i = start; i < end; i++) {
+      var char = input.codeUnitAt(i);
+      charOr |= char;
+      var code = _inverseAlphabet[char & asciiMask];
+      if (code >= 0) {
+        bits = ((bits << bitsPerCharacter) | code) & 0xFFFFFF;
+        count = (count + 1) & 3;
+        if (count == 0) {
+          assert(outIndex + 3 <= output.length);
+          output[outIndex++] = (bits >> 16) & eightBitMask;
+          output[outIndex++] = (bits >> 8) & eightBitMask;
+          output[outIndex++] = bits & eightBitMask;
+          bits = 0;
+        }
+        continue;
+      } else if (code == _padding && count > 1) {
+        if (charOr < 0 || charOr > asciiMax) break;
+        if (count == 3) {
+          if ((bits & 0x03) != 0) {
+            throw FormatException("Invalid encoding before padding", input, i);
+          }
+          output[outIndex++] = bits >> 10;
+          output[outIndex++] = bits >> 2;
+        } else {
+          if ((bits & 0x0F) != 0) {
+            throw FormatException("Invalid encoding before padding", input, i);
+          }
+          output[outIndex++] = bits >> 4;
+        }
+        // Expected padding is the number of expected padding characters,
+        // where `=` counts as three and `%3D` counts as one per character.
+        //
+        // Expect either zero or one padding depending on count (2 or 3),
+        // plus two more characters if the code was `%` (a partial padding).
+        var expectedPadding = (3 - count) * 3;
+        if (char == _char_percent) expectedPadding += 2;
+        state = _encodePaddingState(expectedPadding);
+        return _checkPadding(input, i + 1, end, state);
+      }
+      throw FormatException("Invalid character", input, i);
+    }
+    if (charOr >= 0 && charOr <= asciiMax) {
+      return _encodeCharacterState(count, bits);
+    }
+    // There is an invalid (non-ASCII) character in the input.
+    int i;
+    for (i = start; i < end; i++) {
+      var char = input.codeUnitAt(i);
+      if (char < 0 || char > asciiMax) break;
+    }
+    throw FormatException("Invalid character", input, i);
+  }
+
+  /// Allocates a buffer with room for the decoding of a substring of [input].
+  ///
+  /// Includes room for the characters in [state], and handles padding correctly.
+  static Uint8List _allocateBuffer(
+      String input, int start, int end, int state) {
+    assert(state >= 0);
+    var paddingStart = _trimPaddingChars(input, start, end);
+    var length = _stateCount(state) + (paddingStart - start);
+    // Three bytes per full four bytes in the input.
+    var bufferLength = (length >> 2) * 3;
+    // If padding was seen, then this is the last chunk, and the final partial
+    // chunk should be decoded too.
+    var remainderLength = length & 3;
+    if (remainderLength != 0 && paddingStart < end) {
+      bufferLength += remainderLength - 1;
+    }
+    if (bufferLength > 0) return Uint8List(bufferLength);
+    // If the input plus state is less than four characters, and it's not
+    // at the end of input, no buffer is needed.
+    return null;
+  }
+
+  /// Returns the position of the start of padding at the end of the input.
+  ///
+  /// Returns the end of input if there is no padding.
+  ///
+  /// This is used to ensure that the decoding buffer has the exact size
+  /// it needs when input is valid, and at least enough bytes to reach the error
+  /// when input is invalid.
+  ///
+  /// Never count more than two padding sequences since any more than that
+  /// will raise an error anyway, and we only care about being precise for
+  /// successful conversions.
+  static int _trimPaddingChars(String input, int start, int end) {
+    // This may count '%=' as two paddings. That's ok, it will err later,
+    // but the buffer will be large enough to reach the error.
+    var padding = 0;
+    var index = end;
+    var newEnd = end;
+    while (index > start && padding < 2) {
+      index--;
+      var char = input.codeUnitAt(index);
+      if (char == _paddingChar) {
+        padding++;
+        newEnd = index;
+        continue;
+      }
+      if ((char | 0x20) == _char_d) {
+        if (index == start) break;
+        index--;
+        char = input.codeUnitAt(index);
+      }
+      if (char == _char_3) {
+        if (index == start) break;
+        index--;
+        char = input.codeUnitAt(index);
+      }
+      if (char == _char_percent) {
+        padding++;
+        newEnd = index;
+        continue;
+      }
+      break;
+    }
+    return newEnd;
+  }
+
+  /// Check that the remainder of the string is valid padding.
+  ///
+  /// Valid padding is a correct number (0, 1 or 2) of `=` characters
+  /// or `%3D` sequences depending on the number of preceding base64 characters.
+  /// The [state] parameter encodes which padding continuations are allowed
+  /// as the number of expected characters. That number is the number of
+  /// expected padding characters times 3 minus the number of padding characters
+  /// seen so far, where `=` counts as 3 counts as three characters,
+  /// and the padding sequence `%3D` counts as one character per character.
+  ///
+  /// The number of missing characters is always between 0 and 5 because we
+  /// only call this function after having seen at least one `=` or `%`
+  /// character.
+  /// If the number of missing characters is not 3 or 0, we have seen (at least)
+  /// a `%` character and expects the rest of the `%3D` sequence, and a `=` is
+  /// not allowed. When missing 3 characters, either `=` or `%` is allowed.
+  ///
+  /// When the value is 0, no more padding (or any other character) is allowed.
+  static int _checkPadding(String input, int start, int end, int state) {
+    assert(_hasSeenPadding(state));
+    if (start == end) return state;
+    var expectedPadding = _statePadding(state);
+    assert(expectedPadding >= 0);
+    assert(expectedPadding < 6);
+    while (expectedPadding > 0) {
+      var char = input.codeUnitAt(start);
+      if (expectedPadding == 3) {
+        if (char == _paddingChar) {
+          expectedPadding -= 3;
+          start++;
+          break;
+        }
+        if (char == _char_percent) {
+          expectedPadding--;
+          start++;
+          if (start == end) break;
+          char = input.codeUnitAt(start);
+        } else {
+          break;
+        }
+      }
+      // Partial padding means we have seen part of a "%3D" escape.
+      var expectedPartialPadding = expectedPadding;
+      if (expectedPartialPadding > 3) expectedPartialPadding -= 3;
+      if (expectedPartialPadding == 2) {
+        // Expects '3'
+        if (char != _char_3) break;
+        start++;
+        expectedPadding--;
+        if (start == end) break;
+        char = input.codeUnitAt(start);
+      }
+      // Expects 'D' or 'd'.
+      if ((char | 0x20) != _char_d) break;
+      start++;
+      expectedPadding--;
+      if (start == end) break;
+    }
+    if (start != end) {
+      throw FormatException("Invalid padding character", input, start);
+    }
+    return _encodePaddingState(expectedPadding);
+  }
+}
+
+class _Base64DecoderSink extends StringConversionSinkBase {
+  /// Output sink
+  final Sink<List<int>> _sink;
+  final _Base64Decoder _decoder = _Base64Decoder();
+
+  _Base64DecoderSink(this._sink);
+
+  void add(String string) {
+    if (string.isEmpty) return;
+    var buffer = _decoder.decode(string, 0, string.length);
+    if (buffer != null) _sink.add(buffer);
+  }
+
+  void close() {
+    _decoder.close(null, null);
+    _sink.close();
+  }
+
+  void addSlice(String string, int start, int end, bool isLast) {
+    end = RangeError.checkValidRange(start, end, string.length);
+    if (start == end) return;
+    var buffer = _decoder.decode(string, start, end);
+    if (buffer != null) _sink.add(buffer);
+    if (isLast) {
+      _decoder.close(string, end);
+      _sink.close();
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/convert/byte_conversion.dart b/sdk_nnbd/lib/convert/byte_conversion.dart
new file mode 100644
index 0000000..3d52d78
--- /dev/null
+++ b/sdk_nnbd/lib/convert/byte_conversion.dart
@@ -0,0 +1,109 @@
+// 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 dart.convert;
+
+/// The [ByteConversionSink] provides an interface for converters to
+/// efficiently transmit byte data.
+///
+/// Instead of limiting the interface to one non-chunked list of bytes it
+/// accepts its input in chunks (themselves being lists of bytes).
+///
+/// This abstract class will likely get more methods over time. Implementers are
+/// urged to extend or mix in [ByteConversionSinkBase] to ensure that their
+/// class covers the newly added methods.
+abstract class ByteConversionSink extends ChunkedConversionSink<List<int>> {
+  ByteConversionSink();
+  factory ByteConversionSink.withCallback(
+      void callback(List<int> accumulated)) = _ByteCallbackSink;
+  factory ByteConversionSink.from(Sink<List<int>> sink) = _ByteAdapterSink;
+
+  /// Adds the next [chunk] to `this`.
+  ///
+  /// Adds the bytes defined by [start] and [end]-exclusive to `this`.
+  ///
+  /// If [isLast] is `true` closes `this`.
+  ///
+  /// Contrary to `add` the given [chunk] must not be held onto. Once the method
+  /// returns, it is safe to overwrite the data in it.
+  void addSlice(List<int> chunk, int start, int end, bool isLast);
+
+  // TODO(floitsch): add more methods:
+  // - iterateBytes.
+}
+
+/// This class provides a base-class for converters that need to accept byte
+/// inputs.
+abstract class ByteConversionSinkBase extends ByteConversionSink {
+  void add(List<int> chunk);
+  void close();
+
+  void addSlice(List<int> chunk, int start, int end, bool isLast) {
+    add(chunk.sublist(start, end));
+    if (isLast) close();
+  }
+}
+
+/// This class adapts a simple [Sink] to a [ByteConversionSink].
+///
+/// All additional methods of the [ByteConversionSink] (compared to the
+/// ChunkedConversionSink) are redirected to the `add` method.
+class _ByteAdapterSink extends ByteConversionSinkBase {
+  final Sink<List<int>> _sink;
+
+  _ByteAdapterSink(this._sink);
+
+  void add(List<int> chunk) {
+    _sink.add(chunk);
+  }
+
+  void close() {
+    _sink.close();
+  }
+}
+
+/// This class accumulates all chunks into one list of bytes
+/// and invokes a callback when the sink is closed.
+///
+/// This class can be used to terminate a chunked conversion.
+class _ByteCallbackSink extends ByteConversionSinkBase {
+  static const _INITIAL_BUFFER_SIZE = 1024;
+
+  final void Function(List<int>) _callback;
+  List<int> _buffer = Uint8List(_INITIAL_BUFFER_SIZE);
+  int _bufferIndex = 0;
+
+  _ByteCallbackSink(void callback(List<int> accumulated))
+      : _callback = callback;
+
+  void add(Iterable<int> chunk) {
+    var freeCount = _buffer.length - _bufferIndex;
+    if (chunk.length > freeCount) {
+      // Grow the buffer.
+      var oldLength = _buffer.length;
+      var newLength = _roundToPowerOf2(chunk.length + oldLength) * 2;
+      var grown = Uint8List(newLength);
+      grown.setRange(0, _buffer.length, _buffer);
+      _buffer = grown;
+    }
+    _buffer.setRange(_bufferIndex, _bufferIndex + chunk.length, chunk);
+    _bufferIndex += chunk.length;
+  }
+
+  static int _roundToPowerOf2(int v) {
+    assert(v > 0);
+    v--;
+    v |= v >> 1;
+    v |= v >> 2;
+    v |= v >> 4;
+    v |= v >> 8;
+    v |= v >> 16;
+    v++;
+    return v;
+  }
+
+  void close() {
+    _callback(_buffer.sublist(0, _bufferIndex));
+  }
+}
diff --git a/sdk_nnbd/lib/convert/chunked_conversion.dart b/sdk_nnbd/lib/convert/chunked_conversion.dart
new file mode 100644
index 0000000..e946f97
--- /dev/null
+++ b/sdk_nnbd/lib/convert/chunked_conversion.dart
@@ -0,0 +1,82 @@
+// 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 dart.convert;
+
+/// A [ChunkedConversionSink] is used to transmit data more efficiently between
+/// two converters during chunked conversions.
+///
+/// The basic `ChunkedConversionSink` is just a [Sink], and converters should
+/// work with a plain `Sink`, but may work more efficiently with certain
+/// specialized types of `ChunkedConversionSink`.
+///
+/// It is recommended that implementations of `ChunkedConversionSink` extend
+/// this class, to inherit any further methods that may be added to the class.
+abstract class ChunkedConversionSink<T> implements Sink<T> {
+  ChunkedConversionSink();
+  factory ChunkedConversionSink.withCallback(
+      void callback(List<T> accumulated)) = _SimpleCallbackSink<T>;
+
+  /// Adds chunked data to this sink.
+  ///
+  /// This method is also used when converters are used as [StreamTransformer]s.
+  void add(T chunk);
+
+  /// Closes the sink.
+  ///
+  /// This signals the end of the chunked conversion. This method is called
+  /// when converters are used as [StreamTransformer]'s.
+  void close();
+}
+
+/// This class accumulates all chunks and invokes a callback with a list of
+/// the chunks when the sink is closed.
+///
+/// This class can be used to terminate a chunked conversion.
+class _SimpleCallbackSink<T> extends ChunkedConversionSink<T> {
+  final void Function(List<T>) _callback;
+  final List<T> _accumulated = <T>[];
+
+  _SimpleCallbackSink(this._callback);
+
+  void add(T chunk) {
+    _accumulated.add(chunk);
+  }
+
+  void close() {
+    _callback(_accumulated);
+  }
+}
+
+/// This class implements the logic for a chunked conversion as a
+/// stream transformer.
+///
+/// It is used as strategy in the [EventTransformStream].
+///
+/// It also implements the [ChunkedConversionSink] interface so that it
+/// can be used as output sink in a chunked conversion.
+class _ConverterStreamEventSink<S, T> implements EventSink<S> {
+  /// The output sink for the converter.
+  final EventSink<T> _eventSink;
+
+  /// The input sink for new data. All data that is received with
+  /// [handleData] is added into this sink.
+  final Sink<S> _chunkedSink;
+
+  _ConverterStreamEventSink(Converter<S, T> converter, EventSink<T> sink)
+      : _eventSink = sink,
+        _chunkedSink = converter.startChunkedConversion(sink);
+
+  void add(S o) {
+    _chunkedSink.add(o);
+  }
+
+  void addError(Object error, [StackTrace stackTrace]) {
+    _eventSink.addError(error, stackTrace);
+  }
+
+  void close() {
+    _chunkedSink.close();
+  }
+}
diff --git a/sdk_nnbd/lib/convert/codec.dart b/sdk_nnbd/lib/convert/codec.dart
new file mode 100644
index 0000000..38e4a3c
--- /dev/null
+++ b/sdk_nnbd/lib/convert/codec.dart
@@ -0,0 +1,97 @@
+// 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 dart.convert;
+
+/// A [Codec] encodes and (if supported) decodes data.
+///
+/// Codecs can be fused. For example fusing [json] and [utf8] produces
+/// an encoder that can convert Json objects directly to bytes, or can decode
+/// bytes directly to json objects.
+///
+/// Fused codecs generally attempt to optimize the operations and can be faster
+/// than executing each step of an encoding separately.
+abstract class Codec<S, T> {
+  const Codec();
+
+  /// Encodes [input].
+  ///
+  /// The input is encoded as if by `encoder.convert`.
+  T encode(S input) => encoder.convert(input);
+
+  /// Decodes [encoded] data.
+  ///
+  /// The input is decoded as if by `decoder.convert`.
+  S decode(T encoded) => decoder.convert(encoded);
+
+  /// Returns the encoder from [S] to [T].
+  ///
+  /// It may be stateful and should not be reused.
+  Converter<S, T> get encoder;
+
+  /// Returns the decoder of `this`, converting from [T] to [S].
+  ///
+  /// It may be stateful and should not be reused.
+  Converter<T, S> get decoder;
+
+  /// Fuses `this` with `other`.
+  ///
+  /// When encoding, the resulting codec encodes with `this` before
+  /// encoding with [other].
+  ///
+  /// When decoding, the resulting codec decodes with [other] before decoding
+  /// with `this`.
+  ///
+  /// In some cases one needs to use the [inverted] codecs to be able to fuse
+  /// them correctly. That is, the output type of `this` ([T]) must match the
+  /// input type of the second codec [other].
+  ///
+  /// Examples:
+  /// ```dart
+  /// final jsonToBytes = json.fuse(utf8);
+  /// List<int> bytes = jsonToBytes.encode(["json-object"]);
+  /// var decoded = jsonToBytes.decode(bytes);
+  /// assert(decoded is List && decoded[0] == "json-object");
+  ///
+  /// var inverted = json.inverted;
+  /// var jsonIdentity = json.fuse(inverted);
+  /// var jsonObject = jsonIdentity.encode(["1", 2]);
+  /// assert(jsonObject is List && jsonObject[0] == "1" && jsonObject[1] == 2);
+  /// ```
+  // TODO(floitsch): use better example with line-splitter once that one is
+  // in this library.
+  Codec<S, R> fuse<R>(Codec<T, R> other) {
+    return _FusedCodec<S, T, R>(this, other);
+  }
+
+  /// Inverts `this`.
+  ///
+  /// The [encoder] and [decoder] of the resulting codec are swapped.
+  Codec<T, S> get inverted => _InvertedCodec<T, S>(this);
+}
+
+/// Fuses the given codecs.
+///
+/// In the non-chunked conversion simply invokes the non-chunked conversions in
+/// sequence.
+class _FusedCodec<S, M, T> extends Codec<S, T> {
+  final Codec<S, M> _first;
+  final Codec<M, T> _second;
+
+  Converter<S, T> get encoder => _first.encoder.fuse<T>(_second.encoder);
+  Converter<T, S> get decoder => _second.decoder.fuse<S>(_first.decoder);
+
+  _FusedCodec(this._first, this._second);
+}
+
+class _InvertedCodec<T, S> extends Codec<T, S> {
+  final Codec<S, T> _codec;
+
+  _InvertedCodec(Codec<S, T> codec) : _codec = codec;
+
+  Converter<T, S> get encoder => _codec.decoder;
+  Converter<S, T> get decoder => _codec.encoder;
+
+  Codec<S, T> get inverted => _codec;
+}
diff --git a/sdk_nnbd/lib/convert/convert.dart b/sdk_nnbd/lib/convert/convert.dart
new file mode 100644
index 0000000..6173782
--- /dev/null
+++ b/sdk_nnbd/lib/convert/convert.dart
@@ -0,0 +1,72 @@
+// 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.
+
+///
+/// Encoders and decoders for converting between different data representations,
+/// including JSON and UTF-8.
+///
+/// In addition to converters for common data representations, this library
+/// provides support for implementing converters in a way which makes them easy to
+/// chain and to use with streams.
+///
+/// To use this library in your code:
+///
+///     import 'dart:convert';
+///
+/// Two commonly used converters are the top-level instances of
+/// [JsonCodec] and [Utf8Codec], named [json] and [utf8], respectively.
+///
+/// JSON is a simple text format for representing
+/// structured objects and collections.
+/// The JSON encoder/decoder transforms between strings and
+/// object structures, such as lists and maps, using the JSON format.
+///
+/// UTF-8 is a common variable-width encoding that can represent
+/// every character in the Unicode character set.
+/// The UTF-8 encoder/decoder transforms between Strings and bytes.
+///
+/// Converters are often used with streams
+/// to transform the data that comes through the stream
+/// as it becomes available.
+/// The following code uses two converters.
+/// The first is a UTF-8 decoder, which converts the data from bytes to UTF-8
+/// as it's read from a file,
+/// The second is an instance of [LineSplitter],
+/// which splits the data on newline boundaries.
+///
+///     var lineNumber = 1;
+///     var stream = File('quotes.txt').openRead();
+///
+///     stream.transform(utf8.decoder)
+///           .transform(const LineSplitter())
+///           .listen((line) {
+///             if (showLineNumbers) {
+///               stdout.write('${lineNumber++} ');
+///             }
+///             stdout.writeln(line);
+///           });
+///
+/// See the documentation for the [Codec] and [Converter] classes
+/// for information about creating your own converters.
+///
+/// {@category Core}
+library dart.convert;
+
+import 'dart:async';
+import 'dart:typed_data';
+import 'dart:_internal' show CastConverter, parseHexByte;
+
+part 'ascii.dart';
+part 'base64.dart';
+part 'byte_conversion.dart';
+part 'chunked_conversion.dart';
+part 'codec.dart';
+part 'converter.dart';
+part 'encoding.dart';
+part 'html_escape.dart';
+part 'json.dart';
+part 'latin1.dart';
+part 'line_splitter.dart';
+part 'string_conversion.dart';
+part 'utf.dart';
diff --git a/sdk_nnbd/lib/convert/convert_sources.gni b/sdk_nnbd/lib/convert/convert_sources.gni
new file mode 100644
index 0000000..ad79649
--- /dev/null
+++ b/sdk_nnbd/lib/convert/convert_sources.gni
@@ -0,0 +1,23 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for 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 file contains all sources for the dart:convert library.
+convert_sdk_sources = [
+  "convert.dart",
+
+  # The above file needs to be first as it lists the parts below.
+  "ascii.dart",
+  "base64.dart",
+  "byte_conversion.dart",
+  "chunked_conversion.dart",
+  "codec.dart",
+  "converter.dart",
+  "encoding.dart",
+  "html_escape.dart",
+  "json.dart",
+  "latin1.dart",
+  "line_splitter.dart",
+  "string_conversion.dart",
+  "utf.dart",
+]
diff --git a/sdk_nnbd/lib/convert/converter.dart b/sdk_nnbd/lib/convert/converter.dart
new file mode 100644
index 0000000..2167933
--- /dev/null
+++ b/sdk_nnbd/lib/convert/converter.dart
@@ -0,0 +1,72 @@
+// 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 dart.convert;
+
+/// A [Converter] converts data from one representation into another.
+///
+/// It is recommended that implementations of `Converter` extend this class,
+/// to inherit any further methods that may be added to the class.
+abstract class Converter<S, T> extends StreamTransformerBase<S, T> {
+  const Converter();
+
+  /// Adapts [source] to be a `Converter<TS, TT>`.
+  ///
+  /// This allows [source] to be used at the new type, but at run-time it
+  /// must satisfy the requirements of both the new type and its original type.
+  ///
+  /// Conversion input must be both [SS] and [TS] and the output created by
+  /// [source] for those input must be both [ST] and [TT].
+  static Converter<TS, TT> castFrom<SS, ST, TS, TT>(Converter<SS, ST> source) =>
+      CastConverter<SS, ST, TS, TT>(source);
+
+  /// Converts [input] and returns the result of the conversion.
+  T convert(S input);
+
+  /// Fuses `this` with [other].
+  ///
+  /// Encoding with the resulting converter is equivalent to converting with
+  /// `this` before converting with `other`.
+  Converter<S, TT> fuse<TT>(Converter<T, TT> other) {
+    return _FusedConverter<S, T, TT>(this, other);
+  }
+
+  /// Starts a chunked conversion.
+  ///
+  /// The returned sink serves as input for the long-running conversion. The
+  /// given [sink] serves as output.
+  Sink<S> startChunkedConversion(Sink<T> sink) {
+    throw UnsupportedError(
+        "This converter does not support chunked conversions: $this");
+  }
+
+  Stream<T> bind(Stream<S> stream) {
+    return Stream<T>.eventTransformed(
+        stream, (EventSink sink) => _ConverterStreamEventSink(this, sink));
+  }
+
+  /// Provides a `Converter<RS, RT>` view of this stream transformer.
+  ///
+  /// The resulting transformer will check at run-time that all conversion
+  /// inputs are actually instances of [S],
+  /// and it will check that all conversion output produced by this converter
+  /// are actually instances of [RT].
+  Converter<RS, RT> cast<RS, RT>() => Converter.castFrom<S, T, RS, RT>(this);
+}
+
+/// Fuses two converters.
+///
+/// For a non-chunked conversion converts the input in sequence.
+class _FusedConverter<S, M, T> extends Converter<S, T> {
+  final Converter<S, M> _first;
+  final Converter<M, T> _second;
+
+  _FusedConverter(this._first, this._second);
+
+  T convert(S input) => _second.convert(_first.convert(input));
+
+  Sink<S> startChunkedConversion(Sink<T> sink) {
+    return _first.startChunkedConversion(_second.startChunkedConversion(sink));
+  }
+}
diff --git a/sdk_nnbd/lib/convert/encoding.dart b/sdk_nnbd/lib/convert/encoding.dart
new file mode 100644
index 0000000..7ce8ec3
--- /dev/null
+++ b/sdk_nnbd/lib/convert/encoding.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart.convert;
+
+/// Open-ended Encoding enum.
+abstract class Encoding extends Codec<String, List<int>> {
+  const Encoding();
+
+  /// Returns the encoder from `String` to `List<int>`.
+  ///
+  /// It may be stateful and should not be reused.
+  Converter<String, List<int>> get encoder;
+
+  /// Returns the decoder of `this`, converting from `List<int>` to `String`.
+  ///
+  /// It may be stateful and should not be reused.
+  Converter<List<int>, String> get decoder;
+
+  Future<String> decodeStream(Stream<List<int>> byteStream) {
+    return decoder
+        .bind(byteStream)
+        .fold(StringBuffer(),
+            (StringBuffer buffer, String string) => buffer..write(string))
+        .then((StringBuffer buffer) => buffer.toString());
+  }
+
+  /// Name of the encoding.
+  ///
+  /// If the encoding is standardized, this is the lower-case version of one of
+  /// the IANA official names for the character set (see
+  /// http://www.iana.org/assignments/character-sets/character-sets.xml)
+  String get name;
+
+  // All aliases (in lowercase) of supported encoding from
+  // http://www.iana.org/assignments/character-sets/character-sets.xml.
+  static final Map<String, Encoding> _nameToEncoding = <String, Encoding>{
+    // ISO_8859-1:1987.
+    "iso_8859-1:1987": latin1,
+    "iso-ir-100": latin1,
+    "iso_8859-1": latin1,
+    "iso-8859-1": latin1,
+    "latin1": latin1,
+    "l1": latin1,
+    "ibm819": latin1,
+    "cp819": latin1,
+    "csisolatin1": latin1,
+
+    // US-ASCII.
+    "iso-ir-6": ascii,
+    "ansi_x3.4-1968": ascii,
+    "ansi_x3.4-1986": ascii,
+    "iso_646.irv:1991": ascii,
+    "iso646-us": ascii,
+    "us-ascii": ascii,
+    "us": ascii,
+    "ibm367": ascii,
+    "cp367": ascii,
+    "csascii": ascii,
+    "ascii": ascii, // This is not in the IANA official names.
+
+    // UTF-8.
+    "csutf8": utf8,
+    "utf-8": utf8
+  };
+
+  /// Gets an [Encoding] object from the name of the character set
+  /// name. The names used are the IANA official names for the
+  /// character set (see
+  /// http://www.iana.org/assignments/character-sets/character-sets.xml).
+  ///
+  /// The [name] passed is case insensitive.
+  ///
+  /// If character set is not supported [:null:] is returned.
+  static Encoding getByName(String name) {
+    if (name == null) return null;
+    name = name.toLowerCase();
+    return _nameToEncoding[name];
+  }
+}
diff --git a/sdk_nnbd/lib/convert/html_escape.dart b/sdk_nnbd/lib/convert/html_escape.dart
new file mode 100644
index 0000000..a0a7119
--- /dev/null
+++ b/sdk_nnbd/lib/convert/html_escape.dart
@@ -0,0 +1,223 @@
+// 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 dart.convert;
+
+/// A `String` converter that converts characters to HTML entities.
+///
+/// This is intended to sanitize text before inserting the text into an HTML
+/// document. Characters that are meaningful in HTML are converted to
+/// HTML entities (like `&amp;` for `&`).
+///
+/// The general converter escapes all characters that are meaningful in HTML
+/// attributes or normal element context. Elements with special content types
+/// (like CSS or JavaScript) may need a more specialized escaping that
+/// understands that content type.
+///
+/// If the context where the text will be inserted is known in more detail,
+/// it's possible to omit escaping some characters (like quotes when not
+/// inside an attribute value).
+///
+/// The escaped text should only be used inside quoted HTML attributes values
+/// or as text content of a normal element. Using the escaped text inside a
+/// tag, but not inside a quoted attribute value, is still dangerous.
+const HtmlEscape htmlEscape = HtmlEscape();
+
+/// HTML escape modes.
+///
+/// Allows specifying a mode for HTML escaping that depend on the context
+/// where the escaped result is going to be used.
+/// The relevant contexts are:
+///
+/// * as text content of an HTML element.
+/// * as value of a (single- or double-) quoted attribute value.
+///
+/// All modes require escaping of `&` (ampersand) characters, and may
+/// enable escaping of more characters.
+///
+/// Custom escape modes can be created using the [HtmlEscapeMode.HtmlEscapeMode]
+/// constructor.
+class HtmlEscapeMode {
+  final String _name;
+
+  /// Whether to escape '<' and '>'.
+  final bool escapeLtGt;
+
+  /// Whether to escape '"' (quote).
+  final bool escapeQuot;
+
+  /// Whether to escape "'" (apostrophe).
+  final bool escapeApos;
+
+  /// Whether to escape "/" (forward slash, solidus).
+  ///
+  /// Escaping a slash is recommended to avoid cross-site scripting attacks by
+  /// [the Open Web Application Security Project](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.231_-_HTML_Escape_Before_Inserting_Untrusted_Data_into_HTML_Element_Content)
+  final bool escapeSlash;
+
+  /// Default escaping mode which escape all characters.
+  ///
+  /// The result of such an escaping is usable both in element content and
+  /// in any attribute value.
+  ///
+  /// The escaping only works for elements with normal HTML content,
+  /// and not for, for example, script or style element content,
+  /// which require escapes matching their particular content syntax.
+  static const HtmlEscapeMode unknown =
+      HtmlEscapeMode._('unknown', true, true, true, true);
+
+  /// Escaping mode for text going into double-quoted HTML attribute values.
+  ///
+  /// The result should not be used as the content of an unquoted
+  /// or single-quoted attribute value.
+  ///
+  /// Escapes double quotes (`"`) but not single quotes (`'`),
+  /// and escapes `<` and `>` characters because they are not allowed
+  /// in strict XHTML attributes
+  static const HtmlEscapeMode attribute =
+      HtmlEscapeMode._('attribute', true, true, false, false);
+
+  /// Escaping mode for text going into single-quoted HTML attribute values.
+  ///
+  /// The result should not be used as the content of an unquoted
+  /// or double-quoted attribute value.
+  ///
+  /// Escapes single quotes (`'`) but not double quotes (`"`),
+  /// and escapes `<` and `>` characters because they are not allowed
+  /// in strict XHTML attributes
+  static const HtmlEscapeMode sqAttribute =
+      HtmlEscapeMode._('attribute', true, false, true, false);
+
+  /// Escaping mode for text going into HTML element content.
+  ///
+  /// The escaping only works for elements with normal HTML content,
+  /// and not for, for example, script or style element content,
+  /// which require escapes matching their particular content syntax.
+  ///
+  /// Escapes `<` and `>` characters.
+  static const HtmlEscapeMode element =
+      HtmlEscapeMode._('element', true, false, false, false);
+
+  const HtmlEscapeMode._(this._name, this.escapeLtGt, this.escapeQuot,
+      this.escapeApos, this.escapeSlash);
+
+  /// Create a custom escaping mode.
+  ///
+  /// All modes escape `&`.
+  /// The mode can further be set to escape `<` and `>` ([escapeLtGt]),
+  /// `"` ([escapeQuot]), `'` ([escapeApos]), and/or `/` ([escapeSlash]).
+  const HtmlEscapeMode(
+      {String name = "custom",
+      this.escapeLtGt = false,
+      this.escapeQuot = false,
+      this.escapeApos = false,
+      this.escapeSlash = false})
+      : _name = name;
+
+  String toString() => _name;
+}
+
+/// Converter which escapes characters with special meaning in HTML.
+///
+/// The converter finds characters that are significant in HTML source and
+/// replaces them with corresponding HTML entities.
+///
+/// The characters that need escaping in HTML are:
+///
+/// * `&` (ampersand) always need to be escaped.
+/// * `<` (less than) and '>' (greater than) when inside an element.
+/// * `"` (quote) when inside a double-quoted attribute value.
+/// * `'` (apostrophe) when inside a single-quoted attribute value.
+///       Apostrophe is escaped as `&#39;` instead of `&apos;` since
+///       not all browsers understand `&apos;`.
+/// * `/` (slash) is recommended to be escaped because it may be used
+///       to terminate an element in some HTML dialects.
+///
+/// Escaping `>` (greater than) isn't necessary, but the result is often
+/// found to be easier to read if greater-than is also escaped whenever
+/// less-than is.
+class HtmlEscape extends Converter<String, String> {
+  /// The [HtmlEscapeMode] used by the converter.
+  final HtmlEscapeMode mode;
+
+  /// Create converter that escapes HTML characters.
+  ///
+  /// If [mode] is provided as either [HtmlEscapeMode.attribute] or
+  /// [HtmlEscapeMode.element], only the corresponding subset of HTML
+  /// characters are escaped.
+  /// The default is to escape all HTML characters.
+  const HtmlEscape([this.mode = HtmlEscapeMode.unknown]);
+
+  String convert(String text) {
+    var val = _convert(text, 0, text.length);
+    return val == null ? text : val;
+  }
+
+  /// Converts the substring of text from start to end.
+  ///
+  /// Returns `null` if no changes were necessary, otherwise returns
+  /// the converted string.
+  String _convert(String text, int start, int end) {
+    StringBuffer result;
+    for (var i = start; i < end; i++) {
+      var ch = text[i];
+      String replacement;
+      switch (ch) {
+        case '&':
+          replacement = '&amp;';
+          break;
+        case '"':
+          if (mode.escapeQuot) replacement = '&quot;';
+          break;
+        case "'":
+          if (mode.escapeApos) replacement = '&#39;';
+          break;
+        case '<':
+          if (mode.escapeLtGt) replacement = '&lt;';
+          break;
+        case '>':
+          if (mode.escapeLtGt) replacement = '&gt;';
+          break;
+        case '/':
+          if (mode.escapeSlash) replacement = '&#47;';
+          break;
+      }
+      if (replacement != null) {
+        result ??= StringBuffer();
+        if (i > start) result.write(text.substring(start, i));
+        result.write(replacement);
+        start = i + 1;
+      }
+    }
+    if (result == null) return null;
+    if (end > start) result.write(text.substring(start, end));
+    return result.toString();
+  }
+
+  StringConversionSink startChunkedConversion(Sink<String> sink) {
+    return _HtmlEscapeSink(this,
+        sink is StringConversionSink ? sink : StringConversionSink.from(sink));
+  }
+}
+
+class _HtmlEscapeSink extends StringConversionSinkBase {
+  final HtmlEscape _escape;
+  final StringConversionSink _sink;
+
+  _HtmlEscapeSink(this._escape, this._sink);
+
+  void addSlice(String chunk, int start, int end, bool isLast) {
+    var val = _escape._convert(chunk, start, end);
+    if (val == null) {
+      _sink.addSlice(chunk, start, end, isLast);
+    } else {
+      _sink.add(val);
+      if (isLast) _sink.close();
+    }
+  }
+
+  void close() {
+    _sink.close();
+  }
+}
diff --git a/sdk_nnbd/lib/convert/json.dart b/sdk_nnbd/lib/convert/json.dart
new file mode 100644
index 0000000..5746e52
--- /dev/null
+++ b/sdk_nnbd/lib/convert/json.dart
@@ -0,0 +1,1034 @@
+// 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 dart.convert;
+
+/// Error thrown by JSON serialization if an object cannot be serialized.
+///
+/// The [unsupportedObject] field holds that object that failed to be serialized.
+///
+/// If an object isn't directly serializable, the serializer calls the `toJson`
+/// method on the object. If that call fails, the error will be stored in the
+/// [cause] field. If the call returns an object that isn't directly
+/// serializable, the [cause] is null.
+class JsonUnsupportedObjectError extends Error {
+  /// The object that could not be serialized.
+  final Object unsupportedObject;
+
+  /// The exception thrown when trying to convert the object.
+  final Object cause;
+
+  /// The partial result of the conversion, up until the error happened.
+  ///
+  /// May be null.
+  final String partialResult;
+
+  JsonUnsupportedObjectError(this.unsupportedObject,
+      {this.cause, this.partialResult});
+
+  String toString() {
+    var safeString = Error.safeToString(unsupportedObject);
+    String prefix;
+    if (cause != null) {
+      prefix = "Converting object to an encodable object failed:";
+    } else {
+      prefix = "Converting object did not return an encodable object:";
+    }
+    return "$prefix $safeString";
+  }
+}
+
+/// Reports that an object could not be stringified due to cyclic references.
+///
+/// An object that references itself cannot be serialized by
+/// [JsonCodec.encode]/[JsonEncoder.convert].
+/// When the cycle is detected, a [JsonCyclicError] is thrown.
+class JsonCyclicError extends JsonUnsupportedObjectError {
+  /// The first object that was detected as part of a cycle.
+  JsonCyclicError(Object object) : super(object);
+  String toString() => "Cyclic error in JSON stringify";
+}
+
+/// An instance of the default implementation of the [JsonCodec].
+///
+/// This instance provides a convenient access to the most common JSON
+/// use cases.
+///
+/// Examples:
+///
+///     var encoded = json.encode([1, 2, { "a": null }]);
+///     var decoded = json.decode('["foo", { "bar": 499 }]');
+///
+/// The top-level [jsonEncode] and [jsonDecode] functions may be used instead if
+/// a local variable shadows the [json] constant.
+const JsonCodec json = JsonCodec();
+
+/// Converts [value] to a JSON string.
+///
+/// If value contains objects that are not directly encodable to a JSON
+/// string (a value that is not a number, boolean, string, null, list or a map
+/// with string keys), the [toEncodable] function is used to convert it to an
+/// object that must be directly encodable.
+///
+/// If [toEncodable] is omitted, it defaults to a function that returns the
+/// result of calling `.toJson()` on the unencodable object.
+///
+/// Shorthand for [json.encode]. Useful if a local variable shadows the global
+/// [json] constant.
+String jsonEncode(Object object, {Object toEncodable(Object nonEncodable)}) =>
+    json.encode(object, toEncodable: toEncodable);
+
+/// Parses the string and returns the resulting Json object.
+///
+/// The optional [reviver] function is called once for each object or list
+/// property that has been parsed during decoding. The `key` argument is either
+/// the integer list index for a list property, the string map key for object
+/// properties, or `null` for the final result.
+///
+/// The default [reviver] (when not provided) is the identity function.
+///
+/// Shorthand for [json.decode]. Useful if a local variable shadows the global
+/// [json] constant.
+dynamic jsonDecode(String source, {Object reviver(Object key, Object value)}) =>
+    json.decode(source, reviver: reviver);
+
+/// A [JsonCodec] encodes JSON objects to strings and decodes strings to
+/// JSON objects.
+///
+/// Examples:
+///
+///     var encoded = json.encode([1, 2, { "a": null }]);
+///     var decoded = json.decode('["foo", { "bar": 499 }]');
+class JsonCodec extends Codec<Object, String> {
+  final Function(Object key, Object value) _reviver;
+  final Function(dynamic) _toEncodable;
+
+  /// Creates a `JsonCodec` with the given reviver and encoding function.
+  ///
+  /// The [reviver] function is called during decoding. It is invoked once for
+  /// each object or list property that has been parsed.
+  /// The `key` argument is either the integer list index for a list property,
+  /// the string map key for object properties, or `null` for the final result.
+  ///
+  /// If [reviver] is omitted, it defaults to returning the value argument.
+  ///
+  /// The [toEncodable] function is used during encoding. It is invoked for
+  /// values that are not directly encodable to a string (a value that is not a
+  /// number, boolean, string, null, list or a map with string keys). The
+  /// function must return an object that is directly encodable. The elements of
+  /// a returned list and values of a returned map do not need to be directly
+  /// encodable, and if they aren't, `toEncodable` will be used on them as well.
+  /// Please notice that it is possible to cause an infinite recursive regress
+  /// in this way, by effectively creating an infinite data structure through
+  /// repeated call to `toEncodable`.
+  ///
+  /// If [toEncodable] is omitted, it defaults to a function that returns the
+  /// result of calling `.toJson()` on the unencodable object.
+  const JsonCodec({reviver(Object key, Object value), toEncodable(var object)})
+      : _reviver = reviver,
+        _toEncodable = toEncodable;
+
+  /// Creates a `JsonCodec` with the given reviver.
+  ///
+  /// The [reviver] function is called once for each object or list property
+  /// that has been parsed during decoding. The `key` argument is either the
+  /// integer list index for a list property, the string map key for object
+  /// properties, or `null` for the final result.
+  JsonCodec.withReviver(reviver(Object key, Object value))
+      : this(reviver: reviver);
+
+  /// Parses the string and returns the resulting Json object.
+  ///
+  /// The optional [reviver] function is called once for each object or list
+  /// property that has been parsed during decoding. The `key` argument is either
+  /// the integer list index for a list property, the string map key for object
+  /// properties, or `null` for the final result.
+  ///
+  /// The default [reviver] (when not provided) is the identity function.
+  dynamic decode(String source, {reviver(Object key, Object value)}) {
+    reviver ??= _reviver;
+    if (reviver == null) return decoder.convert(source);
+    return JsonDecoder(reviver).convert(source);
+  }
+
+  /// Converts [value] to a JSON string.
+  ///
+  /// If value contains objects that are not directly encodable to a JSON
+  /// string (a value that is not a number, boolean, string, null, list or a map
+  /// with string keys), the [toEncodable] function is used to convert it to an
+  /// object that must be directly encodable.
+  ///
+  /// If [toEncodable] is omitted, it defaults to a function that returns the
+  /// result of calling `.toJson()` on the unencodable object.
+  String encode(Object value, {toEncodable(object)}) {
+    toEncodable ??= _toEncodable;
+    if (toEncodable == null) return encoder.convert(value);
+    return JsonEncoder(toEncodable).convert(value);
+  }
+
+  JsonEncoder get encoder {
+    if (_toEncodable == null) return const JsonEncoder();
+    return JsonEncoder(_toEncodable);
+  }
+
+  JsonDecoder get decoder {
+    if (_reviver == null) return const JsonDecoder();
+    return JsonDecoder(_reviver);
+  }
+}
+
+/// This class converts JSON objects to strings.
+class JsonEncoder extends Converter<Object, String> {
+  /// The string used for indention.
+  ///
+  /// When generating multi-line output, this string is inserted once at the
+  /// beginning of each indented line for each level of indentation.
+  ///
+  /// If `null`, the output is encoded as a single line.
+  final String indent;
+
+  /// Function called on non-encodable objects to return a replacement
+  /// encodable object that will be encoded in the orignal's place.
+  final Function(dynamic) _toEncodable;
+
+  /// Creates a JSON encoder.
+  ///
+  /// The JSON encoder handles numbers, strings, booleans, null, lists and
+  /// maps with string keys directly.
+  ///
+  /// Any other object is attempted converted by [toEncodable] to an
+  /// object that is of one of the convertible types.
+  ///
+  /// If [toEncodable] is omitted, it defaults to calling `.toJson()` on
+  /// the object.
+  const JsonEncoder([toEncodable(object)])
+      : indent = null,
+        _toEncodable = toEncodable;
+
+  /// Creates a JSON encoder that creates multi-line JSON.
+  ///
+  /// The encoding of elements of lists and maps are indented and put on separate
+  /// lines. The [indent] string is prepended to these elements, once for each
+  /// level of indentation.
+  ///
+  /// If [indent] is `null`, the output is encoded as a single line.
+  ///
+  /// The JSON encoder handles numbers, strings, booleans, null, lists and
+  /// maps with string keys directly.
+  ///
+  /// Any other object is attempted converted by [toEncodable] to an
+  /// object that is of one of the convertible types.
+  ///
+  /// If [toEncodable] is omitted, it defaults to calling `.toJson()` on
+  /// the object.
+  const JsonEncoder.withIndent(this.indent, [toEncodable(object)])
+      : _toEncodable = toEncodable;
+
+  /// Converts [object] to a JSON [String].
+  ///
+  /// Directly serializable values are [num], [String], [bool], and [Null], as
+  /// well as some [List] and [Map] values. For [List], the elements must all be
+  /// serializable. For [Map], the keys must be [String] and the values must be
+  /// serializable.
+  ///
+  /// If a value of any other type is attempted to be serialized, the
+  /// `toEncodable` function provided in the constructor is called with the value
+  /// as argument. The result, which must be a directly serializable value, is
+  /// serialized instead of the original value.
+  ///
+  /// If the conversion throws, or returns a value that is not directly
+  /// serializable, a [JsonUnsupportedObjectError] exception is thrown.
+  /// If the call throws, the error is caught and stored in the
+  /// [JsonUnsupportedObjectError]'s [:cause:] field.
+  ///
+  /// If a [List] or [Map] contains a reference to itself, directly or through
+  /// other lists or maps, it cannot be serialized and a [JsonCyclicError] is
+  /// thrown.
+  ///
+  /// [object] should not change during serialization.
+  ///
+  /// If an object is serialized more than once, [convert] may cache the text
+  /// for it. In other words, if the content of an object changes after it is
+  /// first serialized, the new values may not be reflected in the result.
+  String convert(Object object) =>
+      _JsonStringStringifier.stringify(object, _toEncodable, indent);
+
+  /// Starts a chunked conversion.
+  ///
+  /// The converter works more efficiently if the given [sink] is a
+  /// [StringConversionSink].
+  ///
+  /// Returns a chunked-conversion sink that accepts at most one object. It is
+  /// an error to invoke `add` more than once on the returned sink.
+  ChunkedConversionSink<Object> startChunkedConversion(Sink<String> sink) {
+    if (sink is _Utf8EncoderSink) {
+      return _JsonUtf8EncoderSink(
+          sink._sink,
+          _toEncodable,
+          JsonUtf8Encoder._utf8Encode(indent),
+          JsonUtf8Encoder._defaultBufferSize);
+    }
+    return _JsonEncoderSink(
+        sink is StringConversionSink ? sink : StringConversionSink.from(sink),
+        _toEncodable,
+        indent);
+  }
+
+  // Override the base class's bind, to provide a better type.
+  Stream<String> bind(Stream<Object> stream) => super.bind(stream);
+
+  Converter<Object, T> fuse<T>(Converter<String, T> other) {
+    if (other is Utf8Encoder && T is List<int>) {
+      // The instance check guarantees that `T` is (a subtype of) List<int>,
+      // but the static type system doesn't know that, and so we cast.
+      // Cast through dynamic to keep the cast implicit for builds using
+      // unchecked implicit casts.
+      return JsonUtf8Encoder(indent, _toEncodable) as dynamic;
+    }
+    return super.fuse<T>(other);
+  }
+}
+
+/// Encoder that encodes a single object as a UTF-8 encoded JSON string.
+///
+/// This encoder works equivalently to first converting the object to
+/// a JSON string, and then UTF-8 encoding the string, but without
+/// creating an intermediate string.
+class JsonUtf8Encoder extends Converter<Object, List<int>> {
+  /// Default buffer size used by the JSON-to-UTF-8 encoder.
+  static const int _defaultBufferSize = 256;
+  @deprecated
+  static const int DEFAULT_BUFFER_SIZE = _defaultBufferSize;
+
+  /// Indentation used in pretty-print mode, `null` if not pretty.
+  final List<int> _indent;
+
+  /// Function called with each un-encodable object encountered.
+  final Function(dynamic) _toEncodable;
+
+  /// UTF-8 buffer size.
+  final int _bufferSize;
+
+  /// Create converter.
+  ///
+  /// If [indent] is non-`null`, the converter attempts to "pretty-print" the
+  /// JSON, and uses `indent` as the indentation. Otherwise the result has no
+  /// whitespace outside of string literals.
+  /// If `indent` contains characters that are not valid JSON whitespace
+  /// characters, the result will not be valid JSON. JSON whitespace characters
+  /// are space (U+0020), tab (U+0009), line feed (U+000a) and carriage return
+  /// (U+000d) ([ECMA
+  /// 404](http://www.ecma-international.org/publications/standards/Ecma-404.htm)).
+  ///
+  /// The [bufferSize] is the size of the internal buffers used to collect
+  /// UTF-8 code units.
+  /// If using [startChunkedConversion], it will be the size of the chunks.
+  ///
+  /// The JSON encoder handles numbers, strings, booleans, null, lists and maps
+  /// directly.
+  ///
+  /// Any other object is attempted converted by [toEncodable] to an object that
+  /// is of one of the convertible types.
+  ///
+  /// If [toEncodable] is omitted, it defaults to calling `.toJson()` on the
+  /// object.
+  JsonUtf8Encoder(
+      [String indent, toEncodable(object), int bufferSize = _defaultBufferSize])
+      : _indent = _utf8Encode(indent),
+        _toEncodable = toEncodable,
+        _bufferSize = bufferSize;
+
+  static List<int> _utf8Encode(String string) {
+    if (string == null) return null;
+    if (string.isEmpty) return Uint8List(0);
+    checkAscii:
+    {
+      for (var i = 0; i < string.length; i++) {
+        if (string.codeUnitAt(i) >= 0x80) break checkAscii;
+      }
+      return string.codeUnits;
+    }
+    return utf8.encode(string);
+  }
+
+  /// Convert [object] into UTF-8 encoded JSON.
+  List<int> convert(Object object) {
+    var bytes = <List<int>>[];
+    // The `stringify` function always converts into chunks.
+    // Collect the chunks into the `bytes` list, then combine them afterwards.
+    void addChunk(Uint8List chunk, int start, int end) {
+      if (start > 0 || end < chunk.length) {
+        var length = end - start;
+        chunk =
+            Uint8List.view(chunk.buffer, chunk.offsetInBytes + start, length);
+      }
+      bytes.add(chunk);
+    }
+
+    _JsonUtf8Stringifier.stringify(
+        object, _indent, _toEncodable, _bufferSize, addChunk);
+    if (bytes.length == 1) return bytes[0];
+    var length = 0;
+    for (var i = 0; i < bytes.length; i++) {
+      length += bytes[i].length;
+    }
+    var result = Uint8List(length);
+    for (var i = 0, offset = 0; i < bytes.length; i++) {
+      var byteList = bytes[i];
+      int end = offset + byteList.length;
+      result.setRange(offset, end, byteList);
+      offset = end;
+    }
+    return result;
+  }
+
+  /// Start a chunked conversion.
+  ///
+  /// Only one object can be passed into the returned sink.
+  ///
+  /// The argument [sink] will receive byte lists in sizes depending on the
+  /// `bufferSize` passed to the constructor when creating this encoder.
+  ChunkedConversionSink<Object> startChunkedConversion(Sink<List<int>> sink) {
+    ByteConversionSink byteSink;
+    if (sink is ByteConversionSink) {
+      byteSink = sink;
+    } else {
+      byteSink = ByteConversionSink.from(sink);
+    }
+    return _JsonUtf8EncoderSink(byteSink, _toEncodable, _indent, _bufferSize);
+  }
+
+  // Override the base class's bind, to provide a better type.
+  Stream<List<int>> bind(Stream<Object> stream) {
+    return super.bind(stream);
+  }
+}
+
+/// Implements the chunked conversion from object to its JSON representation.
+///
+/// The sink only accepts one value, but will produce output in a chunked way.
+class _JsonEncoderSink extends ChunkedConversionSink<Object> {
+  final String _indent;
+  final Function(dynamic) _toEncodable;
+  final StringConversionSink _sink;
+  bool _isDone = false;
+
+  _JsonEncoderSink(this._sink, this._toEncodable, this._indent);
+
+  /// Encodes the given object [o].
+  ///
+  /// It is an error to invoke this method more than once on any instance. While
+  /// this makes the input effectively non-chunked the output will be generated
+  /// in a chunked way.
+  void add(Object o) {
+    if (_isDone) {
+      throw StateError("Only one call to add allowed");
+    }
+    _isDone = true;
+    var stringSink = _sink.asStringSink();
+    _JsonStringStringifier.printOn(o, stringSink, _toEncodable, _indent);
+    stringSink.close();
+  }
+
+  void close() {/* do nothing */}
+}
+
+/// Sink returned when starting a chunked conversion from object to bytes.
+class _JsonUtf8EncoderSink extends ChunkedConversionSink<Object> {
+  /// The byte sink receiveing the encoded chunks.
+  final ByteConversionSink _sink;
+  final List<int> _indent;
+  final Function(dynamic) _toEncodable;
+  final int _bufferSize;
+  bool _isDone = false;
+  _JsonUtf8EncoderSink(
+      this._sink, this._toEncodable, this._indent, this._bufferSize);
+
+  /// Callback called for each slice of result bytes.
+  void _addChunk(Uint8List chunk, int start, int end) {
+    _sink.addSlice(chunk, start, end, false);
+  }
+
+  void add(Object object) {
+    if (_isDone) {
+      throw StateError("Only one call to add allowed");
+    }
+    _isDone = true;
+    _JsonUtf8Stringifier.stringify(
+        object, _indent, _toEncodable, _bufferSize, _addChunk);
+    _sink.close();
+  }
+
+  void close() {
+    if (!_isDone) {
+      _isDone = true;
+      _sink.close();
+    }
+  }
+}
+
+/// This class parses JSON strings and builds the corresponding objects.
+class JsonDecoder extends Converter<String, Object> {
+  final Function(Object key, Object value) _reviver;
+
+  /// Constructs a new JsonDecoder.
+  ///
+  /// The [reviver] may be `null`.
+  const JsonDecoder([reviver(Object key, Object value)]) : _reviver = reviver;
+
+  /// Converts the given JSON-string [input] to its corresponding object.
+  ///
+  /// Parsed JSON values are of the types [num], [String], [bool], [Null],
+  /// [List]s of parsed JSON values or [Map]s from [String] to parsed JSON
+  /// values.
+  ///
+  /// If `this` was initialized with a reviver, then the parsing operation
+  /// invokes the reviver on every object or list property that has been parsed.
+  /// The arguments are the property name ([String]) or list index ([int]), and
+  /// the value is the parsed value. The return value of the reviver is used as
+  /// the value of that property instead the parsed value.
+  ///
+  /// Throws [FormatException] if the input is not valid JSON text.
+  dynamic convert(String input) => _parseJson(input, _reviver);
+
+  /// Starts a conversion from a chunked JSON string to its corresponding object.
+  ///
+  /// The output [sink] receives exactly one decoded element through `add`.
+  external StringConversionSink startChunkedConversion(Sink<Object> sink);
+
+  // Override the base class's bind, to provide a better type.
+  Stream<Object> bind(Stream<String> stream) => super.bind(stream);
+}
+
+// Internal optimized JSON parsing implementation.
+external _parseJson(String source, reviver(key, value));
+
+// Implementation of encoder/stringifier.
+
+dynamic _defaultToEncodable(dynamic object) => object.toJson();
+
+/// JSON encoder that traverses an object structure and writes JSON source.
+///
+/// This is an abstract implementation that doesn't decide on the output
+/// format, but writes the JSON through abstract methods like [writeString].
+abstract class _JsonStringifier {
+  // Character code constants.
+  static const int backspace = 0x08;
+  static const int tab = 0x09;
+  static const int newline = 0x0a;
+  static const int carriageReturn = 0x0d;
+  static const int formFeed = 0x0c;
+  static const int quote = 0x22;
+  static const int char_0 = 0x30;
+  static const int backslash = 0x5c;
+  static const int char_b = 0x62;
+  static const int char_f = 0x66;
+  static const int char_n = 0x6e;
+  static const int char_r = 0x72;
+  static const int char_t = 0x74;
+  static const int char_u = 0x75;
+
+  /// List of objects currently being traversed. Used to detect cycles.
+  final List _seen = [];
+
+  /// Function called for each un-encodable object encountered.
+  final Function(dynamic) _toEncodable;
+
+  _JsonStringifier(toEncodable(o))
+      : _toEncodable = toEncodable ?? _defaultToEncodable;
+
+  String get _partialResult;
+
+  /// Append a string to the JSON output.
+  void writeString(String characters);
+
+  /// Append part of a string to the JSON output.
+  void writeStringSlice(String characters, int start, int end);
+
+  /// Append a single character, given by its code point, to the JSON output.
+  void writeCharCode(int charCode);
+
+  /// Write a number to the JSON output.
+  void writeNumber(num number);
+
+  // ('0' + x) or ('a' + x - 10)
+  static int hexDigit(int x) => x < 10 ? 48 + x : 87 + x;
+
+  /// Write, and suitably escape, a string's content as a JSON string literal.
+  void writeStringContent(String s) {
+    var offset = 0;
+    final length = s.length;
+    for (var i = 0; i < length; i++) {
+      var charCode = s.codeUnitAt(i);
+      if (charCode > backslash) continue;
+      if (charCode < 32) {
+        if (i > offset) writeStringSlice(s, offset, i);
+        offset = i + 1;
+        writeCharCode(backslash);
+        switch (charCode) {
+          case backspace:
+            writeCharCode(char_b);
+            break;
+          case tab:
+            writeCharCode(char_t);
+            break;
+          case newline:
+            writeCharCode(char_n);
+            break;
+          case formFeed:
+            writeCharCode(char_f);
+            break;
+          case carriageReturn:
+            writeCharCode(char_r);
+            break;
+          default:
+            writeCharCode(char_u);
+            writeCharCode(char_0);
+            writeCharCode(char_0);
+            writeCharCode(hexDigit((charCode >> 4) & 0xf));
+            writeCharCode(hexDigit(charCode & 0xf));
+            break;
+        }
+      } else if (charCode == quote || charCode == backslash) {
+        if (i > offset) writeStringSlice(s, offset, i);
+        offset = i + 1;
+        writeCharCode(backslash);
+        writeCharCode(charCode);
+      }
+    }
+    if (offset == 0) {
+      writeString(s);
+    } else if (offset < length) {
+      writeStringSlice(s, offset, length);
+    }
+  }
+
+  /// Check if an encountered object is already being traversed.
+  ///
+  /// Records the object if it isn't already seen. Should have a matching call to
+  /// [_removeSeen] when the object is no longer being traversed.
+  void _checkCycle(object) {
+    for (var i = 0; i < _seen.length; i++) {
+      if (identical(object, _seen[i])) {
+        throw JsonCyclicError(object);
+      }
+    }
+    _seen.add(object);
+  }
+
+  /// Remove [object] from the list of currently traversed objects.
+  ///
+  /// Should be called in the opposite order of the matching [_checkCycle]
+  /// calls.
+  void _removeSeen(object) {
+    assert(_seen.isNotEmpty);
+    assert(identical(_seen.last, object));
+    _seen.removeLast();
+  }
+
+  /// Write an object.
+  ///
+  /// If [object] isn't directly encodable, the [_toEncodable] function gets one
+  /// chance to return a replacement which is encodable.
+  void writeObject(object) {
+    // Tries stringifying object directly. If it's not a simple value, List or
+    // Map, call toJson() to get a custom representation and try serializing
+    // that.
+    if (writeJsonValue(object)) return;
+    _checkCycle(object);
+    try {
+      var customJson = _toEncodable(object);
+      if (!writeJsonValue(customJson)) {
+        throw JsonUnsupportedObjectError(object, partialResult: _partialResult);
+      }
+      _removeSeen(object);
+    } catch (e) {
+      throw JsonUnsupportedObjectError(object,
+          cause: e, partialResult: _partialResult);
+    }
+  }
+
+  /// Serialize a [num], [String], [bool], [Null], [List] or [Map] value.
+  ///
+  /// Returns true if the value is one of these types, and false if not.
+  /// If a value is both a [List] and a [Map], it's serialized as a [List].
+  bool writeJsonValue(object) {
+    if (object is num) {
+      if (!object.isFinite) return false;
+      writeNumber(object);
+      return true;
+    } else if (identical(object, true)) {
+      writeString('true');
+      return true;
+    } else if (identical(object, false)) {
+      writeString('false');
+      return true;
+    } else if (object == null) {
+      writeString('null');
+      return true;
+    } else if (object is String) {
+      writeString('"');
+      writeStringContent(object);
+      writeString('"');
+      return true;
+    } else if (object is List) {
+      _checkCycle(object);
+      writeList(object);
+      _removeSeen(object);
+      return true;
+    } else if (object is Map) {
+      _checkCycle(object);
+      // writeMap can fail if keys are not all strings.
+      var success = writeMap(object);
+      _removeSeen(object);
+      return success;
+    } else {
+      return false;
+    }
+  }
+
+  /// Serialize a [List].
+  void writeList(List list) {
+    writeString('[');
+    if (list.isNotEmpty) {
+      writeObject(list[0]);
+      for (var i = 1; i < list.length; i++) {
+        writeString(',');
+        writeObject(list[i]);
+      }
+    }
+    writeString(']');
+  }
+
+  /// Serialize a [Map].
+  bool writeMap(Map map) {
+    if (map.isEmpty) {
+      writeString("{}");
+      return true;
+    }
+    var keyValueList = List(map.length * 2);
+    var i = 0;
+    var allStringKeys = true;
+    map.forEach((key, value) {
+      if (key is! String) {
+        allStringKeys = false;
+      }
+      keyValueList[i++] = key;
+      keyValueList[i++] = value;
+    });
+    if (!allStringKeys) return false;
+    writeString('{');
+    var separator = '"';
+    for (var i = 0; i < keyValueList.length; i += 2) {
+      writeString(separator);
+      separator = ',"';
+      writeStringContent(keyValueList[i]);
+      writeString('":');
+      writeObject(keyValueList[i + 1]);
+    }
+    writeString('}');
+    return true;
+  }
+}
+
+/// A modification of [_JsonStringifier] which indents the contents of [List] and
+/// [Map] objects using the specified indent value.
+///
+/// Subclasses should implement [writeIndentation].
+abstract class _JsonPrettyPrintMixin implements _JsonStringifier {
+  int _indentLevel = 0;
+
+  /// Add [indentLevel] indentations to the JSON output.
+  void writeIndentation(int indentLevel);
+
+  void writeList(List list) {
+    if (list.isEmpty) {
+      writeString('[]');
+    } else {
+      writeString('[\n');
+      _indentLevel++;
+      writeIndentation(_indentLevel);
+      writeObject(list[0]);
+      for (var i = 1; i < list.length; i++) {
+        writeString(',\n');
+        writeIndentation(_indentLevel);
+        writeObject(list[i]);
+      }
+      writeString('\n');
+      _indentLevel--;
+      writeIndentation(_indentLevel);
+      writeString(']');
+    }
+  }
+
+  bool writeMap(Map map) {
+    if (map.isEmpty) {
+      writeString("{}");
+      return true;
+    }
+    var keyValueList = List(map.length * 2);
+    var i = 0;
+    var allStringKeys = true;
+    map.forEach((key, value) {
+      if (key is! String) {
+        allStringKeys = false;
+      }
+      keyValueList[i++] = key;
+      keyValueList[i++] = value;
+    });
+    if (!allStringKeys) return false;
+    writeString('{\n');
+    _indentLevel++;
+    var separator = "";
+    for (var i = 0; i < keyValueList.length; i += 2) {
+      writeString(separator);
+      separator = ",\n";
+      writeIndentation(_indentLevel);
+      writeString('"');
+      writeStringContent(keyValueList[i]);
+      writeString('": ');
+      writeObject(keyValueList[i + 1]);
+    }
+    writeString('\n');
+    _indentLevel--;
+    writeIndentation(_indentLevel);
+    writeString('}');
+    return true;
+  }
+}
+
+/// A specialization of [_JsonStringifier] that writes its JSON to a string.
+class _JsonStringStringifier extends _JsonStringifier {
+  final StringSink _sink;
+
+  _JsonStringStringifier(this._sink, dynamic Function(dynamic) _toEncodable)
+      : super(_toEncodable);
+
+  /// Convert object to a string.
+  ///
+  /// The [toEncodable] function is used to convert non-encodable objects
+  /// to encodable ones.
+  ///
+  /// If [indent] is not `null`, the resulting JSON will be "pretty-printed"
+  /// with newlines and indentation. The `indent` string is added as indentation
+  /// for each indentation level. It should only contain valid JSON whitespace
+  /// characters (space, tab, carriage return or line feed).
+  static String stringify(object, toEncodable(o), String indent) {
+    var output = StringBuffer();
+    printOn(object, output, toEncodable, indent);
+    return output.toString();
+  }
+
+  /// Convert object to a string, and write the result to the [output] sink.
+  ///
+  /// The result is written piecemally to the sink.
+  static void printOn(
+      object, StringSink output, toEncodable(o), String indent) {
+    _JsonStringifier stringifier;
+    if (indent == null) {
+      stringifier = _JsonStringStringifier(output, toEncodable);
+    } else {
+      stringifier = _JsonStringStringifierPretty(output, toEncodable, indent);
+    }
+    stringifier.writeObject(object);
+  }
+
+  String get _partialResult => _sink is StringBuffer ? _sink.toString() : null;
+
+  void writeNumber(num number) {
+    _sink.write(number.toString());
+  }
+
+  void writeString(String string) {
+    _sink.write(string);
+  }
+
+  void writeStringSlice(String string, int start, int end) {
+    _sink.write(string.substring(start, end));
+  }
+
+  void writeCharCode(int charCode) {
+    _sink.writeCharCode(charCode);
+  }
+}
+
+class _JsonStringStringifierPretty extends _JsonStringStringifier
+    with _JsonPrettyPrintMixin {
+  final String _indent;
+
+  _JsonStringStringifierPretty(StringSink sink, toEncodable(o), this._indent)
+      : super(sink, toEncodable);
+
+  void writeIndentation(int count) {
+    for (var i = 0; i < count; i++) writeString(_indent);
+  }
+}
+
+/// Specialization of [_JsonStringifier] that writes the JSON as UTF-8.
+///
+/// The JSON text is UTF-8 encoded and written to [Uint8List] buffers.
+/// The buffers are then passed back to a user provided callback method.
+class _JsonUtf8Stringifier extends _JsonStringifier {
+  final int bufferSize;
+  final void Function(Uint8List list, int start, int end) addChunk;
+  Uint8List buffer;
+  int index = 0;
+
+  _JsonUtf8Stringifier(toEncodable(o), this.bufferSize, this.addChunk)
+      : buffer = Uint8List(bufferSize),
+        super(toEncodable);
+
+  /// Convert [object] to UTF-8 encoded JSON.
+  ///
+  /// Calls [addChunk] with slices of UTF-8 code units.
+  /// These will typically have size [bufferSize], but may be shorter.
+  /// The buffers are not reused, so the [addChunk] call may keep and reuse the
+  /// chunks.
+  ///
+  /// If [indent] is non-`null`, the result will be "pretty-printed" with extra
+  /// newlines and indentation, using [indent] as the indentation.
+  static void stringify(Object object, List<int> indent, toEncodable(o),
+      int bufferSize, void addChunk(Uint8List chunk, int start, int end)) {
+    _JsonUtf8Stringifier stringifier;
+    if (indent != null) {
+      stringifier =
+          _JsonUtf8StringifierPretty(toEncodable, indent, bufferSize, addChunk);
+    } else {
+      stringifier = _JsonUtf8Stringifier(toEncodable, bufferSize, addChunk);
+    }
+    stringifier.writeObject(object);
+    stringifier.flush();
+  }
+
+  /// Must be called at the end to push the last chunk to the [addChunk]
+  /// callback.
+  void flush() {
+    if (index > 0) {
+      addChunk(buffer, 0, index);
+    }
+    buffer = null;
+    index = 0;
+  }
+
+  String get _partialResult => null;
+
+  void writeNumber(num number) {
+    writeAsciiString(number.toString());
+  }
+
+  /// Write a string that is known to not have non-ASCII characters.
+  void writeAsciiString(String string) {
+    // TODO(lrn): Optimize by copying directly into buffer instead of going
+    // through writeCharCode;
+    for (var i = 0; i < string.length; i++) {
+      var char = string.codeUnitAt(i);
+      assert(char <= 0x7f);
+      writeByte(char);
+    }
+  }
+
+  void writeString(String string) {
+    writeStringSlice(string, 0, string.length);
+  }
+
+  void writeStringSlice(String string, int start, int end) {
+    // TODO(lrn): Optimize by copying directly into buffer instead of going
+    // through writeCharCode/writeByte. Assumption is the most characters
+    // in starings are plain ASCII.
+    for (var i = start; i < end; i++) {
+      var char = string.codeUnitAt(i);
+      if (char <= 0x7f) {
+        writeByte(char);
+      } else {
+        if ((char & 0xFC00) == 0xD800 && i + 1 < end) {
+          // Lead surrogate.
+          var nextChar = string.codeUnitAt(i + 1);
+          if ((nextChar & 0xFC00) == 0xDC00) {
+            // Tail surrogate.
+            char = 0x10000 + ((char & 0x3ff) << 10) + (nextChar & 0x3ff);
+            writeFourByteCharCode(char);
+            i++;
+            continue;
+          }
+        }
+        writeMultiByteCharCode(char);
+      }
+    }
+  }
+
+  void writeCharCode(int charCode) {
+    if (charCode <= 0x7f) {
+      writeByte(charCode);
+      return;
+    }
+    writeMultiByteCharCode(charCode);
+  }
+
+  void writeMultiByteCharCode(int charCode) {
+    if (charCode <= 0x7ff) {
+      writeByte(0xC0 | (charCode >> 6));
+      writeByte(0x80 | (charCode & 0x3f));
+      return;
+    }
+    if (charCode <= 0xffff) {
+      writeByte(0xE0 | (charCode >> 12));
+      writeByte(0x80 | ((charCode >> 6) & 0x3f));
+      writeByte(0x80 | (charCode & 0x3f));
+      return;
+    }
+    writeFourByteCharCode(charCode);
+  }
+
+  void writeFourByteCharCode(int charCode) {
+    assert(charCode <= 0x10ffff);
+    writeByte(0xF0 | (charCode >> 18));
+    writeByte(0x80 | ((charCode >> 12) & 0x3f));
+    writeByte(0x80 | ((charCode >> 6) & 0x3f));
+    writeByte(0x80 | (charCode & 0x3f));
+  }
+
+  void writeByte(int byte) {
+    assert(byte <= 0xff);
+    if (index == buffer.length) {
+      addChunk(buffer, 0, index);
+      buffer = Uint8List(bufferSize);
+      index = 0;
+    }
+    buffer[index++] = byte;
+  }
+}
+
+/// Pretty-printing version of [_JsonUtf8Stringifier].
+class _JsonUtf8StringifierPretty extends _JsonUtf8Stringifier
+    with _JsonPrettyPrintMixin {
+  final List<int> indent;
+  _JsonUtf8StringifierPretty(toEncodable(o), this.indent, int bufferSize,
+      void addChunk(Uint8List buffer, int start, int end))
+      : super(toEncodable, bufferSize, addChunk);
+
+  void writeIndentation(int count) {
+    var indent = this.indent;
+    var indentLength = indent.length;
+    if (indentLength == 1) {
+      var char = indent[0];
+      while (count > 0) {
+        writeByte(char);
+        count -= 1;
+      }
+      return;
+    }
+    while (count > 0) {
+      count--;
+      var end = index + indentLength;
+      if (end <= buffer.length) {
+        buffer.setRange(index, end, indent);
+        index = end;
+      } else {
+        for (var i = 0; i < indentLength; i++) {
+          writeByte(indent[i]);
+        }
+      }
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/convert/latin1.dart b/sdk_nnbd/lib/convert/latin1.dart
new file mode 100644
index 0000000..c22010c
--- /dev/null
+++ b/sdk_nnbd/lib/convert/latin1.dart
@@ -0,0 +1,182 @@
+// 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 dart.convert;
+
+/// An instance of the default implementation of the [Latin1Codec].
+///
+/// This instance provides a convenient access to the most common ISO Latin 1
+/// use cases.
+///
+/// Examples:
+/// ```dart
+/// var encoded = latin1.encode("blåbærgrød");
+/// var decoded = latin1.decode([0x62, 0x6c, 0xe5, 0x62, 0xe6,
+///                              0x72, 0x67, 0x72, 0xf8, 0x64]);
+/// ```
+const Latin1Codec latin1 = Latin1Codec();
+
+const int _latin1Mask = 0xFF;
+
+/// A [Latin1Codec] encodes strings to ISO Latin-1 (aka ISO-8859-1) bytes
+/// and decodes Latin-1 bytes to strings.
+class Latin1Codec extends Encoding {
+  final bool _allowInvalid;
+
+  /// Instantiates a new [Latin1Codec].
+  ///
+  /// If [allowInvalid] is true, the [decode] method and the converter
+  /// returned by [decoder] will default to allowing invalid values. Invalid
+  /// values are decoded into the Unicode Replacement character (U+FFFD).
+  /// Calls to the [decode] method can override this default.
+  ///
+  /// Encoders will not accept invalid (non Latin-1) characters.
+  const Latin1Codec({bool allowInvalid = false}) : _allowInvalid = allowInvalid;
+
+  /// The name of this codec, "iso-8859-1".
+  String get name => "iso-8859-1";
+
+  Uint8List encode(String source) => encoder.convert(source);
+
+  /// Decodes the Latin-1 [bytes] (a list of unsigned 8-bit integers) to the
+  /// corresponding string.
+  ///
+  /// If [bytes] contains values that are not in the range 0 .. 255, the decoder
+  /// will eventually throw a [FormatException].
+  ///
+  /// If [allowInvalid] is not provided, it defaults to the value used to create
+  /// this [Latin1Codec].
+  String decode(List<int> bytes, {bool allowInvalid}) {
+    allowInvalid ??= _allowInvalid;
+    if (allowInvalid) {
+      return const Latin1Decoder(allowInvalid: true).convert(bytes);
+    } else {
+      return const Latin1Decoder(allowInvalid: false).convert(bytes);
+    }
+  }
+
+  Latin1Encoder get encoder => const Latin1Encoder();
+
+  Latin1Decoder get decoder => _allowInvalid
+      ? const Latin1Decoder(allowInvalid: true)
+      : const Latin1Decoder(allowInvalid: false);
+}
+
+/// This class converts strings of only ISO Latin-1 characters to bytes.
+class Latin1Encoder extends _UnicodeSubsetEncoder {
+  const Latin1Encoder() : super(_latin1Mask);
+}
+
+/// This class converts Latin-1 bytes (lists of unsigned 8-bit integers)
+/// to a string.
+class Latin1Decoder extends _UnicodeSubsetDecoder {
+  /// Instantiates a new [Latin1Decoder].
+  ///
+  /// The optional [allowInvalid] argument defines how [convert] deals
+  /// with invalid bytes.
+  ///
+  /// If it is `true`, [convert] replaces invalid bytes with the Unicode
+  /// Replacement character `U+FFFD` (�).
+  /// Otherwise it throws a [FormatException].
+  const Latin1Decoder({bool allowInvalid = false})
+      : super(allowInvalid, _latin1Mask);
+
+  /// Starts a chunked conversion.
+  ///
+  /// The converter works more efficiently if the given [sink] is a
+  /// [StringConversionSink].
+  ByteConversionSink startChunkedConversion(Sink<String> sink) {
+    StringConversionSink stringSink;
+    if (sink is StringConversionSink) {
+      stringSink = sink;
+    } else {
+      stringSink = StringConversionSink.from(sink);
+    }
+    // TODO(lrn): Use stringSink.asUtf16Sink() if it becomes available.
+    if (!_allowInvalid) return _Latin1DecoderSink(stringSink);
+    return _Latin1AllowInvalidDecoderSink(stringSink);
+  }
+}
+
+class _Latin1DecoderSink extends ByteConversionSinkBase {
+  StringConversionSink _sink;
+  _Latin1DecoderSink(this._sink);
+
+  void close() {
+    _sink.close();
+    _sink = null;
+  }
+
+  void add(List<int> source) {
+    addSlice(source, 0, source.length, false);
+  }
+
+  void _addSliceToSink(List<int> source, int start, int end, bool isLast) {
+    // If _sink was a UTF-16 conversion sink, just add the slice directly with
+    // _sink.addSlice(source, start, end, isLast).
+    // The code below is an moderately stupid workaround until a real
+    // solution can be made.
+    _sink.add(String.fromCharCodes(source, start, end));
+    if (isLast) close();
+  }
+
+  void addSlice(List<int> source, int start, int end, bool isLast) {
+    end = RangeError.checkValidRange(start, end, source.length);
+    if (start == end) return;
+    if (source is! Uint8List) {
+      // List may contain value outside of the 0..255 range. If so, throw.
+      // Technically, we could excuse Uint8ClampedList as well, but it unlikely
+      // to be relevant.
+      _checkValidLatin1(source, start, end);
+    }
+    _addSliceToSink(source, start, end, isLast);
+  }
+
+  static void _checkValidLatin1(List<int> source, int start, int end) {
+    var mask = 0;
+    for (var i = start; i < end; i++) {
+      mask |= source[i];
+    }
+    if (mask >= 0 && mask <= _latin1Mask) {
+      return;
+    }
+    _reportInvalidLatin1(source, start, end); // Always throws.
+  }
+
+  static void _reportInvalidLatin1(List<int> source, int start, int end) {
+    // Find the index of the first non-Latin-1 character code.
+    for (var i = start; i < end; i++) {
+      var char = source[i];
+      if (char < 0 || char > _latin1Mask) {
+        throw FormatException(
+            "Source contains non-Latin-1 characters.", source, i);
+      }
+    }
+    // Unreachable - we only call the function if the loop above throws.
+    assert(false);
+  }
+}
+
+class _Latin1AllowInvalidDecoderSink extends _Latin1DecoderSink {
+  _Latin1AllowInvalidDecoderSink(StringConversionSink sink) : super(sink);
+
+  void addSlice(List<int> source, int start, int end, bool isLast) {
+    RangeError.checkValidRange(start, end, source.length);
+    for (var i = start; i < end; i++) {
+      var char = source[i];
+      if (char > _latin1Mask || char < 0) {
+        if (i > start) _addSliceToSink(source, start, i, false);
+        // Add UTF-8 encoding of U+FFFD.
+        _addSliceToSink(const [0xFFFD], 0, 1, false);
+        start = i + 1;
+      }
+    }
+    if (start < end) {
+      _addSliceToSink(source, start, end, isLast);
+    }
+    if (isLast) {
+      close();
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/convert/line_splitter.dart b/sdk_nnbd/lib/convert/line_splitter.dart
new file mode 100644
index 0000000..71be2c0
--- /dev/null
+++ b/sdk_nnbd/lib/convert/line_splitter.dart
@@ -0,0 +1,172 @@
+// 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 dart.convert;
+
+// Character constants.
+const int _LF = 10;
+const int _CR = 13;
+
+/// A [StreamTransformer] that splits a [String] into individual lines.
+///
+/// A line is terminated by either a CR (U+000D), a LF (U+000A), a
+/// CR+LF sequence (DOS line ending),
+/// and a final non-empty line can be ended by the end of the string.
+///
+/// The returned lines do not contain the line terminators.
+
+class LineSplitter extends StreamTransformerBase<String, String> {
+  const LineSplitter();
+
+  /// Split [lines] into individual lines.
+  ///
+  /// If [start] and [end] are provided, only split the contents of
+  /// `lines.substring(start, end)`. The [start] and [end] values must
+  /// specify a valid sub-range of [lines]
+  /// (`0 <= start <= end <= lines.length`).
+  static Iterable<String> split(String lines, [int start = 0, int end]) sync* {
+    end = RangeError.checkValidRange(start, end, lines.length);
+    var sliceStart = start;
+    var char = 0;
+    for (var i = start; i < end; i++) {
+      var previousChar = char;
+      char = lines.codeUnitAt(i);
+      if (char != _CR) {
+        if (char != _LF) continue;
+        if (previousChar == _CR) {
+          sliceStart = i + 1;
+          continue;
+        }
+      }
+      yield lines.substring(sliceStart, i);
+      sliceStart = i + 1;
+    }
+    if (sliceStart < end) {
+      yield lines.substring(sliceStart, end);
+    }
+  }
+
+  List<String> convert(String data) {
+    var lines = <String>[];
+    var end = data.length;
+    var sliceStart = 0;
+    var char = 0;
+    for (var i = 0; i < end; i++) {
+      var previousChar = char;
+      char = data.codeUnitAt(i);
+      if (char != _CR) {
+        if (char != _LF) continue;
+        if (previousChar == _CR) {
+          sliceStart = i + 1;
+          continue;
+        }
+      }
+      lines.add(data.substring(sliceStart, i));
+      sliceStart = i + 1;
+    }
+    if (sliceStart < end) {
+      lines.add(data.substring(sliceStart, end));
+    }
+    return lines;
+  }
+
+  StringConversionSink startChunkedConversion(Sink<String> sink) {
+    return _LineSplitterSink(
+        sink is StringConversionSink ? sink : StringConversionSink.from(sink));
+  }
+
+  Stream<String> bind(Stream<String> stream) {
+    return Stream<String>.eventTransformed(
+        stream, (EventSink<String> sink) => _LineSplitterEventSink(sink));
+  }
+}
+
+// TODO(floitsch): deal with utf8.
+class _LineSplitterSink extends StringConversionSinkBase {
+  final StringConversionSink _sink;
+
+  /// The carry-over from the previous chunk.
+  ///
+  /// If the previous slice ended in a line without a line terminator,
+  /// then the next slice may continue the line.
+  String _carry;
+
+  /// Whether to skip a leading LF character from the next slice.
+  ///
+  /// If the previous slice ended on a CR character, a following LF
+  /// would be part of the same line termination, and should be ignored.
+  ///
+  /// Only `true` when [_carry] is `null`.
+  bool _skipLeadingLF = false;
+
+  _LineSplitterSink(this._sink);
+
+  void addSlice(String chunk, int start, int end, bool isLast) {
+    end = RangeError.checkValidRange(start, end, chunk.length);
+    // If the chunk is empty, it's probably because it's the last one.
+    // Handle that here, so we know the range is non-empty below.
+    if (start >= end) {
+      if (isLast) close();
+      return;
+    }
+    if (_carry != null) {
+      assert(!_skipLeadingLF);
+      chunk = _carry + chunk.substring(start, end);
+      start = 0;
+      end = chunk.length;
+      _carry = null;
+    } else if (_skipLeadingLF) {
+      if (chunk.codeUnitAt(start) == _LF) {
+        start += 1;
+      }
+      _skipLeadingLF = false;
+    }
+    _addLines(chunk, start, end);
+    if (isLast) close();
+  }
+
+  void close() {
+    if (_carry != null) {
+      _sink.add(_carry);
+      _carry = null;
+    }
+    _sink.close();
+  }
+
+  void _addLines(String lines, int start, int end) {
+    var sliceStart = start;
+    var char = 0;
+    for (var i = start; i < end; i++) {
+      var previousChar = char;
+      char = lines.codeUnitAt(i);
+      if (char != _CR) {
+        if (char != _LF) continue;
+        if (previousChar == _CR) {
+          sliceStart = i + 1;
+          continue;
+        }
+      }
+      _sink.add(lines.substring(sliceStart, i));
+      sliceStart = i + 1;
+    }
+    if (sliceStart < end) {
+      _carry = lines.substring(sliceStart, end);
+    } else {
+      _skipLeadingLF = (char == _CR);
+    }
+  }
+}
+
+class _LineSplitterEventSink extends _LineSplitterSink
+    implements EventSink<String> {
+  final EventSink<String> _eventSink;
+
+  _LineSplitterEventSink(EventSink<String> eventSink)
+      : _eventSink = eventSink,
+        super(StringConversionSink.from(eventSink));
+
+  void addError(Object o, [StackTrace stackTrace]) {
+    _eventSink.addError(o, stackTrace);
+  }
+}
diff --git a/sdk_nnbd/lib/convert/string_conversion.dart b/sdk_nnbd/lib/convert/string_conversion.dart
new file mode 100644
index 0000000..81e5621
--- /dev/null
+++ b/sdk_nnbd/lib/convert/string_conversion.dart
@@ -0,0 +1,318 @@
+// 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 dart.convert;
+
+/// This class provides an interface for converters to
+/// efficiently transmit String data.
+///
+/// Instead of limiting the interface to one non-chunked String it accepts
+/// partial strings or can be transformed into a byte sink that
+/// accepts UTF-8 code units.
+///
+/// This abstract class will likely get more methods over time. Implementers are
+/// urged to extend [StringConversionSinkBase] or to mix in
+/// [StringConversionSinkMixin], to ensure that their class covers the newly
+/// added methods.
+abstract class StringConversionSink extends ChunkedConversionSink<String> {
+  StringConversionSink();
+  factory StringConversionSink.withCallback(void callback(String accumulated)) =
+      _StringCallbackSink;
+  factory StringConversionSink.from(Sink<String> sink) = _StringAdapterSink;
+
+  /// Creates a new instance wrapping the given [sink].
+  ///
+  /// Every string that is added to the returned instance is forwarded to
+  /// the [sink]. The instance is allowed to buffer and is not required to
+  /// forward immediately.
+  factory StringConversionSink.fromStringSink(StringSink sink) =
+      _StringSinkConversionSink<StringSink>;
+
+  /// Adds the next [chunk] to `this`.
+  ///
+  /// Adds the substring defined by [start] and [end]-exclusive to `this`.
+  ///
+  /// If [isLast] is `true` closes `this`.
+  void addSlice(String chunk, int start, int end, bool isLast);
+
+  /// Returns `this` as a sink that accepts UTF-8 input.
+  ///
+  /// If used, this method must be the first and only call to `this`. It
+  /// invalidates `this`. All further operations must be performed on the result.
+  ByteConversionSink asUtf8Sink(bool allowMalformed);
+  // - asRuneSink
+  // - asCodeUnitsSink
+
+  /// Returns `this` as a [ClosableStringSink].
+  ///
+  /// If used, this method must be the first and only call to `this`. It
+  /// invalidates `this`. All further operations must be performed on the result.
+  ClosableStringSink asStringSink();
+}
+
+/// A [ClosableStringSink] extends the [StringSink] interface by adding a
+/// `close` method.
+abstract class ClosableStringSink extends StringSink {
+  /// Creates a new instance combining a [StringSink] [sink] and a callback
+  /// [onClose] which is invoked when the returned instance is closed.
+  factory ClosableStringSink.fromStringSink(StringSink sink, void onClose()) =
+      _ClosableStringSink;
+
+  /// Closes `this` and flushes any outstanding data.
+  void close();
+}
+
+/// This class wraps an existing [StringSink] and invokes a
+/// closure when [close] is invoked.
+class _ClosableStringSink implements ClosableStringSink {
+  final void Function() _callback;
+  final StringSink _sink;
+
+  _ClosableStringSink(this._sink, this._callback);
+
+  void close() {
+    _callback();
+  }
+
+  void writeCharCode(int charCode) {
+    _sink.writeCharCode(charCode);
+  }
+
+  void write(Object o) {
+    _sink.write(o);
+  }
+
+  void writeln([Object o = ""]) {
+    _sink.writeln(o);
+  }
+
+  void writeAll(Iterable objects, [String separator = ""]) {
+    _sink.writeAll(objects, separator);
+  }
+}
+
+/// This class wraps an existing [StringConversionSink] and exposes a
+/// [ClosableStringSink] interface. The wrapped sink only needs to implement
+/// `add` and `close`.
+// TODO(floitsch): make this class public?
+class _StringConversionSinkAsStringSinkAdapter implements ClosableStringSink {
+  static const _MIN_STRING_SIZE = 16;
+
+  StringBuffer _buffer;
+  StringConversionSink _chunkedSink;
+
+  _StringConversionSinkAsStringSinkAdapter(this._chunkedSink)
+      : _buffer = StringBuffer();
+
+  void close() {
+    if (_buffer.isNotEmpty) _flush();
+    _chunkedSink.close();
+  }
+
+  void writeCharCode(int charCode) {
+    _buffer.writeCharCode(charCode);
+    if (_buffer.length > _MIN_STRING_SIZE) _flush();
+  }
+
+  void write(Object o) {
+    if (_buffer.isNotEmpty) _flush();
+    _chunkedSink.add(o.toString());
+  }
+
+  void writeln([Object o = ""]) {
+    _buffer.writeln(o);
+    if (_buffer.length > _MIN_STRING_SIZE) _flush();
+  }
+
+  void writeAll(Iterable objects, [String separator = ""]) {
+    if (_buffer.isNotEmpty) _flush();
+    var iterator = objects.iterator;
+    if (!iterator.moveNext()) return;
+    if (separator.isEmpty) {
+      do {
+        _chunkedSink.add(iterator.current.toString());
+      } while (iterator.moveNext());
+    } else {
+      _chunkedSink.add(iterator.current.toString());
+      while (iterator.moveNext()) {
+        write(separator);
+        _chunkedSink.add(iterator.current.toString());
+      }
+    }
+  }
+
+  void _flush() {
+    var accumulated = _buffer.toString();
+    _buffer.clear();
+    _chunkedSink.add(accumulated);
+  }
+}
+
+/// This class provides a base-class for converters that need to accept String
+/// inputs.
+abstract class StringConversionSinkBase extends StringConversionSinkMixin {}
+
+/// This class provides a mixin for converters that need to accept String
+/// inputs.
+abstract class StringConversionSinkMixin implements StringConversionSink {
+  void addSlice(String str, int start, int end, bool isLast);
+  void close();
+
+  void add(String str) {
+    addSlice(str, 0, str.length, false);
+  }
+
+  ByteConversionSink asUtf8Sink(bool allowMalformed) {
+    return _Utf8ConversionSink(this, allowMalformed);
+  }
+
+  ClosableStringSink asStringSink() {
+    return _StringConversionSinkAsStringSinkAdapter(this);
+  }
+}
+
+/// This class is a [StringConversionSink] that wraps a [StringSink].
+class _StringSinkConversionSink<TStringSink extends StringSink>
+    extends StringConversionSinkBase {
+  TStringSink _stringSink;
+  _StringSinkConversionSink(this._stringSink);
+
+  void close() {}
+  void addSlice(String str, int start, int end, bool isLast) {
+    if (start != 0 || end != str.length) {
+      for (var i = start; i < end; i++) {
+        _stringSink.writeCharCode(str.codeUnitAt(i));
+      }
+    } else {
+      _stringSink.write(str);
+    }
+    if (isLast) close();
+  }
+
+  void add(String str) {
+    _stringSink.write(str);
+  }
+
+  ByteConversionSink asUtf8Sink(bool allowMalformed) {
+    return _Utf8StringSinkAdapter(this, _stringSink, allowMalformed);
+  }
+
+  ClosableStringSink asStringSink() {
+    return ClosableStringSink.fromStringSink(_stringSink, close);
+  }
+}
+
+/// This class accumulates all chunks into one string
+/// and invokes a callback when the sink is closed.
+///
+/// This class can be used to terminate a chunked conversion.
+class _StringCallbackSink extends _StringSinkConversionSink<StringBuffer> {
+  final void Function(String) _callback;
+  _StringCallbackSink(this._callback) : super(StringBuffer());
+
+  void close() {
+    var accumulated = _stringSink.toString();
+    _stringSink.clear();
+    _callback(accumulated);
+  }
+
+  ByteConversionSink asUtf8Sink(bool allowMalformed) {
+    return _Utf8StringSinkAdapter(this, _stringSink, allowMalformed);
+  }
+}
+
+/// This class adapts a simple [ChunkedConversionSink] to a
+/// [StringConversionSink].
+///
+/// All additional methods of the [StringConversionSink] (compared to the
+/// ChunkedConversionSink) are redirected to the `add` method.
+class _StringAdapterSink extends StringConversionSinkBase {
+  final Sink<String> _sink;
+
+  _StringAdapterSink(this._sink);
+
+  void add(String str) {
+    _sink.add(str);
+  }
+
+  void addSlice(String str, int start, int end, bool isLast) {
+    if (start == 0 && end == str.length) {
+      add(str);
+    } else {
+      add(str.substring(start, end));
+    }
+    if (isLast) close();
+  }
+
+  void close() {
+    _sink.close();
+  }
+}
+
+/// Decodes UTF-8 code units and stores them in a [StringSink].
+class _Utf8StringSinkAdapter extends ByteConversionSink {
+  final _Utf8Decoder _decoder;
+  final Sink _sink;
+
+  _Utf8StringSinkAdapter(this._sink, StringSink stringSink, bool allowMalformed)
+      : _decoder = _Utf8Decoder(stringSink, allowMalformed);
+
+  void close() {
+    _decoder.close();
+    if (_sink != null) _sink.close();
+  }
+
+  void add(List<int> chunk) {
+    addSlice(chunk, 0, chunk.length, false);
+  }
+
+  void addSlice(
+      List<int> codeUnits, int startIndex, int endIndex, bool isLast) {
+    _decoder.convert(codeUnits, startIndex, endIndex);
+    if (isLast) close();
+  }
+}
+
+/// Decodes UTF-8 code units.
+///
+/// Forwards the decoded strings to the given [StringConversionSink].
+// TODO(floitsch): make this class public?
+class _Utf8ConversionSink extends ByteConversionSink {
+  final _Utf8Decoder _decoder;
+  final StringConversionSink _chunkedSink;
+  final StringBuffer _buffer;
+  _Utf8ConversionSink(StringConversionSink sink, bool allowMalformed)
+      : this._(sink, StringBuffer(), allowMalformed);
+
+  _Utf8ConversionSink._(
+      this._chunkedSink, StringBuffer stringBuffer, bool allowMalformed)
+      : _decoder = _Utf8Decoder(stringBuffer, allowMalformed),
+        _buffer = stringBuffer;
+
+  void close() {
+    _decoder.close();
+    if (_buffer.isNotEmpty) {
+      var accumulated = _buffer.toString();
+      _buffer.clear();
+      _chunkedSink.addSlice(accumulated, 0, accumulated.length, true);
+    } else {
+      _chunkedSink.close();
+    }
+  }
+
+  void add(List<int> chunk) {
+    addSlice(chunk, 0, chunk.length, false);
+  }
+
+  void addSlice(List<int> chunk, int startIndex, int endIndex, bool isLast) {
+    _decoder.convert(chunk, startIndex, endIndex);
+    if (_buffer.isNotEmpty) {
+      var accumulated = _buffer.toString();
+      _chunkedSink.addSlice(accumulated, 0, accumulated.length, isLast);
+      _buffer.clear();
+      return;
+    }
+    if (isLast) close();
+  }
+}
diff --git a/sdk_nnbd/lib/convert/utf.dart b/sdk_nnbd/lib/convert/utf.dart
new file mode 100644
index 0000000..39eb135
--- /dev/null
+++ b/sdk_nnbd/lib/convert/utf.dart
@@ -0,0 +1,556 @@
+// 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 dart.convert;
+
+/// The Unicode Replacement character `U+FFFD` (�).
+const int unicodeReplacementCharacterRune = 0xFFFD;
+
+/// The Unicode Byte Order Marker (BOM) character `U+FEFF`.
+const int unicodeBomCharacterRune = 0xFEFF;
+
+/// An instance of the default implementation of the [Utf8Codec].
+///
+/// This instance provides a convenient access to the most common UTF-8
+/// use cases.
+///
+/// Examples:
+///
+///     var encoded = utf8.encode("Îñţérñåţîöñåļîžåţîờñ");
+///     var decoded = utf8.decode([0x62, 0x6c, 0xc3, 0xa5, 0x62, 0xc3, 0xa6,
+///                                0x72, 0x67, 0x72, 0xc3, 0xb8, 0x64]);
+const Utf8Codec utf8 = Utf8Codec();
+
+/// A [Utf8Codec] encodes strings to utf-8 code units (bytes) and decodes
+/// UTF-8 code units to strings.
+class Utf8Codec extends Encoding {
+  final bool _allowMalformed;
+
+  /// Instantiates a new [Utf8Codec].
+  ///
+  /// The optional [allowMalformed] argument defines how [decoder] (and [decode])
+  /// deal with invalid or unterminated character sequences.
+  ///
+  /// If it is `true` (and not overridden at the method invocation) [decode] and
+  /// the [decoder] replace invalid (or unterminated) octet
+  /// sequences with the Unicode Replacement character `U+FFFD` (�). Otherwise
+  /// they throw a [FormatException].
+  const Utf8Codec({bool allowMalformed = false})
+      : _allowMalformed = allowMalformed;
+
+  /// The name of this codec, "utf-8".
+  String get name => "utf-8";
+
+  /// Decodes the UTF-8 [codeUnits] (a list of unsigned 8-bit integers) to the
+  /// corresponding string.
+  ///
+  /// If the [codeUnits] start with the encoding of a
+  /// [unicodeBomCharacterRune], that character is discarded.
+  ///
+  /// If [allowMalformed] is `true` the decoder replaces invalid (or
+  /// unterminated) character sequences with the Unicode Replacement character
+  /// `U+FFFD` (�). Otherwise it throws a [FormatException].
+  ///
+  /// If [allowMalformed] is not given, it defaults to the `allowMalformed` that
+  /// was used to instantiate `this`.
+  String decode(List<int> codeUnits, {bool allowMalformed}) {
+    allowMalformed ??= _allowMalformed;
+    return Utf8Decoder(allowMalformed: allowMalformed).convert(codeUnits);
+  }
+
+  Utf8Encoder get encoder => const Utf8Encoder();
+  Utf8Decoder get decoder {
+    return Utf8Decoder(allowMalformed: _allowMalformed);
+  }
+}
+
+/// This class converts strings to their UTF-8 code units (a list of
+/// unsigned 8-bit integers).
+class Utf8Encoder extends Converter<String, List<int>> {
+  const Utf8Encoder();
+
+  /// Converts [string] to its UTF-8 code units (a list of
+  /// unsigned 8-bit integers).
+  ///
+  /// If [start] and [end] are provided, only the substring
+  /// `string.substring(start, end)` is converted.
+  Uint8List convert(String string, [int start = 0, int end]) {
+    var stringLength = string.length;
+    end = RangeError.checkValidRange(start, end, stringLength);
+    var length = end - start;
+    if (length == 0) return Uint8List(0);
+    // Create a new encoder with a length that is guaranteed to be big enough.
+    // A single code unit uses at most 3 bytes, a surrogate pair at most 4.
+    var encoder = _Utf8Encoder.withBufferSize(length * 3);
+    var endPosition = encoder._fillBuffer(string, start, end);
+    assert(endPosition >= end - 1);
+    if (endPosition != end) {
+      // Encoding skipped the last code unit.
+      // That can only happen if the last code unit is a leadsurrogate.
+      // Force encoding of the lead surrogate by itself.
+      var lastCodeUnit = string.codeUnitAt(end - 1);
+      assert(_isLeadSurrogate(lastCodeUnit));
+      // We use a non-surrogate as `nextUnit` so that _writeSurrogate just
+      // writes the lead-surrogate.
+      var wasCombined = encoder._writeSurrogate(lastCodeUnit, 0);
+      assert(!wasCombined);
+    }
+    return encoder._buffer.sublist(0, encoder._bufferIndex);
+  }
+
+  /// Starts a chunked conversion.
+  ///
+  /// The converter works more efficiently if the given [sink] is a
+  /// [ByteConversionSink].
+  StringConversionSink startChunkedConversion(Sink<List<int>> sink) {
+    return _Utf8EncoderSink(
+        sink is ByteConversionSink ? sink : ByteConversionSink.from(sink));
+  }
+
+  // Override the base-classes bind, to provide a better type.
+  Stream<List<int>> bind(Stream<String> stream) => super.bind(stream);
+}
+
+/// This class encodes Strings to UTF-8 code units (unsigned 8 bit integers).
+// TODO(floitsch): make this class public.
+class _Utf8Encoder {
+  int _carry = 0;
+  int _bufferIndex = 0;
+  final Uint8List _buffer;
+
+  static const _DEFAULT_BYTE_BUFFER_SIZE = 1024;
+
+  _Utf8Encoder() : this.withBufferSize(_DEFAULT_BYTE_BUFFER_SIZE);
+
+  _Utf8Encoder.withBufferSize(int bufferSize)
+      : _buffer = _createBuffer(bufferSize);
+
+  /// Allow an implementation to pick the most efficient way of storing bytes.
+  static Uint8List _createBuffer(int size) => Uint8List(size);
+
+  /// Tries to combine the given [leadingSurrogate] with the [nextCodeUnit] and
+  /// writes it to [_buffer].
+  ///
+  /// Returns true if the [nextCodeUnit] was combined with the
+  /// [leadingSurrogate]. If it wasn't then nextCodeUnit was not a trailing
+  /// surrogate and has not been written yet.
+  ///
+  /// It is safe to pass 0 for [nextCodeUnit] in which case only the leading
+  /// surrogate is written.
+  bool _writeSurrogate(int leadingSurrogate, int nextCodeUnit) {
+    if (_isTailSurrogate(nextCodeUnit)) {
+      var rune = _combineSurrogatePair(leadingSurrogate, nextCodeUnit);
+      // If the rune is encoded with 2 code-units then it must be encoded
+      // with 4 bytes in UTF-8.
+      assert(rune > _THREE_BYTE_LIMIT);
+      assert(rune <= _FOUR_BYTE_LIMIT);
+      _buffer[_bufferIndex++] = 0xF0 | (rune >> 18);
+      _buffer[_bufferIndex++] = 0x80 | ((rune >> 12) & 0x3f);
+      _buffer[_bufferIndex++] = 0x80 | ((rune >> 6) & 0x3f);
+      _buffer[_bufferIndex++] = 0x80 | (rune & 0x3f);
+      return true;
+    } else {
+      // TODO(floitsch): allow to throw on malformed strings.
+      // Encode the half-surrogate directly into UTF-8. This yields
+      // invalid UTF-8, but we started out with invalid UTF-16.
+
+      // Surrogates are always encoded in 3 bytes in UTF-8.
+      _buffer[_bufferIndex++] = 0xE0 | (leadingSurrogate >> 12);
+      _buffer[_bufferIndex++] = 0x80 | ((leadingSurrogate >> 6) & 0x3f);
+      _buffer[_bufferIndex++] = 0x80 | (leadingSurrogate & 0x3f);
+      return false;
+    }
+  }
+
+  /// Fills the [_buffer] with as many characters as possible.
+  ///
+  /// Does not encode any trailing lead-surrogate. This must be done by the
+  /// caller.
+  ///
+  /// Returns the position in the string. The returned index points to the
+  /// first code unit that hasn't been encoded.
+  int _fillBuffer(String str, int start, int end) {
+    if (start != end && _isLeadSurrogate(str.codeUnitAt(end - 1))) {
+      // Don't handle a trailing lead-surrogate in this loop. The caller has
+      // to deal with those.
+      end--;
+    }
+    int stringIndex;
+    for (stringIndex = start; stringIndex < end; stringIndex++) {
+      var codeUnit = str.codeUnitAt(stringIndex);
+      // ASCII has the same representation in UTF-8 and UTF-16.
+      if (codeUnit <= _ONE_BYTE_LIMIT) {
+        if (_bufferIndex >= _buffer.length) break;
+        _buffer[_bufferIndex++] = codeUnit;
+      } else if (_isLeadSurrogate(codeUnit)) {
+        if (_bufferIndex + 3 >= _buffer.length) break;
+        // Note that it is safe to read the next code unit. We decremented
+        // [end] above when the last valid code unit was a leading surrogate.
+        var nextCodeUnit = str.codeUnitAt(stringIndex + 1);
+        var wasCombined = _writeSurrogate(codeUnit, nextCodeUnit);
+        if (wasCombined) stringIndex++;
+      } else {
+        var rune = codeUnit;
+        if (rune <= _TWO_BYTE_LIMIT) {
+          if (_bufferIndex + 1 >= _buffer.length) break;
+          _buffer[_bufferIndex++] = 0xC0 | (rune >> 6);
+          _buffer[_bufferIndex++] = 0x80 | (rune & 0x3f);
+        } else {
+          assert(rune <= _THREE_BYTE_LIMIT);
+          if (_bufferIndex + 2 >= _buffer.length) break;
+          _buffer[_bufferIndex++] = 0xE0 | (rune >> 12);
+          _buffer[_bufferIndex++] = 0x80 | ((rune >> 6) & 0x3f);
+          _buffer[_bufferIndex++] = 0x80 | (rune & 0x3f);
+        }
+      }
+    }
+    return stringIndex;
+  }
+}
+
+/// This class encodes chunked strings to UTF-8 code units (unsigned 8-bit
+/// integers).
+class _Utf8EncoderSink extends _Utf8Encoder with StringConversionSinkMixin {
+  final ByteConversionSink _sink;
+
+  _Utf8EncoderSink(this._sink);
+
+  void close() {
+    if (_carry != 0) {
+      // addSlice will call close again, but then the carry must be equal to 0.
+      addSlice("", 0, 0, true);
+      return;
+    }
+    _sink.close();
+  }
+
+  void addSlice(String str, int start, int end, bool isLast) {
+    _bufferIndex = 0;
+
+    if (start == end && !isLast) {
+      return;
+    }
+
+    if (_carry != 0) {
+      var nextCodeUnit = 0;
+      if (start != end) {
+        nextCodeUnit = str.codeUnitAt(start);
+      } else {
+        assert(isLast);
+      }
+      var wasCombined = _writeSurrogate(_carry, nextCodeUnit);
+      // Either we got a non-empty string, or we must not have been combined.
+      assert(!wasCombined || start != end);
+      if (wasCombined) start++;
+      _carry = 0;
+    }
+    do {
+      start = _fillBuffer(str, start, end);
+      var isLastSlice = isLast && (start == end);
+      if (start == end - 1 && _isLeadSurrogate(str.codeUnitAt(start))) {
+        if (isLast && _bufferIndex < _buffer.length - 3) {
+          // There is still space for the last incomplete surrogate.
+          // We use a non-surrogate as second argument. This way the
+          // function will just add the surrogate-half to the buffer.
+          var hasBeenCombined = _writeSurrogate(str.codeUnitAt(start), 0);
+          assert(!hasBeenCombined);
+        } else {
+          // Otherwise store it in the carry. If isLast is true, then
+          // close will flush the last carry.
+          _carry = str.codeUnitAt(start);
+        }
+        start++;
+      }
+      _sink.addSlice(_buffer, 0, _bufferIndex, isLastSlice);
+      _bufferIndex = 0;
+    } while (start < end);
+    if (isLast) close();
+  }
+
+  // TODO(floitsch): implement asUtf8Sink. Sligthly complicated because it
+  // needs to deal with malformed input.
+}
+
+/// This class converts UTF-8 code units (lists of unsigned 8-bit integers)
+/// to a string.
+class Utf8Decoder extends Converter<List<int>, String> {
+  final bool _allowMalformed;
+
+  /// Instantiates a new [Utf8Decoder].
+  ///
+  /// The optional [allowMalformed] argument defines how [convert] deals
+  /// with invalid or unterminated character sequences.
+  ///
+  /// If it is `true` [convert] replaces invalid (or unterminated) character
+  /// sequences with the Unicode Replacement character `U+FFFD` (�). Otherwise
+  /// it throws a [FormatException].
+  const Utf8Decoder({bool allowMalformed = false})
+      : _allowMalformed = allowMalformed;
+
+  /// Converts the UTF-8 [codeUnits] (a list of unsigned 8-bit integers) to the
+  /// corresponding string.
+  ///
+  /// Uses the code units from [start] to, but no including, [end].
+  /// If [end] is omitted, it defaults to `codeUnits.length`.
+  ///
+  /// If the [codeUnits] start with the encoding of a
+  /// [unicodeBomCharacterRune], that character is discarded.
+  String convert(List<int> codeUnits, [int start = 0, int end]) {
+    // Allow the implementation to intercept and specialize based on the type
+    // of codeUnits.
+    var result = _convertIntercepted(_allowMalformed, codeUnits, start, end);
+    if (result != null) {
+      return result;
+    }
+
+    var length = codeUnits.length;
+    end = RangeError.checkValidRange(start, end, length);
+
+    // Fast case for ASCII strings avoids StringBuffer/_Utf8Decoder.
+    int oneBytes = _scanOneByteCharacters(codeUnits, start, end);
+    StringBuffer buffer;
+    bool isFirstCharacter = true;
+    if (oneBytes > 0) {
+      var firstPart = String.fromCharCodes(codeUnits, start, start + oneBytes);
+      start += oneBytes;
+      if (start == end) {
+        return firstPart;
+      }
+      buffer = StringBuffer(firstPart);
+      isFirstCharacter = false;
+    }
+
+    buffer ??= StringBuffer();
+    var decoder = _Utf8Decoder(buffer, _allowMalformed);
+    decoder._isFirstCharacter = isFirstCharacter;
+    decoder.convert(codeUnits, start, end);
+    decoder.flush(codeUnits, end);
+    return buffer.toString();
+  }
+
+  /// Starts a chunked conversion.
+  ///
+  /// The converter works more efficiently if the given [sink] is a
+  /// [StringConversionSink].
+  ByteConversionSink startChunkedConversion(Sink<String> sink) {
+    StringConversionSink stringSink;
+    if (sink is StringConversionSink) {
+      stringSink = sink;
+    } else {
+      stringSink = StringConversionSink.from(sink);
+    }
+    return stringSink.asUtf8Sink(_allowMalformed);
+  }
+
+  // Override the base-classes bind, to provide a better type.
+  Stream<String> bind(Stream<List<int>> stream) => super.bind(stream);
+
+  external Converter<List<int>, T> fuse<T>(Converter<String, T> next);
+
+  external static String _convertIntercepted(
+      bool allowMalformed, List<int> codeUnits, int start, int end);
+}
+
+// UTF-8 constants.
+const int _ONE_BYTE_LIMIT = 0x7f; // 7 bits
+const int _TWO_BYTE_LIMIT = 0x7ff; // 11 bits
+const int _THREE_BYTE_LIMIT = 0xffff; // 16 bits
+const int _FOUR_BYTE_LIMIT = 0x10ffff; // 21 bits, truncated to Unicode max.
+
+// UTF-16 constants.
+const int _SURROGATE_TAG_MASK = 0xFC00;
+const int _SURROGATE_VALUE_MASK = 0x3FF;
+const int _LEAD_SURROGATE_MIN = 0xD800;
+const int _TAIL_SURROGATE_MIN = 0xDC00;
+
+bool _isLeadSurrogate(int codeUnit) =>
+    (codeUnit & _SURROGATE_TAG_MASK) == _LEAD_SURROGATE_MIN;
+bool _isTailSurrogate(int codeUnit) =>
+    (codeUnit & _SURROGATE_TAG_MASK) == _TAIL_SURROGATE_MIN;
+int _combineSurrogatePair(int lead, int tail) =>
+    0x10000 + ((lead & _SURROGATE_VALUE_MASK) << 10) |
+    (tail & _SURROGATE_VALUE_MASK);
+
+/// Decodes UTF-8.
+///
+/// The decoder handles chunked input.
+// TODO(floitsch): make this class public.
+class _Utf8Decoder {
+  final bool _allowMalformed;
+  final StringSink _stringSink;
+  bool _isFirstCharacter = true;
+  int _value = 0;
+  int _expectedUnits = 0;
+  int _extraUnits = 0;
+
+  _Utf8Decoder(this._stringSink, this._allowMalformed);
+
+  bool get hasPartialInput => _expectedUnits > 0;
+
+  // Limits of one through four byte encodings.
+  static const List<int> _LIMITS = <int>[
+    _ONE_BYTE_LIMIT,
+    _TWO_BYTE_LIMIT,
+    _THREE_BYTE_LIMIT,
+    _FOUR_BYTE_LIMIT
+  ];
+
+  void close() {
+    flush();
+  }
+
+  /// Flushes this decoder as if closed.
+  ///
+  /// This method throws if the input was partial and the decoder was
+  /// constructed with `allowMalformed` set to `false`.
+  ///
+  /// The [source] and [offset] of the current position may be provided,
+  /// and are included in the exception if one is thrown.
+  void flush([List<int> source, int offset]) {
+    if (hasPartialInput) {
+      if (!_allowMalformed) {
+        throw FormatException(
+            "Unfinished UTF-8 octet sequence", source, offset);
+      }
+      _stringSink.writeCharCode(unicodeReplacementCharacterRune);
+      _value = 0;
+      _expectedUnits = 0;
+      _extraUnits = 0;
+    }
+  }
+
+  void convert(List<int> codeUnits, int startIndex, int endIndex) {
+    var value = _value;
+    var expectedUnits = _expectedUnits;
+    var extraUnits = _extraUnits;
+    _value = 0;
+    _expectedUnits = 0;
+    _extraUnits = 0;
+
+    var i = startIndex;
+    loop:
+    while (true) {
+      multibyte:
+      if (expectedUnits > 0) {
+        do {
+          if (i == endIndex) {
+            break loop;
+          }
+          var unit = codeUnits[i];
+          if ((unit & 0xC0) != 0x80) {
+            expectedUnits = 0;
+            if (!_allowMalformed) {
+              throw FormatException(
+                  "Bad UTF-8 encoding 0x${unit.toRadixString(16)}",
+                  codeUnits,
+                  i);
+            }
+            _isFirstCharacter = false;
+            _stringSink.writeCharCode(unicodeReplacementCharacterRune);
+            break multibyte;
+          } else {
+            value = (value << 6) | (unit & 0x3f);
+            expectedUnits--;
+            i++;
+          }
+        } while (expectedUnits > 0);
+        if (value <= _LIMITS[extraUnits - 1]) {
+          // Overly long encoding. The value could be encoded with a shorter
+          // encoding.
+          if (!_allowMalformed) {
+            throw FormatException(
+                "Overlong encoding of 0x${value.toRadixString(16)}",
+                codeUnits,
+                i - extraUnits - 1);
+          }
+          expectedUnits = extraUnits = 0;
+          value = unicodeReplacementCharacterRune;
+        }
+        if (value > _FOUR_BYTE_LIMIT) {
+          if (!_allowMalformed) {
+            throw FormatException(
+                "Character outside valid Unicode range: "
+                "0x${value.toRadixString(16)}",
+                codeUnits,
+                i - extraUnits - 1);
+          }
+          value = unicodeReplacementCharacterRune;
+        }
+        if (!_isFirstCharacter || value != unicodeBomCharacterRune) {
+          _stringSink.writeCharCode(value);
+        }
+        _isFirstCharacter = false;
+      }
+
+      while (i < endIndex) {
+        var oneBytes = _scanOneByteCharacters(codeUnits, i, endIndex);
+        if (oneBytes > 0) {
+          _isFirstCharacter = false;
+          assert(i + oneBytes <= endIndex);
+          _stringSink.write(String.fromCharCodes(codeUnits, i, i + oneBytes));
+
+          i += oneBytes;
+          if (i == endIndex) break;
+        }
+        var unit = codeUnits[i++];
+        // TODO(floitsch): the way we test we could potentially allow
+        // units that are too large, if they happen to have the
+        // right bit-pattern. (Same is true for the multibyte loop above).
+        // TODO(floitsch): optimize this loop. See:
+        // https://codereview.chromium.org/22929022/diff/1/sdk/lib/convert/utf.dart?column_width=80
+        if (unit < 0) {
+          // TODO(floitsch): should this be unit <= 0 ?
+          if (!_allowMalformed) {
+            throw FormatException(
+                "Negative UTF-8 code unit: -0x${(-unit).toRadixString(16)}",
+                codeUnits,
+                i - 1);
+          }
+          _stringSink.writeCharCode(unicodeReplacementCharacterRune);
+        } else {
+          assert(unit > _ONE_BYTE_LIMIT);
+          if ((unit & 0xE0) == 0xC0) {
+            value = unit & 0x1F;
+            expectedUnits = extraUnits = 1;
+            continue loop;
+          }
+          if ((unit & 0xF0) == 0xE0) {
+            value = unit & 0x0F;
+            expectedUnits = extraUnits = 2;
+            continue loop;
+          }
+          // 0xF5, 0xF6 ... 0xFF never appear in valid UTF-8 sequences.
+          if ((unit & 0xF8) == 0xF0 && unit < 0xF5) {
+            value = unit & 0x07;
+            expectedUnits = extraUnits = 3;
+            continue loop;
+          }
+          if (!_allowMalformed) {
+            throw FormatException(
+                "Bad UTF-8 encoding 0x${unit.toRadixString(16)}",
+                codeUnits,
+                i - 1);
+          }
+          value = unicodeReplacementCharacterRune;
+          expectedUnits = extraUnits = 0;
+          _isFirstCharacter = false;
+          _stringSink.writeCharCode(value);
+        }
+      }
+      break loop;
+    }
+    if (expectedUnits > 0) {
+      _value = value;
+      _expectedUnits = expectedUnits;
+      _extraUnits = extraUnits;
+    }
+  }
+}
+
+// Returns the number of bytes in [units] starting at offset [from] which have
+// the leftmost bit set to 0.
+//
+// To increase performance of this critical method we have a special variant of
+// it implemented in the VM's patch files, which is why we make it external.
+external int _scanOneByteCharacters(List<int> units, int from, int endIndex);
diff --git a/sdk_nnbd/lib/core/annotations.dart b/sdk_nnbd/lib/core/annotations.dart
new file mode 100644
index 0000000..2d30f1c
--- /dev/null
+++ b/sdk_nnbd/lib/core/annotations.dart
@@ -0,0 +1,240 @@
+// 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 dart.core;
+
+/**
+ * The annotation `@Deprecated('migration')` marks a feature as deprecated.
+ *
+ * The annotation [deprecated] is a shorthand for deprecating until
+ * an unspecified "next release" without migration instructions.
+ *
+ * The intent of the `@Deprecated` annotation is to inform users of a feature
+ * that they should change their code, even if it is currently still working
+ * correctly.
+ *
+ * A deprecated feature is scheduled to be removed at a later time, possibly
+ * specified in [message]. A deprecated feature should not be used, code using
+ * it will break at some point in the future. If existing code is using the
+ * feature it should be rewritten to not use the deprecated feature.
+ *
+ * A deprecated feature should document how the same effect can be achieved in
+ * [message], so the programmer knows how to rewrite the code.
+ *
+ * The `@Deprecated` annotation applies to libraries, top-level declarations
+ * (variables, getters, setters, functions, classes and typedefs),
+ * class-level declarations (variables, getters, setters, methods, operators or
+ * constructors, whether static or not), named optional arguments and
+ * trailing optional positional parameters.
+ *
+ * Deprecation is transitive:
+ *
+ *  - If a library is deprecated, so is every member of it.
+ *  - If a class is deprecated, so is every member of it.
+ *  - If a variable is deprecated, so are its implicit getter and setter.
+ *
+ *
+ * A tool that processes Dart source code may report when:
+ *
+ * - the code imports a deprecated library.
+ * - the code exports a deprecated library, or any deprecated member of
+ *   a non-deprecated library.
+ * - the code refers statically to a deprecated declaration.
+ * - the code dynamically uses a member of an object with a statically known
+ *   type, where the member is deprecated on the static type of the object.
+ * - the code dynamically calls a method with an argument where the
+ *   corresponding optional parameter is deprecated on the object's static type.
+ *
+ *
+ * If the deprecated use is inside a library, class or method which is itself
+ * deprecated, the tool should not bother the user about it.
+ * A deprecated feature is expected to use other deprecated features.
+ */
+class Deprecated {
+  /**
+   * Message provided to the user when they use the deprecated feature.
+   *
+   * The message should explain how to migrate away from the feature if an
+   * alternative is available, and when the deprecated feature is expected to be
+   * removed.
+   */
+  final String message;
+
+  /**
+   * Create a deprecation annotation which specifies the migration path and
+   * expiration of the annotated feature.
+   *
+   * The [message] argument should be readable by programmers, and should state
+   * an alternative feature (if available) as well as when an annotated feature
+   * is expected to be removed.
+   */
+  const Deprecated(this.message);
+
+  @Deprecated('Use `message` instead. Will be removed in Dart 3.0.0')
+  String get expires => message;
+
+  String toString() => "Deprecated feature: $message";
+}
+
+/**
+ * Marks a feature as [Deprecated] until the next release.
+ */
+const Deprecated deprecated = Deprecated("next release");
+
+class _Override {
+  const _Override();
+}
+
+/**
+ * The annotation `@override` marks an instance member as overriding a
+ * superclass member with the same name.
+ *
+ * The annotation applies to instance methods, getters and setters, and to
+ * instance fields, where it means that the implicit getter and setter of the
+ * field is marked as overriding, but the field itself is not.
+ *
+ * The intent of the `@override` notation is to catch situations where a
+ * superclass renames a member, and an independent subclass which used to
+ * override the member, could silently continue working using the
+ * superclass implementation.
+ *
+ * The editor, or a similar tool aimed at the programmer, may report if no
+ * declaration of an annotated member is inherited by the class from either a
+ * superclass or an interface.
+ *
+ * Use the `@override` annotation judiciously and only for methods where
+ * the superclass is not under the programmer's control, the superclass is in a
+ * different library or package, and it is not considered stable.
+ * In any case, the use of `@override` is optional.
+ *
+ * For example, the annotation is intentionally not used in the Dart platform
+ * libraries, since they only depend on themselves.
+ */
+const Object override = _Override();
+
+/**
+ * An annotation class that was used during development of Dart 2.
+ *
+ * Should not be used any more.
+ */
+@deprecated
+class Provisional {
+  String get message => null;
+  const Provisional({String message});
+}
+
+/**
+ * An annotation that was used during development of Dart 2.
+ *
+ * Should not be used any more.
+ */
+@deprecated
+const Null provisional = null;
+
+class _Proxy {
+  const _Proxy();
+}
+
+/**
+ * This annotation is deprecated and will be removed in Dart 2.
+ *
+ * Dart 2 has a more restrictive type system than Dart 1, and it requires
+ * method access to be either through a known interface or by using
+ * dynamic invocations. The original intent of `@proxy` (to implement a class
+ * that isn't known statically, as documented at the end of this text),
+ * is not supported by Dart 2.
+ * To continue to perform dynamic invocations on an object,
+ * it should be accessed through a reference of type `dynamic`.
+ *
+ * The annotation `@proxy` marks a class as implementing members dynamically
+ * through `noSuchMethod`.
+ *
+ * The annotation applies to any class. It is inherited by subclasses from both
+ * superclass and interfaces.
+ *
+ * If a class is annotated with `@proxy`, or it implements any class that is
+ * annotated, then all member accesses are allowed on an object of that type.
+ * As such, it is not a static type warning to access any member of the object
+ * which is not implemented by the class, or to call a method with a different
+ * number of parameters than it is declared with.
+ *
+ * The annotation does not change which classes the annotated class implements,
+ * and does not prevent static warnings for assigning an object to a variable
+ * with a static type not implemented by the object.
+ *
+ * The suppression of warnings only affect static type warnings about
+ * member access.
+ * The runtime type of the object is unaffected.
+ * It is not considered to implement any special interfaces,
+ * so assigning it to a typed variable may fail in checked mode,
+ * and testing it with the `is` operator
+ * will only return true for types it actually implements or extends.
+ * Accessing a member which isn't implemented by the class
+ * will cause the `noSuchMethod` method to be called normally,
+ * the `@proxy` annotation merely states the intent to handle (some of) those
+ * `noSuchMethod` calls gracefully.
+ *
+ * A class that marked as `@proxy` should override the `noSuchMethod`
+ * declared on [Object].
+ *
+ * The intent of the `@proxy` notation is to create objects that implement a
+ * type (or multiple types) that are not known at compile time. If the types
+ * are known at compile time, a class can be written that implements these
+ * types.
+ */
+@deprecated
+const Object proxy = _Proxy();
+
+/**
+ * A hint to tools.
+ *
+ * Tools that work with Dart programs may accept hints to guide their behavior
+ * as `pragma` annotations on declarations.
+ * Each tool decides which hints it accepts, what they mean, and whether and
+ * how they apply to sub-parts of the annotated entity.
+ *
+ * Tools that recognize pragma hints should pick a pragma prefix to identify
+ * the tool. They should recognize any hint with a [name] starting with their
+ * prefix followed by `:` as if it was intended for that tool. A hint with a
+ * prefix for another tool should be ignored (unless compatibility with that
+ * other tool is a goal).
+ *
+ * A tool may recognize unprefixed names as well, if they would recognize that
+ * name with their own prefix in front.
+ *
+ * If the hint can be parameterized, an extra [options] object can be added as well.
+ *
+ * For example:
+ *
+ * ```dart
+ * @pragma('Tool:pragma-name', [param1, param2, ...])
+ * class Foo { }
+ *
+ * @pragma('OtherTool:other-pragma')
+ * void foo() { }
+ * ```
+ *
+ * Here class Foo is annotated with a Tool specific pragma 'pragma-name' and
+ * function foo is annotated with a pragma 'other-pragma' specific to OtherTool.
+ *
+ */
+@pragma('vm:entry-point')
+class pragma {
+  /**
+   * The name of the hint.
+   *
+   * A string that is recognized by one or more tools, or such a string prefixed
+   * by a tool identifier and a colon, which is only recognized by that
+   * particular tool.
+   */
+  final String name;
+
+  /** Optional extra data parameterizing the hint. */
+  final Object options;
+
+  /** Creates a hint named [name] with optional [options]. */
+  const factory pragma(String name, [Object options]) = pragma._;
+
+  const pragma._(this.name, [this.options]);
+}
diff --git a/sdk_nnbd/lib/core/bigint.dart b/sdk_nnbd/lib/core/bigint.dart
new file mode 100644
index 0000000..b495a9e
--- /dev/null
+++ b/sdk_nnbd/lib/core/bigint.dart
@@ -0,0 +1,414 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.core;
+
+/**
+ * An arbitrarily large integer.
+ */
+abstract class BigInt implements Comparable<BigInt> {
+  external static BigInt get zero;
+  external static BigInt get one;
+  external static BigInt get two;
+
+  /**
+   * Parses [source] as a, possibly signed, integer literal and returns its
+   * value.
+   *
+   * The [source] must be a non-empty sequence of base-[radix] digits,
+   * optionally prefixed with a minus or plus sign ('-' or '+').
+   *
+   * The [radix] must be in the range 2..36. The digits used are
+   * first the decimal digits 0..9, and then the letters 'a'..'z' with
+   * values 10 through 35. Also accepts upper-case letters with the same
+   * values as the lower-case ones.
+   *
+   * If no [radix] is given then it defaults to 10. In this case, the [source]
+   * digits may also start with `0x`, in which case the number is interpreted
+   * as a hexadecimal literal, which effectively means that the `0x` is ignored
+   * and the radix is instead set to 16.
+   *
+   * For any int `n` and radix `r`, it is guaranteed that
+   * `n == int.parse(n.toRadixString(r), radix: r)`.
+   *
+   * Throws a [FormatException] if the [source] is not a valid integer literal,
+   * optionally prefixed by a sign.
+   */
+  external static BigInt parse(String source, {int radix});
+
+  /**
+   * Parses [source] as a, possibly signed, integer literal and returns its
+   * value.
+   *
+   * As [parse] except that this method returns `null` if the input is not
+   * valid
+   */
+  external static BigInt tryParse(String source, {int radix});
+
+  /// Allocates a big integer from the provided [value] number.
+  external factory BigInt.from(num value);
+
+  /**
+   * Returns the absolute value of this integer.
+   *
+   * For any integer `x`, the result is the same as `x < 0 ? -x : x`.
+   */
+  BigInt abs();
+
+  /**
+   * Return the negative value of this integer.
+   *
+   * The result of negating an integer always has the opposite sign, except
+   * for zero, which is its own negation.
+   */
+  BigInt operator -();
+
+  /// Addition operator.
+  BigInt operator +(BigInt other);
+
+  /// Subtraction operator.
+  BigInt operator -(BigInt other);
+
+  /// Multiplication operator.
+  BigInt operator *(BigInt other);
+
+  /// Division operator.
+  double operator /(BigInt other);
+
+  /**
+   * Truncating division operator.
+   *
+   * Performs a truncating integer division, where the remainder is discarded.
+   *
+   * The remainder can be computed using the [remainder] method.
+   *
+   * Examples:
+   * ```
+   * var seven = new BigInt.from(7);
+   * var three = new BigInt.from(3);
+   * seven ~/ three;    // => 2
+   * (-seven) ~/ three; // => -2
+   * seven ~/ -three;   // => -2
+   * seven.remainder(three);    // => 1
+   * (-seven).remainder(three); // => -1
+   * seven.remainder(-three);   // => 1
+   * ```
+   */
+  BigInt operator ~/(BigInt other);
+
+  /**
+   * Euclidean modulo operator.
+   *
+   * Returns the remainder of the Euclidean division. The Euclidean division of
+   * two integers `a` and `b` yields two integers `q` and `r` such that
+   * `a == b * q + r` and `0 <= r < b.abs()`.
+   *
+   * The sign of the returned value `r` is always positive.
+   *
+   * See [remainder] for the remainder of the truncating division.
+   */
+  BigInt operator %(BigInt other);
+
+  /**
+   * Returns the remainder of the truncating division of `this` by [other].
+   *
+   * The result `r` of this operation satisfies:
+   * `this == (this ~/ other) * other + r`.
+   * As a consequence the remainder `r` has the same sign as the divider `this`.
+   */
+  BigInt remainder(BigInt other);
+
+  /**
+   * Shift the bits of this integer to the left by [shiftAmount].
+   *
+   * Shifting to the left makes the number larger, effectively multiplying
+   * the number by `pow(2, shiftIndex)`.
+   *
+   * There is no limit on the size of the result. It may be relevant to
+   * limit intermediate values by using the "and" operator with a suitable
+   * mask.
+   *
+   * It is an error if [shiftAmount] is negative.
+   */
+  BigInt operator <<(int shiftAmount);
+
+  /**
+   * Shift the bits of this integer to the right by [shiftAmount].
+   *
+   * Shifting to the right makes the number smaller and drops the least
+   * significant bits, effectively doing an integer division by
+   *`pow(2, shiftIndex)`.
+   *
+   * It is an error if [shiftAmount] is negative.
+   */
+  BigInt operator >>(int shiftAmount);
+
+  /**
+   * Bit-wise and operator.
+   *
+   * Treating both `this` and [other] as sufficiently large two's component
+   * integers, the result is a number with only the bits set that are set in
+   * both `this` and [other]
+   *
+   * Of both operands are negative, the result is negative, otherwise
+   * the result is non-negative.
+   */
+  BigInt operator &(BigInt other);
+
+  /**
+   * Bit-wise or operator.
+   *
+   * Treating both `this` and [other] as sufficiently large two's component
+   * integers, the result is a number with the bits set that are set in either
+   * of `this` and [other]
+   *
+   * If both operands are non-negative, the result is non-negative,
+   * otherwise the result us negative.
+   */
+  BigInt operator |(BigInt other);
+
+  /**
+   * Bit-wise exclusive-or operator.
+   *
+   * Treating both `this` and [other] as sufficiently large two's component
+   * integers, the result is a number with the bits set that are set in one,
+   * but not both, of `this` and [other]
+   *
+   * If the operands have the same sign, the result is non-negative,
+   * otherwise the result is negative.
+   */
+  BigInt operator ^(BigInt other);
+
+  /**
+   * The bit-wise negate operator.
+   *
+   * Treating `this` as a sufficiently large two's component integer,
+   * the result is a number with the opposite bits set.
+   *
+   * This maps any integer `x` to `-x - 1`.
+   */
+  BigInt operator ~();
+
+  /** Relational less than operator. */
+  bool operator <(BigInt other);
+
+  /** Relational less than or equal operator. */
+  bool operator <=(BigInt other);
+
+  /** Relational greater than operator. */
+  bool operator >(BigInt other);
+
+  /** Relational greater than or equal operator. */
+  bool operator >=(BigInt other);
+
+  /**
+   * Compares this to `other`.
+   *
+   * Returns a negative number if `this` is less than `other`, zero if they are
+   * equal, and a positive number if `this` is greater than `other`.
+   */
+  int compareTo(BigInt other);
+
+  /**
+   * Returns the minimum number of bits required to store this big integer.
+   *
+   * The number of bits excludes the sign bit, which gives the natural length
+   * for non-negative (unsigned) values.  Negative values are complemented to
+   * return the bit position of the first bit that differs from the sign bit.
+   *
+   * To find the number of bits needed to store the value as a signed value,
+   * add one, i.e. use `x.bitLength + 1`.
+   *
+   * ```
+   * x.bitLength == (-x-1).bitLength
+   *
+   * new BigInt.from(3).bitLength == 2;   // 00000011
+   * new BigInt.from(2).bitLength == 2;   // 00000010
+   * new BigInt.from(1).bitLength == 1;   // 00000001
+   * new BigInt.from(0).bitLength == 0;   // 00000000
+   * new BigInt.from(-1).bitLength == 0;  // 11111111
+   * new BigInt.from(-2).bitLength == 1;  // 11111110
+   * new BigInt.from(-3).bitLength == 2;  // 11111101
+   * new BigInt.from(-4).bitLength == 2;  // 11111100
+   * ```
+   */
+  int get bitLength;
+
+  /**
+   * Returns the sign of this big integer.
+   *
+   * Returns 0 for zero, -1 for values less than zero and
+   * +1 for values greater than zero.
+   */
+  int get sign;
+
+  /// Whether this big integer is even.
+  bool get isEven;
+
+  /// Whether this big integer is odd.
+  bool get isOdd;
+
+  /// Whether this number is negative.
+  bool get isNegative;
+
+  /**
+   * Returns `this` to the power of [exponent].
+   *
+   * Returns [one] if the [exponent] equals 0.
+   *
+   * The [exponent] must otherwise be positive.
+   *
+   * The result is always equal to the mathematical result of this to the power
+   * [exponent], only limited by the available memory.
+   */
+  BigInt pow(int exponent);
+
+  /**
+   * Returns this integer to the power of [exponent] modulo [modulus].
+   *
+   * The [exponent] must be non-negative and [modulus] must be
+   * positive.
+   */
+  BigInt modPow(BigInt exponent, BigInt modulus);
+
+  /**
+   * Returns the modular multiplicative inverse of this big integer
+   * modulo [modulus].
+   *
+   * The [modulus] must be positive.
+   *
+   * It is an error if no modular inverse exists.
+   */
+  // Returns 1/this % modulus, with modulus > 0.
+  BigInt modInverse(BigInt modulus);
+
+  /**
+   * Returns the greatest common divisor of this big integer and [other].
+   *
+   * If either number is non-zero, the result is the numerically greatest
+   * integer dividing both `this` and `other`.
+   *
+   * The greatest common divisor is independent of the order,
+   * so `x.gcd(y)` is  always the same as `y.gcd(x)`.
+   *
+   * For any integer `x`, `x.gcd(x)` is `x.abs()`.
+   *
+   * If both `this` and `other` is zero, the result is also zero.
+   */
+  BigInt gcd(BigInt other);
+
+  /**
+   * Returns the least significant [width] bits of this big integer as a
+   * non-negative number (i.e. unsigned representation).  The returned value has
+   * zeros in all bit positions higher than [width].
+   *
+   * ```
+   * new BigInt.from(-1).toUnsigned(5) == 31   // 11111111  ->  00011111
+   * ```
+   *
+   * This operation can be used to simulate arithmetic from low level languages.
+   * For example, to increment an 8 bit quantity:
+   *
+   * ```
+   * q = (q + 1).toUnsigned(8);
+   * ```
+   *
+   * `q` will count from `0` up to `255` and then wrap around to `0`.
+   *
+   * If the input fits in [width] bits without truncation, the result is the
+   * same as the input.  The minimum width needed to avoid truncation of `x` is
+   * given by `x.bitLength`, i.e.
+   *
+   * ```
+   * x == x.toUnsigned(x.bitLength);
+   * ```
+   */
+  BigInt toUnsigned(int width);
+
+  /**
+   * Returns the least significant [width] bits of this integer, extending the
+   * highest retained bit to the sign.  This is the same as truncating the value
+   * to fit in [width] bits using an signed 2-s complement representation.  The
+   * returned value has the same bit value in all positions higher than [width].
+   *
+   * ```
+   * var big15 = new BigInt.from(15);
+   * var big16 = new BigInt.from(16);
+   * var big239 = new BigInt.from(239);
+   *                                      V--sign bit-V
+   * big16.toSigned(5) == -big16   //  00010000 -> 11110000
+   * big239.toSigned(5) == big15   //  11101111 -> 00001111
+   *                                      ^           ^
+   * ```
+   *
+   * This operation can be used to simulate arithmetic from low level languages.
+   * For example, to increment an 8 bit signed quantity:
+   *
+   * ```
+   * q = (q + 1).toSigned(8);
+   * ```
+   *
+   * `q` will count from `0` up to `127`, wrap to `-128` and count back up to
+   * `127`.
+   *
+   * If the input value fits in [width] bits without truncation, the result is
+   * the same as the input.  The minimum width needed to avoid truncation of `x`
+   * is `x.bitLength + 1`, i.e.
+   *
+   * ```
+   * x == x.toSigned(x.bitLength + 1);
+   * ```
+   */
+  BigInt toSigned(int width);
+
+  /**
+   * Whether this big integer can be represented as an `int` without losing
+   * precision.
+   *
+   * Warning: this function may give a different result on
+   * dart2js, dev compiler, and the VM, due to the differences in
+   * integer precision.
+   */
+  bool get isValidInt;
+
+  /**
+   * Returns this [BigInt] as an [int].
+   *
+   * If the number does not fit, clamps to the max (or min)
+   * integer.
+   *
+   * Warning: the clamping behaves differently on dart2js, dev
+   * compiler, and the VM, due to the differences in integer
+   * precision.
+   */
+  int toInt();
+
+  /**
+   * Returns this [BigInt] as a [double].
+   *
+   * If the number is not representable as a [double], an
+   * approximation is returned. For numerically large integers, the
+   * approximation may be infinite.
+   */
+  double toDouble();
+
+  /**
+   * Returns a String-representation of this integer.
+   *
+   * The returned string is parsable by [parse].
+   * For any `BigInt` `i`, it is guaranteed that
+   * `i == BigInt.parse(i.toString())`.
+   */
+  String toString();
+
+  /**
+   * Converts [this] to a string representation in the given [radix].
+   *
+   * In the string representation, lower-case letters are used for digits above
+   * '9', with 'a' being 10 an 'z' being 35.
+   *
+   * The [radix] argument must be an integer in the range 2 to 36.
+   */
+  String toRadixString(int radix);
+}
diff --git a/sdk_nnbd/lib/core/bool.dart b/sdk_nnbd/lib/core/bool.dart
new file mode 100644
index 0000000..5ed1065
--- /dev/null
+++ b/sdk_nnbd/lib/core/bool.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 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 dart.core;
+
+/**
+ * The reserved words `true` and `false` denote objects that are the only two
+ * instances of this class.
+ *
+ * It is a compile-time error for a class to attempt to extend or implement
+ * bool.
+ */
+@pragma("vm:entry-point")
+class bool {
+  /**
+   * Returns the boolean value of the environment declaration [name].
+   *
+   * The boolean value of the declaration is `true` if the declared value is
+   * the string `"true"`, and `false` if the value is `"false"`.
+   *
+   * In all other cases, including when there is no declaration for `name`,
+   * the result is the [defaultValue].
+   *
+   * The result is the same as would be returned by:
+   * ```dart
+   * (const String.fromEnvironment(name) == "true")
+   *     ? true
+   *     : (const String.fromEnvironment(name) == "false")
+   *         ? false
+   *         : defaultValue
+   * ```
+   * Example:
+   * ```dart
+   * const loggingFlag = const bool.fromEnvironment("logging");
+   * ```
+   * If you want to use a different truth-string than `"true"`, you can use the
+   * [String.fromEnvironment] constructor directly:
+   * ```dart
+   * const isLoggingOn = (const String.fromEnvironment("logging") == "on");
+   * ```
+   */
+  // The .fromEnvironment() constructors are special in that we do not want
+  // users to call them using "new". We prohibit that by giving them bodies
+  // that throw, even though const constructors are not allowed to have bodies.
+  // Disable those static errors.
+  //ignore: const_constructor_with_body
+  //ignore: const_factory
+  external const factory bool.fromEnvironment(String name,
+      {bool defaultValue = false});
+
+  external int get hashCode;
+
+  /// The logical conjunction ("and") of this and [other].
+  ///
+  /// Returns `true` if both this and [other] are `true`, and `false` otherwise.
+  //TODO(lrn): Remove "as bool" in Dart 2.
+  @Since("2.1")
+  bool operator &(bool other) => (other as bool) && this;
+
+  /// The logical disjunction ("inclusive or") of this and [other].
+  ///
+  /// Returns `true` if either this or [other] is `true`, and `false` otherwise.
+  @Since("2.1")
+  bool operator |(bool other) => (other as bool) || this;
+
+  /// The logical exclusive disjunction ("exclusive or") of this and [other].
+  ///
+  /// Returns whether this and [other] are neither both `true` nor both `false`.
+  @Since("2.1")
+  bool operator ^(bool other) => !(other as bool) == this;
+
+  /**
+   * Returns either `"true"` for `true` and `"false"` for `false`.
+   */
+  String toString() {
+    return this ? "true" : "false";
+  }
+}
diff --git a/sdk_nnbd/lib/core/comparable.dart b/sdk_nnbd/lib/core/comparable.dart
new file mode 100644
index 0000000..835aa34
--- /dev/null
+++ b/sdk_nnbd/lib/core/comparable.dart
@@ -0,0 +1,94 @@
+// 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.
+
+part of dart.core;
+
+/**
+ * The signature of a generic comparison function.
+ *
+ * A comparison function represents an ordering on a type of objects.
+ * A total ordering on a type means that for two values, either they
+ * are equal or one is greater than the other (and the latter must then be
+ * smaller than the former).
+ *
+ * A [Comparator] function represents such a total ordering by returning
+ *
+ * * a negative integer if [a] is smaller than [b],
+ * * zero if [a] is equal to [b], and
+ * * a positive integer if [a] is greater than [b].
+ */
+typedef Comparator<T> = int Function(T a, T b);
+
+/**
+ * Interface used by types that have an intrinsic ordering.
+ *
+ * The [compareTo] operation defines a total ordering of objects,
+ * which can be used for ordering and sorting.
+ *
+ * The [Comparable] interface should be used for the natural ordering of a type.
+ * If a type can be ordered in more than one way,
+ * and none of them is the obvious natural ordering,
+ * then it might be better not to use the [Comparable] interface,
+ * and to provide separate [Comparator]s instead.
+ *
+ * It is recommended that the order of a [Comparable] agrees
+ * with its operator [operator ==] equality (`a.compareTo(b) == 0` iff `a == b`),
+ * but this is not a requirement.
+ * For example, [double] and [DateTime] have `compareTo` methods
+ * that do not agree with operator [operator ==].
+ * For doubles the [compareTo] method is more precise than the equality,
+ * and for [DateTime] it is less precise.
+ *
+ * Examples:
+ *
+ *      (0.0).compareTo(-0.0);  // => 1
+ *      0.0 == -0.0;            // => true
+ *      var dt = new DateTime.now();
+ *      var dt2 = dt.toUtc();
+ *      dt == dt2;              // => false
+ *      dt.compareTo(dt2);      // => 0
+ *
+ * The [Comparable] interface does not imply the existence
+ * of the comparison operators `<`, `<=`, `>` and `>=`.
+ * These should only be defined
+ * if the ordering is a less-than/greater-than ordering,
+ * that is, an ordering where you would naturally
+ * use the words "less than" about the order of two elements.
+ *
+ * If the equality operator and [compareTo] disagree,
+ * the comparison operators should follow the equality operator,
+ * and will likely also disagree with [compareTo].
+ * Otherwise they should match the [compareTo] method,
+ * so that `a < b` iff `a.compareTo(b) < 0`.
+ *
+ * The [double] class defines comparison operators
+ * that are compatible with equality.
+ * The operators differ from `double.compareTo` on -0.0 and NaN.
+ *
+ * The [DateTime] class has no comparison operators, instead it has the more
+ * precisely named [DateTime.isBefore] and [DateTime.isAfter].
+ */
+abstract class Comparable<T> {
+  /**
+   * Compares this object to another [Comparable]
+   *
+   * Returns a value like a [Comparator] when comparing `this` to [other].
+   * That is, it returns a negative integer if `this` is ordered before [other],
+   * a positive integer if `this` is ordered after [other],
+   * and zero if `this` and [other] are ordered together.
+   *
+   * The [other] argument must be a value that is comparable to this object.
+   */
+  int compareTo(T other);
+
+  /**
+   * A [Comparator] that compares one comparable to another.
+   *
+   * It returns the result of `a.compareTo(b)`.
+   *
+   * This utility function is used as the default comparator
+   * for ordering collections, for example in the [List] sort function.
+   */
+  static int compare(Comparable a, Comparable b) => a.compareTo(b);
+}
diff --git a/sdk_nnbd/lib/core/core.dart b/sdk_nnbd/lib/core/core.dart
new file mode 100644
index 0000000..9ab8ed4
--- /dev/null
+++ b/sdk_nnbd/lib/core/core.dart
@@ -0,0 +1,208 @@
+// Copyright (c) 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.
+
+/**
+ *
+ * Built-in types, collections,
+ * and other core functionality for every Dart program.
+ *
+ * This library is automatically imported.
+ *
+ * Some classes in this library,
+ * such as [String] and [num],
+ * support Dart's built-in data types.
+ * Other classes, such as [List] and [Map], provide data structures
+ * for managing collections of objects.
+ * And still other classes represent commonly used types of data
+ * such as URIs, dates and times, and errors.
+ *
+ * ## Numbers and booleans
+ *
+ * [int] and [double] provide support for Dart's built-in numerical data types:
+ * integers and double-precision floating point numbers, respectively.
+ * An object of type [bool] is either true or false.
+ * Variables of these types can be constructed from literals:
+ *
+ *     int meaningOfLife = 42;
+ *     double valueOfPi  = 3.141592;
+ *     bool visible      = true;
+ *
+ * ## Strings and regular expressions
+ *
+ * A [String] is immutable and represents a sequence of characters.
+ *
+ *     String shakespeareQuote = "All the world's a stage, ...";
+ *
+ * [StringBuffer] provides a way to construct strings efficiently.
+ *
+ *     StringBuffer moreShakespeare = new StringBuffer();
+ *     moreShakespeare.write('And all the men and women ');
+ *     moreShakespeare.write('merely players; ...');
+ *
+ * The String and StringBuffer classes implement string concatenation,
+ * interpolation, and other string manipulation features.
+ *
+ *     String philosophy = 'Live on ';
+ *     String get palindrome => philosophy + philosophy.split('').reversed.join();
+ *
+ * [RegExp] implements Dart regular expressions,
+ * which provide a grammar for matching patterns within text.
+ * For example, here's a regular expression that matches
+ * a string of one or more digits:
+ *
+ *     var numbers = new RegExp(r'\d+');
+ *
+ * Dart regular expressions have the same syntax and semantics as
+ * JavaScript regular expressions. See
+ * <http://ecma-international.org/ecma-262/5.1/#sec-15.10>
+ * for the specification of JavaScript regular expressions.
+ *
+ * ## Collections
+ *
+ * The dart:core library provides basic collections,
+ * such as [List], [Map], and [Set].
+ *
+ * A List is an ordered collection of objects, with a length.
+ * Lists are sometimes called arrays.
+ * Use a List when you need to access objects by index.
+ *
+ *     List superheroes = [ 'Batman', 'Superman', 'Harry Potter' ];
+ *
+ * A Set is an unordered collection of unique objects.
+ * You cannot get an item by index (position).
+ * Adding a duplicate item has no effect.
+ *
+ *     Set villains = new Set();
+ *     villains.add('Joker');
+ *     villains.addAll( ['Lex Luther', 'Voldemort'] );
+ *
+ * A Map is an unordered collection of key-value pairs.
+ * Maps are sometimes called associative arrays because
+ * maps associate a key to some value for easy retrieval.
+ * Keys are unique.
+ * Use a Map when you need to access objects
+ * by a unique identifier.
+ *
+ *     Map sidekicks = { 'Batman': 'Robin',
+ *                       'Superman': 'Lois Lane',
+ *                       'Harry Potter': 'Ron and Hermione' };
+ *
+ * In addition to these classes,
+ * dart:core contains [Iterable],
+ * an interface that defines functionality
+ * common in collections of objects.
+ * Examples include the ability
+ * to run a function on each element in the collection,
+ * to apply a test to each element,
+ * to retrieve an object, and to determine length.
+ *
+ * Iterable is implemented by List and Set,
+ * and used by Map for its keys and values.
+ *
+ * For other kinds of collections, check out the
+ * `dart:collection` library.
+ *
+ * ## Date and time
+ *
+ * Use [DateTime] to represent a point in time
+ * and [Duration] to represent a span of time.
+ *
+ * You can create DateTime objects with constructors
+ * or by parsing a correctly formatted string.
+ *
+ *     DateTime now = new DateTime.now();
+ *     DateTime berlinWallFell = new DateTime(1989, 11, 9);
+ *     DateTime moonLanding = DateTime.parse("1969-07-20");
+ *
+ * Create a Duration object specifying the individual time units.
+ *
+ *     Duration timeRemaining = new Duration(hours:56, minutes:14);
+ *
+ * In addition to DateTime and Duration,
+ * dart:core contains the [Stopwatch] class for measuring elapsed time.
+ *
+ * ## Uri
+ *
+ * A [Uri] object represents a uniform resource identifier,
+ * which identifies a resource on the web.
+ *
+ *     Uri dartlang = Uri.parse('http://dartlang.org/');
+ *
+ * ## Errors
+ *
+ * The [Error] class represents the occurrence of an error
+ * during runtime.
+ * Subclasses of this class represent specific kinds of errors.
+ *
+ * ## Other documentation
+ *
+ * For more information about how to use the built-in types, refer to [Built-in
+ * Types](http://www.dartlang.org/docs/dart-up-and-running/contents/ch02.html#built-in-types)
+ * in Chapter 2 of
+ * [Dart: Up and Running](http://www.dartlang.org/docs/dart-up-and-running/).
+ *
+ * Also, see [dart:core - Numbers, Collections, Strings, and
+ * More](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartcore---numbers-collections-strings-and-more)
+ * for more coverage of classes in this package.
+ *
+ * The
+ * [Dart Language Specification](http://www.dartlang.org/docs/spec/)
+ * provides technical details.
+ *
+ * {@category Core}
+ */
+library dart.core;
+
+import "dart:collection";
+import "dart:_internal" hide Symbol, LinkedList, LinkedListEntry;
+import "dart:_internal" as internal show Symbol;
+import "dart:convert"
+    show
+        ascii,
+        base64,
+        Base64Codec,
+        Encoding,
+        latin1,
+        StringConversionSink,
+        utf8;
+import "dart:math" show Random; // Used by List.shuffle.
+import "dart:typed_data" show Uint8List, Uint16List, Endian;
+
+@Since("2.1")
+export "dart:async" show Future, Stream;
+
+part "annotations.dart";
+part "bigint.dart";
+part "bool.dart";
+part "comparable.dart";
+part "date_time.dart";
+part "double.dart";
+part "duration.dart";
+part "errors.dart";
+part "exceptions.dart";
+part "expando.dart";
+part "function.dart";
+part "identical.dart";
+part "int.dart";
+part "invocation.dart";
+part "iterable.dart";
+part "iterator.dart";
+part "list.dart";
+part "map.dart";
+part "null.dart";
+part "num.dart";
+part "object.dart";
+part "pattern.dart";
+part "print.dart";
+part "regexp.dart";
+part "set.dart";
+part "sink.dart";
+part "stacktrace.dart";
+part "stopwatch.dart";
+part "string.dart";
+part "string_buffer.dart";
+part "string_sink.dart";
+part "symbol.dart";
+part "type.dart";
+part "uri.dart";
diff --git a/sdk_nnbd/lib/core/core_sources.gni b/sdk_nnbd/lib/core/core_sources.gni
new file mode 100644
index 0000000..ce2785e
--- /dev/null
+++ b/sdk_nnbd/lib/core/core_sources.gni
@@ -0,0 +1,43 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+core_sdk_sources = [
+  "core.dart",
+
+  # The above file needs to be first as it lists the parts below.
+  "annotations.dart",
+  "bigint.dart",
+  "bool.dart",
+  "comparable.dart",
+  "date_time.dart",
+  "double.dart",
+  "duration.dart",
+  "errors.dart",
+  "exceptions.dart",
+  "expando.dart",
+  "function.dart",
+  "identical.dart",
+  "int.dart",
+  "invocation.dart",
+  "iterable.dart",
+  "iterator.dart",
+  "list.dart",
+  "map.dart",
+  "null.dart",
+  "num.dart",
+  "object.dart",
+  "pattern.dart",
+  "print.dart",
+  "regexp.dart",
+  "set.dart",
+  "sink.dart",
+  "stacktrace.dart",
+  "stopwatch.dart",
+  "string.dart",
+  "string_buffer.dart",
+  "string_sink.dart",
+  "symbol.dart",
+  "type.dart",
+  "uri.dart",
+]
diff --git a/sdk_nnbd/lib/core/date_time.dart b/sdk_nnbd/lib/core/date_time.dart
new file mode 100644
index 0000000..dd242de
--- /dev/null
+++ b/sdk_nnbd/lib/core/date_time.dart
@@ -0,0 +1,873 @@
+// 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.
+
+part of dart.core;
+
+/**
+ * An instant in time, such as July 20, 1969, 8:18pm GMT.
+ *
+ * DateTimes can represent time values that are at a distance of at most
+ * 100,000,000 days from epoch (1970-01-01 UTC): -271821-04-20 to 275760-09-13.
+ *
+ * Create a DateTime object by using one of the constructors
+ * or by parsing a correctly formatted string,
+ * which complies with a subset of ISO 8601.
+ * Note that hours are specified between 0 and 23,
+ * as in a 24-hour clock.
+ * For example:
+ *
+ * ```
+ * var now = new DateTime.now();
+ * var berlinWallFell = new DateTime.utc(1989, 11, 9);
+ * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");  // 8:18pm
+ * ```
+ *
+ * A DateTime object is anchored either in the UTC time zone
+ * or in the local time zone of the current computer
+ * when the object is created.
+ *
+ * Once created, neither the value nor the time zone
+ * of a DateTime object may be changed.
+ *
+ * You can use properties to get
+ * the individual units of a DateTime object.
+ *
+ * ```
+ * assert(berlinWallFell.month == 11);
+ * assert(moonLanding.hour == 20);
+ * ```
+ *
+ * For convenience and readability,
+ * the DateTime class provides a constant for each day and month
+ * name - for example, [august] and [friday].
+ * You can use these constants to improve code readability:
+ *
+ * ```
+ * var berlinWallFell = new DateTime.utc(1989, DateTime.november, 9);
+ * assert(berlinWallFell.weekday == DateTime.thursday);
+ * ```
+ *
+ * Day and month values begin at 1, and the week starts on Monday.
+ * That is, the constants [january] and [monday] are both 1.
+ *
+ * ## Working with UTC and local time
+ *
+ * A DateTime object is in the local time zone
+ * unless explicitly created in the UTC time zone.
+ *
+ * ```
+ * var dDay = new DateTime.utc(1944, 6, 6);
+ * ```
+ *
+ * Use [isUtc] to determine whether a DateTime object is based in UTC.
+ * Use the methods [toLocal] and [toUtc]
+ * to get the equivalent date/time value specified in the other time zone.
+ * Use [timeZoneName] to get an abbreviated name of the time zone
+ * for the DateTime object.
+ * To find the difference
+ * between UTC and the time zone of a DateTime object
+ * call [timeZoneOffset].
+ *
+ * ## Comparing DateTime objects
+ *
+ * The DateTime class contains several handy methods,
+ * such as [isAfter], [isBefore], and [isAtSameMomentAs],
+ * for comparing DateTime objects.
+ *
+ * ```
+ * assert(berlinWallFell.isAfter(moonLanding) == true);
+ * assert(berlinWallFell.isBefore(moonLanding) == false);
+ * ```
+ *
+ * ## Using DateTime with Duration
+ *
+ * Use the [add] and [subtract] methods with a [Duration] object
+ * to create a new DateTime object based on another.
+ * For example, to find the date that is sixty days (24 * 60 hours) after today,
+ * write:
+ *
+ * ```
+ * var now = new DateTime.now();
+ * var sixtyDaysFromNow = now.add(new Duration(days: 60));
+ * ```
+ *
+ * To find out how much time is between two DateTime objects use
+ * [difference], which returns a [Duration] object:
+ *
+ * ```
+ * var difference = berlinWallFell.difference(moonLanding);
+ * assert(difference.inDays == 7416);
+ * ```
+ *
+ * The difference between two dates in different time zones
+ * is just the number of nanoseconds between the two points in time.
+ * It doesn't take calendar days into account.
+ * That means that the difference between two midnights in local time may be
+ * less than 24 hours times the number of days between them,
+ * if there is a daylight saving change in between.
+ * If the difference above is calculated using Australian local time, the
+ * difference is 7415 days and 23 hours, which is only 7415 whole days as
+ * reported by `inDays`.
+ *
+ * ## Other resources
+ *
+ * See [Duration] to represent a span of time.
+ * See [Stopwatch] to measure timespans.
+ *
+ * The DateTime class does not provide internationalization.
+ * To internationalize your code, use
+ * the [intl](https://pub.dartlang.org/packages/intl) package.
+ *
+ */
+class DateTime implements Comparable<DateTime> {
+  // Weekday constants that are returned by [weekday] method:
+  static const int monday = 1;
+  static const int tuesday = 2;
+  static const int wednesday = 3;
+  static const int thursday = 4;
+  static const int friday = 5;
+  static const int saturday = 6;
+  static const int sunday = 7;
+  static const int daysPerWeek = 7;
+
+  // Month constants that are returned by the [month] getter.
+  static const int january = 1;
+  static const int february = 2;
+  static const int march = 3;
+  static const int april = 4;
+  static const int may = 5;
+  static const int june = 6;
+  static const int july = 7;
+  static const int august = 8;
+  static const int september = 9;
+  static const int october = 10;
+  static const int november = 11;
+  static const int december = 12;
+  static const int monthsPerYear = 12;
+
+  /**
+   * The value of this DateTime.
+   *
+   * The content of this field is implementation dependent. On JavaScript it is
+   * equal to [millisecondsSinceEpoch]. On the VM it is equal to
+   * [microsecondsSinceEpoch].
+   */
+  final int _value;
+
+  /**
+   * True if this [DateTime] is set to UTC time.
+   *
+   * ```
+   * var dDay = new DateTime.utc(1944, 6, 6);
+   * assert(dDay.isUtc);
+   * ```
+   *
+   */
+  final bool isUtc;
+
+  /**
+   * Constructs a [DateTime] instance specified in the local time zone.
+   *
+   * For example,
+   * to create a new DateTime object representing the 7th of September 2017,
+   * 5:30pm
+   *
+   * ```
+   * var dentistAppointment = new DateTime(2017, 9, 7, 17, 30);
+   * ```
+   */
+  DateTime(int year,
+      [int month = 1,
+      int day = 1,
+      int hour = 0,
+      int minute = 0,
+      int second = 0,
+      int millisecond = 0,
+      int microsecond = 0])
+      : this._internal(year, month, day, hour, minute, second, millisecond,
+            microsecond, false);
+
+  /**
+   * Constructs a [DateTime] instance specified in the UTC time zone.
+   *
+   * ```
+   * var moonLanding = new DateTime.utc(1969, 7, 20, 20, 18, 04);
+   * ```
+   *
+   * When dealing with dates or historic events prefer to use UTC DateTimes,
+   * since they are unaffected by daylight-saving changes and are unaffected
+   * by the local timezone.
+   */
+  DateTime.utc(int year,
+      [int month = 1,
+      int day = 1,
+      int hour = 0,
+      int minute = 0,
+      int second = 0,
+      int millisecond = 0,
+      int microsecond = 0])
+      : this._internal(year, month, day, hour, minute, second, millisecond,
+            microsecond, true);
+
+  /**
+   * Constructs a [DateTime] instance with current date and time in the
+   * local time zone.
+   *
+   * ```
+   * var thisInstant = new DateTime.now();
+   * ```
+   */
+  DateTime.now() : this._now();
+
+  /**
+   * Constructs a new [DateTime] instance based on [formattedString].
+   *
+   * The [formattedString] must not be `null`.
+   * Throws a [FormatException] if the input string cannot be parsed.
+   *
+   * The function parses a subset of ISO 8601
+   * which includes the subset accepted by RFC 3339.
+   *
+   * The accepted inputs are currently:
+   *
+   * * A date: A signed four-to-six digit year, two digit month and
+   *   two digit day, optionally separated by `-` characters.
+   *   Examples: "19700101", "-0004-12-24", "81030-04-01".
+   * * An optional time part, separated from the date by either `T` or a space.
+   *   The time part is a two digit hour,
+   *   then optionally a two digit minutes value,
+   *   then optionally a two digit seconds value, and
+   *   then optionally a '.' or ',' followed by a one-to-six digit second fraction.
+   *   The minutes and seconds may be separated from the previous parts by a
+   *   ':'.
+   *   Examples: "12", "12:30:24.124", "12:30:24,124", "123010.50".
+   * * An optional time-zone offset part,
+   *   possibly separated from the previous by a space.
+   *   The time zone is either 'z' or 'Z', or it is a signed two digit hour
+   *   part and an optional two digit minute part. The sign must be either
+   *   "+" or "-", and can not be omitted.
+   *   The minutes may be separated from the hours by a ':'.
+   *   Examples: "Z", "-10", "+01:30", "+1130".
+   *
+   * This includes the output of both [toString] and [toIso8601String], which
+   * will be parsed back into a `DateTime` object with the same time as the
+   * original.
+   *
+   * The result is always in either local time or UTC.
+   * If a time zone offset other than UTC is specified,
+   * the time is converted to the equivalent UTC time.
+   *
+   * Examples of accepted strings:
+   *
+   * * `"2012-02-27 13:27:00"`
+   * * `"2012-02-27 13:27:00.123456z"`
+   * * `"2012-02-27 13:27:00,123456z"`
+   * * `"20120227 13:27:00"`
+   * * `"20120227T132700"`
+   * * `"20120227"`
+   * * `"+20120227"`
+   * * `"2012-02-27T14Z"`
+   * * `"2012-02-27T14+00:00"`
+   * * `"-123450101 00:00:00 Z"`: in the year -12345.
+   * * `"2002-02-27T14:00:00-0500"`: Same as `"2002-02-27T19:00:00Z"`
+   */
+  // TODO(lrn): restrict incorrect values like  2003-02-29T50:70:80.
+  // Or not, that may be a breaking change.
+  static DateTime parse(String formattedString) {
+    var re = _parseFormat;
+    Match match = re.firstMatch(formattedString);
+    if (match != null) {
+      int parseIntOrZero(String matched) {
+        if (matched == null) return 0;
+        return int.parse(matched);
+      }
+
+      // Parses fractional second digits of '.(\d{1,6})' into the combined
+      // microseconds.
+      int parseMilliAndMicroseconds(String matched) {
+        if (matched == null) return 0;
+        int length = matched.length;
+        assert(length >= 1);
+        assert(length <= 6);
+
+        int result = 0;
+        for (int i = 0; i < 6; i++) {
+          result *= 10;
+          if (i < matched.length) {
+            result += matched.codeUnitAt(i) ^ 0x30;
+          }
+        }
+        return result;
+      }
+
+      int years = int.parse(match[1]);
+      int month = int.parse(match[2]);
+      int day = int.parse(match[3]);
+      int hour = parseIntOrZero(match[4]);
+      int minute = parseIntOrZero(match[5]);
+      int second = parseIntOrZero(match[6]);
+      bool addOneMillisecond = false;
+      int milliAndMicroseconds = parseMilliAndMicroseconds(match[7]);
+      int millisecond =
+          milliAndMicroseconds ~/ Duration.microsecondsPerMillisecond;
+      int microsecond =
+          milliAndMicroseconds.remainder(Duration.microsecondsPerMillisecond);
+      bool isUtc = false;
+      if (match[8] != null) {
+        // timezone part
+        isUtc = true;
+        if (match[9] != null) {
+          // timezone other than 'Z' and 'z'.
+          int sign = (match[9] == '-') ? -1 : 1;
+          int hourDifference = int.parse(match[10]);
+          int minuteDifference = parseIntOrZero(match[11]);
+          minuteDifference += 60 * hourDifference;
+          minute -= sign * minuteDifference;
+        }
+      }
+      int value = _brokenDownDateToValue(years, month, day, hour, minute,
+          second, millisecond, microsecond, isUtc);
+      if (value == null) {
+        throw FormatException("Time out of range", formattedString);
+      }
+      return DateTime._withValue(value, isUtc: isUtc);
+    } else {
+      throw FormatException("Invalid date format", formattedString);
+    }
+  }
+
+  /**
+   * Constructs a new [DateTime] instance based on [formattedString].
+   *
+   * Works like [parse] except that this function returns `null`
+   * where [parse] would throw a [FormatException].
+   */
+  static DateTime tryParse(String formattedString) {
+    // TODO: Optimize to avoid throwing.
+    try {
+      return parse(formattedString);
+    } on FormatException {
+      return null;
+    }
+  }
+
+  static const int _maxMillisecondsSinceEpoch = 8640000000000000;
+
+  /**
+   * Constructs a new [DateTime] instance
+   * with the given [millisecondsSinceEpoch].
+   *
+   * If [isUtc] is false then the date is in the local time zone.
+   *
+   * The constructed [DateTime] represents
+   * 1970-01-01T00:00:00Z + [millisecondsSinceEpoch] ms in the given
+   * time zone (local or UTC).
+   */
+  external DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
+      {bool isUtc = false});
+
+  /**
+   * Constructs a new [DateTime] instance
+   * with the given [microsecondsSinceEpoch].
+   *
+   * If [isUtc] is false then the date is in the local time zone.
+   *
+   * The constructed [DateTime] represents
+   * 1970-01-01T00:00:00Z + [microsecondsSinceEpoch] us in the given
+   * time zone (local or UTC).
+   */
+  external DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch,
+      {bool isUtc = false});
+
+  /**
+   * Constructs a new [DateTime] instance with the given value.
+   *
+   * If [isUtc] is false then the date is in the local time zone.
+   */
+  DateTime._withValue(this._value, {this.isUtc}) {
+    if (millisecondsSinceEpoch.abs() > _maxMillisecondsSinceEpoch ||
+        (millisecondsSinceEpoch.abs() == _maxMillisecondsSinceEpoch &&
+            microsecond != 0)) {
+      throw ArgumentError(
+          "DateTime is outside valid range: $millisecondsSinceEpoch");
+    }
+    if (isUtc == null) {
+      throw ArgumentError("'isUtc' flag may not be 'null'");
+    }
+  }
+
+  /**
+   * Returns true if [other] is a [DateTime] at the same moment and in the
+   * same time zone (UTC or local).
+   *
+   * ```
+   * var dDayUtc = new DateTime.utc(1944, 6, 6);
+   * var dDayLocal = dDayUtc.toLocal();
+   *
+   * // These two dates are at the same moment, but are in different zones.
+   * assert(dDayUtc != dDayLocal);
+   * ```
+   *
+   * See [isAtSameMomentAs] for a comparison that compares moments in time
+   * independently of their zones.
+   */
+  external bool operator ==(dynamic other);
+
+  /**
+   * Returns true if [this] occurs before [other].
+   *
+   * The comparison is independent
+   * of whether the time is in UTC or in the local time zone.
+   *
+   * ```
+   * var now = new DateTime.now();
+   * var earlier = now.subtract(const Duration(seconds: 5));
+   * assert(earlier.isBefore(now));
+   * assert(!now.isBefore(now));
+   *
+   * // This relation stays the same, even when changing timezones.
+   * assert(earlier.isBefore(now.toUtc()));
+   * assert(earlier.toUtc().isBefore(now));
+   *
+   * assert(!now.toUtc().isBefore(now));
+   * assert(!now.isBefore(now.toUtc()));
+   * ```
+   */
+  external bool isBefore(DateTime other);
+
+  /**
+   * Returns true if [this] occurs after [other].
+   *
+   * The comparison is independent
+   * of whether the time is in UTC or in the local time zone.
+   *
+   * ```
+   * var now = new DateTime.now();
+   * var later = now.add(const Duration(seconds: 5));
+   * assert(later.isAfter(now));
+   * assert(!now.isBefore(now));
+   *
+   * // This relation stays the same, even when changing timezones.
+   * assert(later.isAfter(now.toUtc()));
+   * assert(later.toUtc().isAfter(now));
+   *
+   * assert(!now.toUtc().isBefore(now));
+   * assert(!now.isBefore(now.toUtc()));
+   * ```
+   */
+  external bool isAfter(DateTime other);
+
+  /**
+   * Returns true if [this] occurs at the same moment as [other].
+   *
+   * The comparison is independent of whether the time is in UTC or in the local
+   * time zone.
+   *
+   * ```
+   * var now = new DateTime.now();
+   * var later = now.add(const Duration(seconds: 5));
+   * assert(!later.isAtSameMomentAs(now));
+   * assert(now.isAtSameMomentAs(now));
+   *
+   * // This relation stays the same, even when changing timezones.
+   * assert(!later.isAtSameMomentAs(now.toUtc()));
+   * assert(!later.toUtc().isAtSameMomentAs(now));
+   *
+   * assert(now.toUtc().isAtSameMomentAs(now));
+   * assert(now.isAtSameMomentAs(now.toUtc()));
+   * ```
+   */
+  external bool isAtSameMomentAs(DateTime other);
+
+  /**
+   * Compares this DateTime object to [other],
+   * returning zero if the values are equal.
+   *
+   * Returns a negative value if this DateTime [isBefore] [other]. It returns 0
+   * if it [isAtSameMomentAs] [other], and returns a positive value otherwise
+   * (when this [isAfter] [other]).
+   */
+  external int compareTo(DateTime other);
+
+  int get hashCode => (_value ^ (_value >> 30)) & 0x3FFFFFFF;
+
+  /**
+   * Returns this DateTime value in the local time zone.
+   *
+   * Returns [this] if it is already in the local time zone.
+   * Otherwise this method is equivalent to:
+   *
+   * ```
+   * new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch,
+   *                                         isUtc: false)
+   * ```
+   */
+  DateTime toLocal() {
+    if (isUtc) {
+      return DateTime._withValue(_value, isUtc: false);
+    }
+    return this;
+  }
+
+  /**
+   * Returns this DateTime value in the UTC time zone.
+   *
+   * Returns [this] if it is already in UTC.
+   * Otherwise this method is equivalent to:
+   *
+   * ```
+   * new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch,
+   *                                         isUtc: true)
+   * ```
+   */
+  DateTime toUtc() {
+    if (isUtc) return this;
+    return DateTime._withValue(_value, isUtc: true);
+  }
+
+  static String _fourDigits(int n) {
+    int absN = n.abs();
+    String sign = n < 0 ? "-" : "";
+    if (absN >= 1000) return "$n";
+    if (absN >= 100) return "${sign}0$absN";
+    if (absN >= 10) return "${sign}00$absN";
+    return "${sign}000$absN";
+  }
+
+  static String _sixDigits(int n) {
+    assert(n < -9999 || n > 9999);
+    int absN = n.abs();
+    String sign = n < 0 ? "-" : "+";
+    if (absN >= 100000) return "$sign$absN";
+    return "${sign}0$absN";
+  }
+
+  static String _threeDigits(int n) {
+    if (n >= 100) return "${n}";
+    if (n >= 10) return "0${n}";
+    return "00${n}";
+  }
+
+  static String _twoDigits(int n) {
+    if (n >= 10) return "${n}";
+    return "0${n}";
+  }
+
+  /**
+   * Returns a human-readable string for this instance.
+   *
+   * The returned string is constructed for the time zone of this instance.
+   * The `toString()` method provides a simply formatted string.
+   * It does not support internationalized strings.
+   * Use the [intl](https://pub.dartlang.org/packages/intl) package
+   * at the pub shared packages repo.
+   *
+   * The resulting string can be parsed back using [parse].
+   */
+  String toString() {
+    String y = _fourDigits(year);
+    String m = _twoDigits(month);
+    String d = _twoDigits(day);
+    String h = _twoDigits(hour);
+    String min = _twoDigits(minute);
+    String sec = _twoDigits(second);
+    String ms = _threeDigits(millisecond);
+    String us = microsecond == 0 ? "" : _threeDigits(microsecond);
+    if (isUtc) {
+      return "$y-$m-$d $h:$min:$sec.$ms${us}Z";
+    } else {
+      return "$y-$m-$d $h:$min:$sec.$ms$us";
+    }
+  }
+
+  /**
+   * Returns an ISO-8601 full-precision extended format representation.
+   *
+   * The format is `yyyy-MM-ddTHH:mm:ss.mmmuuuZ` for UTC time, and
+   * `yyyy-MM-ddTHH:mm:ss.mmmuuu` (no trailing "Z") for local/non-UTC time,
+   * where:
+   *
+   * * `yyyy` is a, possibly negative, four digit representation of the year,
+   *   if the year is in the range -9999 to 9999,
+   *   otherwise it is a signed six digit representation of the year.
+   * * `MM` is the month in the range 01 to 12,
+   * * `dd` is the day of the month in the range 01 to 31,
+   * * `HH` are hours in the range 00 to 23,
+   * * `mm` are minutes in the range 00 to 59,
+   * * `ss` are seconds in the range 00 to 59 (no leap seconds),
+   * * `mmm` are milliseconds in the range 000 to 999, and
+   * * `uuu` are microseconds in the range 001 to 999. If [microsecond] equals
+   *   0, then this part is omitted.
+   *
+   * The resulting string can be parsed back using [parse].
+   */
+  String toIso8601String() {
+    String y =
+        (year >= -9999 && year <= 9999) ? _fourDigits(year) : _sixDigits(year);
+    String m = _twoDigits(month);
+    String d = _twoDigits(day);
+    String h = _twoDigits(hour);
+    String min = _twoDigits(minute);
+    String sec = _twoDigits(second);
+    String ms = _threeDigits(millisecond);
+    String us = microsecond == 0 ? "" : _threeDigits(microsecond);
+    if (isUtc) {
+      return "$y-$m-${d}T$h:$min:$sec.$ms${us}Z";
+    } else {
+      return "$y-$m-${d}T$h:$min:$sec.$ms$us";
+    }
+  }
+
+  /**
+   * Returns a new [DateTime] instance with [duration] added to [this].
+   *
+   * ```
+   * var today = new DateTime.now();
+   * var fiftyDaysFromNow = today.add(new Duration(days: 50));
+   * ```
+   *
+   * Notice that the duration being added is actually 50 * 24 * 60 * 60
+   * seconds. If the resulting `DateTime` has a different daylight saving offset
+   * than `this`, then the result won't have the same time-of-day as `this`, and
+   * may not even hit the calendar date 50 days later.
+   *
+   * Be careful when working with dates in local time.
+   */
+  external DateTime add(Duration duration);
+
+  /**
+   * Returns a new [DateTime] instance with [duration] subtracted from [this].
+   *
+   * ```
+   * DateTime today = new DateTime.now();
+   * DateTime fiftyDaysAgo = today.subtract(new Duration(days: 50));
+   * ```
+   *
+   * Notice that the duration being subtracted is actually 50 * 24 * 60 * 60
+   * seconds. If the resulting `DateTime` has a different daylight saving offset
+   * than `this`, then the result won't have the same time-of-day as `this`, and
+   * may not even hit the calendar date 50 days earlier.
+   *
+   * Be careful when working with dates in local time.
+   */
+  external DateTime subtract(Duration duration);
+
+  /**
+   * Returns a [Duration] with the difference between [this] and [other].
+   *
+   * ```
+   * var berlinWallFell = new DateTime.utc(1989, DateTime.november, 9);
+   * var dDay = new DateTime.utc(1944, DateTime.june, 6);
+   *
+   * Duration difference = berlinWallFell.difference(dDay);
+   * assert(difference.inDays == 16592);
+   * ```
+   *
+   * The difference is measured in seconds and fractions of seconds.
+   * The difference above counts the number of fractional seconds between
+   * midnight at the beginning of those dates.
+   * If the dates above had been in local time, not UTC, then the difference
+   * between two midnights may not be a multiple of 24 hours due to daylight
+   * saving differences.
+   *
+   * For example, in Australia, similar code using local time instead of UTC:
+   *
+   * ```
+   * var berlinWallFell = new DateTime(1989, DateTime.november, 9);
+   * var dDay = new DateTime(1944, DateTime.june, 6);
+   * Duration difference = berlinWallFell.difference(dDay);
+   * assert(difference.inDays == 16592);
+   * ```
+   * will fail because the difference is actually 16591 days and 23 hours, and
+   * [Duration.inDays] only returns the number of whole days.
+   */
+  external Duration difference(DateTime other);
+
+  external DateTime._internal(int year, int month, int day, int hour,
+      int minute, int second, int millisecond, int microsecond, bool isUtc);
+
+  external DateTime._now();
+
+  /// Returns the time as value (millisecond or microsecond since epoch), or
+  /// null if the values are out of range.
+  external static int _brokenDownDateToValue(
+      int year,
+      int month,
+      int day,
+      int hour,
+      int minute,
+      int second,
+      int millisecond,
+      int microsecond,
+      bool isUtc);
+
+  /**
+   * The number of milliseconds since
+   * the "Unix epoch" 1970-01-01T00:00:00Z (UTC).
+   *
+   * This value is independent of the time zone.
+   *
+   * This value is at most
+   * 8,640,000,000,000,000ms (100,000,000 days) from the Unix epoch.
+   * In other words: `millisecondsSinceEpoch.abs() <= 8640000000000000`.
+   */
+  external int get millisecondsSinceEpoch;
+
+  /**
+   * The number of microseconds since
+   * the "Unix epoch" 1970-01-01T00:00:00Z (UTC).
+   *
+   * This value is independent of the time zone.
+   *
+   * This value is at most
+   * 8,640,000,000,000,000,000us (100,000,000 days) from the Unix epoch.
+   * In other words: `microsecondsSinceEpoch.abs() <= 8640000000000000000`.
+   *
+   * Note that this value does not fit into 53 bits (the size of a IEEE double).
+   * A JavaScript number is not able to hold this value.
+   */
+  external int get microsecondsSinceEpoch;
+
+  /**
+   * The time zone name.
+   *
+   * This value is provided by the operating system and may be an
+   * abbreviation or a full name.
+   *
+   * In the browser or on Unix-like systems commonly returns abbreviations,
+   * such as "CET" or "CEST". On Windows returns the full name, for example
+   * "Pacific Standard Time".
+   */
+  external String get timeZoneName;
+
+  /**
+   * The time zone offset, which
+   * is the difference between local time and UTC.
+   *
+   * The offset is positive for time zones east of UTC.
+   *
+   * Note, that JavaScript, Python and C return the difference between UTC and
+   * local time. Java, C# and Ruby return the difference between local time and
+   * UTC.
+   */
+  external Duration get timeZoneOffset;
+
+  /**
+   * The year.
+   *
+   * ```
+   * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");
+   * assert(moonLanding.year == 1969);
+   * ```
+   */
+  external int get year;
+
+  /**
+   * The month [1..12].
+   *
+   * ```
+   * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");
+   * assert(moonLanding.month == 7);
+   * assert(moonLanding.month == DateTime.july);
+   * ```
+   */
+  external int get month;
+
+  /**
+   * The day of the month [1..31].
+   *
+   * ```
+   * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");
+   * assert(moonLanding.day == 20);
+   * ```
+   */
+  external int get day;
+
+  /**
+   * The hour of the day, expressed as in a 24-hour clock [0..23].
+   *
+   * ```
+   * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");
+   * assert(moonLanding.hour == 20);
+   * ```
+   */
+  external int get hour;
+
+  /**
+   * The minute [0...59].
+   *
+   * ```
+   * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");
+   * assert(moonLanding.minute == 18);
+   * ```
+   */
+  external int get minute;
+
+  /**
+   * The second [0...59].
+   *
+   * ```
+   * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");
+   * assert(moonLanding.second == 4);
+   * ```
+   */
+  external int get second;
+
+  /**
+   * The millisecond [0...999].
+   *
+   * ```
+   * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");
+   * assert(moonLanding.millisecond == 0);
+   * ```
+   */
+  external int get millisecond;
+
+  /**
+   * The microsecond [0...999].
+   *
+   * ```
+   * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");
+   * assert(moonLanding.microsecond == 0);
+   * ```
+   */
+  external int get microsecond;
+
+  /**
+   * The day of the week [monday]..[sunday].
+   *
+   * In accordance with ISO 8601
+   * a week starts with Monday, which has the value 1.
+   *
+   * ```
+   * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");
+   * assert(moonLanding.weekday == 7);
+   * assert(moonLanding.weekday == DateTime.sunday);
+   * ```
+   */
+  external int get weekday;
+
+  /*
+   * date ::= yeardate time_opt timezone_opt
+   * yeardate ::= year colon_opt month colon_opt day
+   * year ::= sign_opt digit{4,6}
+   * colon_opt :: <empty> | ':'
+   * sign ::= '+' | '-'
+   * sign_opt ::=  <empty> | sign
+   * month ::= digit{2}
+   * day ::= digit{2}
+   * time_opt ::= <empty> | (' ' | 'T') hour minutes_opt
+   * minutes_opt ::= <empty> | colon_opt digit{2} seconds_opt
+   * seconds_opt ::= <empty> | colon_opt digit{2} millis_opt
+   * micros_opt ::= <empty> | ('.' | ',') digit{1,6}
+   * timezone_opt ::= <empty> | space_opt timezone
+   * space_opt :: ' ' | <empty>
+   * timezone ::= 'z' | 'Z' | sign digit{2} timezonemins_opt
+   * timezonemins_opt ::= <empty> | colon_opt digit{2}
+   */
+  static final RegExp _parseFormat = RegExp(
+      r'^([+-]?\d{4,6})-?(\d\d)-?(\d\d)' // Day part.
+      r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(?:[.,](\d{1,6}))?)?)?' // Time part.
+      r'( ?[zZ]| ?([-+])(\d\d)(?::?(\d\d))?)?)?$'); // Timezone part.
+}
diff --git a/sdk_nnbd/lib/core/double.dart b/sdk_nnbd/lib/core/double.dart
new file mode 100644
index 0000000..61191ec
--- /dev/null
+++ b/sdk_nnbd/lib/core/double.dart
@@ -0,0 +1,218 @@
+// Copyright (c) 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 dart.core;
+
+// TODO: Convert this abstract class into a concrete class double
+// that uses the patch class functionality to account for the
+// different platform implementations.
+
+/**
+ * A double-precision floating point number.
+ *
+ * Representation of Dart doubles containing double specific constants
+ * and operations and specializations of operations inherited from
+ * [num]. Dart doubles are 64-bit floating-point numbers as specified in the
+ * IEEE 754 standard.
+ *
+ * The [double] type is contagious. Operations on [double]s return
+ * [double] results.
+ *
+ * It is a compile-time error for a class to attempt to extend or implement
+ * double.
+ */
+abstract class double extends num {
+  static const double nan = 0.0 / 0.0;
+  static const double infinity = 1.0 / 0.0;
+  static const double negativeInfinity = -infinity;
+  static const double minPositive = 5e-324;
+  static const double maxFinite = 1.7976931348623157e+308;
+
+  double remainder(num other);
+
+  /** Addition operator. */
+  double operator +(num other);
+
+  /** Subtraction operator. */
+  double operator -(num other);
+
+  /** Multiplication operator. */
+  double operator *(num other);
+
+  double operator %(num other);
+
+  /** Division operator. */
+  double operator /(num other);
+
+  /**
+   * Truncating division operator.
+   *
+   * The result of the truncating division `a ~/ b` is equivalent to
+   * `(a / b).truncate()`.
+   */
+  int operator ~/(num other);
+
+  /** Negate operator. */
+  double operator -();
+
+  /** Returns the absolute value of this [double]. */
+  double abs();
+
+  /**
+   * Returns the sign of the double's numerical value.
+   *
+   * Returns -1.0 if the value is less than zero,
+   * +1.0 if the value is greater than zero,
+   * and the value itself if it is -0.0, 0.0 or NaN.
+   */
+  double get sign;
+
+  /**
+   * Returns the integer closest to `this`.
+   *
+   * Rounds away from zero when there is no closest integer:
+   *  `(3.5).round() == 4` and `(-3.5).round() == -4`.
+   *
+   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
+   */
+  int round();
+
+  /**
+   * Returns the greatest integer no greater than `this`.
+   *
+   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
+   */
+  int floor();
+
+  /**
+   * Returns the least integer no smaller than `this`.
+   *
+   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
+   */
+  int ceil();
+
+  /**
+   * Returns the integer obtained by discarding any fractional
+   * digits from `this`.
+   *
+   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
+   */
+  int truncate();
+
+  /**
+   * Returns the integer double value closest to `this`.
+   *
+   * Rounds away from zero when there is no closest integer:
+   *  `(3.5).roundToDouble() == 4` and `(-3.5).roundToDouble() == -4`.
+   *
+   * If this is already an integer valued double, including `-0.0`, or it is not
+   * a finite value, the value is returned unmodified.
+   *
+   * For the purpose of rounding, `-0.0` is considered to be below `0.0`,
+   * and `-0.0` is therefore considered closer to negative numbers than `0.0`.
+   * This means that for a value, `d` in the range `-0.5 < d < 0.0`,
+   * the result is `-0.0`.
+   */
+  double roundToDouble();
+
+  /**
+   * Returns the greatest integer double value no greater than `this`.
+   *
+   * If this is already an integer valued double, including `-0.0`, or it is not
+   * a finite value, the value is returned unmodified.
+   *
+   * For the purpose of rounding, `-0.0` is considered to be below `0.0`.
+   * A number `d` in the range `0.0 < d < 1.0` will return `0.0`.
+   */
+  double floorToDouble();
+
+  /**
+   * Returns the least integer double value no smaller than `this`.
+   *
+   * If this is already an integer valued double, including `-0.0`, or it is not
+   * a finite value, the value is returned unmodified.
+   *
+   * For the purpose of rounding, `-0.0` is considered to be below `0.0`.
+   * A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`.
+   */
+  double ceilToDouble();
+
+  /**
+   * Returns the integer double value obtained by discarding any fractional
+   * digits from `this`.
+   *
+   * If this is already an integer valued double, including `-0.0`, or it is not
+   * a finite value, the value is returned unmodified.
+   *
+   * For the purpose of rounding, `-0.0` is considered to be below `0.0`.
+   * A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`, and
+   * in the range `0.0 < d < 1.0` it will return 0.0.
+   */
+  double truncateToDouble();
+
+  /**
+   * Provide a representation of this [double] value.
+   *
+   * The representation is a number literal such that the closest double value
+   * to the representation's mathematical value is this [double].
+   *
+   * Returns "NaN" for the Not-a-Number value.
+   * Returns "Infinity" and "-Infinity" for positive and negative Infinity.
+   * Returns "-0.0" for negative zero.
+   *
+   * For all doubles, `d`, converting to a string and parsing the string back
+   * gives the same value again: `d == double.parse(d.toString())` (except when
+   * `d` is NaN).
+   */
+  String toString();
+
+  /**
+   * Parse [source] as an double literal and return its value.
+   *
+   * Accepts an optional sign (`+` or `-`) followed by either the characters
+   * "Infinity", the characters "NaN" or a floating-point representation.
+   * A floating-point representation is composed of a mantissa and an optional
+   * exponent part. The mantissa is either a decimal point (`.`) followed by a
+   * sequence of (decimal) digits, or a sequence of digits
+   * optionally followed by a decimal point and optionally more digits. The
+   * (optional) exponent part consists of the character "e" or "E", an optional
+   * sign, and one or more digits.
+   * The [source] must not be `null`.
+   *
+   * Leading and trailing whitespace is ignored.
+   *
+   * If the [source] string is not a valid double literal, 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 instead.
+   *
+   * The [onError] function is only invoked if [source] is a [String] with an
+   * invalid format. It is not invoked if [source] is `null`.
+   *
+   * Examples of accepted strings:
+   *
+   *     "3.14"
+   *     "  3.14 \xA0"
+   *     "0."
+   *     ".0"
+   *     "-1.e3"
+   *     "1234E+7"
+   *     "+.12e-9"
+   *     "-NaN"
+   *
+   * The [onError] parameter is deprecated and will be removed.
+   * Instead of `double.parse(string, (string) { ... })`,
+   * you should use `double.tryParse(string) ?? (...)`.
+   */
+  external static double parse(String source,
+      [@deprecated double onError(String source)]);
+
+  /**
+   * Parse [source] as an double literal and return its value.
+   *
+   * Like [parse] except that this function returns `null` for invalid inputs
+   * instead of throwing, and the [source] must still not be `null`.
+   */
+  external static double tryParse(String source);
+}
diff --git a/sdk_nnbd/lib/core/duration.dart b/sdk_nnbd/lib/core/duration.dart
new file mode 100644
index 0000000..914f05a
--- /dev/null
+++ b/sdk_nnbd/lib/core/duration.dart
@@ -0,0 +1,293 @@
+// 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.
+
+part of dart.core;
+
+/**
+ * A span of time, such as 27 days, 4 hours, 12 minutes, and 3 seconds.
+ *
+ * A `Duration` represents a difference from one point in time to another. The
+ * duration may be "negative" if the difference is from a later time to an
+ * earlier.
+ *
+ * Durations are context independent. For example, a duration of 2 days is
+ * always 48 hours, even when it is added to a `DateTime` just when the
+ * time zone is about to do a daylight-savings switch. (See [DateTime.add]).
+ *
+ * Despite the same name, a `Duration` object does not implement "Durations"
+ * as specified by ISO 8601. In particular, a duration object does not keep
+ * track of the individually provided members (such as "days" or "hours"), but
+ * only uses these arguments to compute the length of the corresponding time
+ * interval.
+ *
+ * To create a new Duration object, use this class's single constructor
+ * giving the appropriate arguments:
+ * ```dart
+ * Duration fastestMarathon = new Duration(hours:2, minutes:3, seconds:2);
+ * ```
+ * The [Duration] is the sum of all individual parts.
+ * This means that individual parts can be larger than the next-bigger unit.
+ * For example, [inMinutes] can be greater than 59.
+ * ```dart
+ * assert(fastestMarathon.inMinutes == 123);
+ * ```
+ * All individual parts are allowed to be negative.
+ *
+ * Use one of the properties, such as [inDays],
+ * to retrieve the integer value of the Duration in the specified time unit.
+ * Note that the returned value is rounded down.
+ * For example,
+ * ```dart
+ * Duration aLongWeekend = new Duration(hours:88);
+ * assert(aLongWeekend.inDays == 3);
+ * ```
+ * This class provides a collection of arithmetic
+ * and comparison operators,
+ * plus a set of constants useful for converting time units.
+ *
+ * See [DateTime] to represent a point in time.
+ * See [Stopwatch] to measure time-spans.
+ */
+class Duration implements Comparable<Duration> {
+  static const int microsecondsPerMillisecond = 1000;
+  static const int millisecondsPerSecond = 1000;
+  static const int secondsPerMinute = 60;
+  static const int minutesPerHour = 60;
+  static const int hoursPerDay = 24;
+
+  static const int microsecondsPerSecond =
+      microsecondsPerMillisecond * millisecondsPerSecond;
+  static const int microsecondsPerMinute =
+      microsecondsPerSecond * secondsPerMinute;
+  static const int microsecondsPerHour = microsecondsPerMinute * minutesPerHour;
+  static const int microsecondsPerDay = microsecondsPerHour * hoursPerDay;
+
+  static const int millisecondsPerMinute =
+      millisecondsPerSecond * secondsPerMinute;
+  static const int millisecondsPerHour = millisecondsPerMinute * minutesPerHour;
+  static const int millisecondsPerDay = millisecondsPerHour * hoursPerDay;
+
+  static const int secondsPerHour = secondsPerMinute * minutesPerHour;
+  static const int secondsPerDay = secondsPerHour * hoursPerDay;
+
+  static const int minutesPerDay = minutesPerHour * hoursPerDay;
+
+  static const Duration zero = Duration(seconds: 0);
+
+  /*
+   * The value of this Duration object in microseconds.
+   */
+  final int _duration;
+
+  /**
+   * Creates a new Duration object whose value
+   * is the sum of all individual parts.
+   *
+   * Individual parts can be larger than the next-bigger unit.
+   * For example, [hours] can be greater than 23.
+   *
+   * All individual parts are allowed to be negative.
+   * All arguments are 0 by default.
+   */
+  const Duration(
+      {int days = 0,
+      int hours = 0,
+      int minutes = 0,
+      int seconds = 0,
+      int milliseconds = 0,
+      int microseconds = 0})
+      : this._microseconds(microsecondsPerDay * days +
+            microsecondsPerHour * hours +
+            microsecondsPerMinute * minutes +
+            microsecondsPerSecond * seconds +
+            microsecondsPerMillisecond * milliseconds +
+            microseconds);
+
+  // Fast path internal direct constructor to avoids the optional arguments and
+  // [_microseconds] recomputation.
+  const Duration._microseconds(this._duration);
+
+  /**
+   * Adds this Duration and [other] and
+   * returns the sum as a new Duration object.
+   */
+  Duration operator +(Duration other) {
+    return Duration._microseconds(_duration + other._duration);
+  }
+
+  /**
+   * Subtracts [other] from this Duration and
+   * returns the difference as a new Duration object.
+   */
+  Duration operator -(Duration other) {
+    return Duration._microseconds(_duration - other._duration);
+  }
+
+  /**
+   * Multiplies this Duration by the given [factor] and returns the result
+   * as a new Duration object.
+   *
+   * 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 *(num factor) {
+    return Duration._microseconds((_duration * factor).round());
+  }
+
+  /**
+   * Divides this Duration by the given [quotient] and returns the truncated
+   * result as a new Duration object.
+   *
+   * Throws an [IntegerDivisionByZeroException] if [quotient] is `0`.
+   */
+  Duration operator ~/(int quotient) {
+    // By doing the check here instead of relying on "~/" below we get the
+    // exception even with dart2js.
+    if (quotient == 0) throw IntegerDivisionByZeroException();
+    return Duration._microseconds(_duration ~/ quotient);
+  }
+
+  /**
+   * Returns `true` if the value of this Duration
+   * is less than the value of [other].
+   */
+  bool operator <(Duration other) => this._duration < other._duration;
+
+  /**
+   * Returns `true` if the value of this Duration
+   * is greater than the value of [other].
+   */
+  bool operator >(Duration other) => this._duration > other._duration;
+
+  /**
+   * Returns `true` if the value of this Duration
+   * is less than or equal to the value of [other].
+   */
+  bool operator <=(Duration other) => this._duration <= other._duration;
+
+  /**
+   * Returns `true` if the value of this Duration
+   * is greater than or equal to the value of [other].
+   */
+  bool operator >=(Duration other) => this._duration >= other._duration;
+
+  /**
+   * Returns the number of whole days spanned by this Duration.
+   */
+  int get inDays => _duration ~/ Duration.microsecondsPerDay;
+
+  /**
+   * Returns the number of whole hours spanned by this Duration.
+   *
+   * The returned value can be greater than 23.
+   */
+  int get inHours => _duration ~/ Duration.microsecondsPerHour;
+
+  /**
+   * Returns the number of whole minutes spanned by this Duration.
+   *
+   * The returned value can be greater than 59.
+   */
+  int get inMinutes => _duration ~/ Duration.microsecondsPerMinute;
+
+  /**
+   * Returns the number of whole seconds spanned by this Duration.
+   *
+   * The returned value can be greater than 59.
+   */
+  int get inSeconds => _duration ~/ Duration.microsecondsPerSecond;
+
+  /**
+   * Returns number of whole milliseconds spanned by this Duration.
+   *
+   * The returned value can be greater than 999.
+   */
+  int get inMilliseconds => _duration ~/ Duration.microsecondsPerMillisecond;
+
+  /**
+   * Returns number of whole microseconds spanned by this Duration.
+   */
+  int get inMicroseconds => _duration;
+
+  /**
+   * Returns `true` if this [Duration] has the same value as [other].
+   */
+  bool operator ==(dynamic other) =>
+      other is Duration && _duration == other.inMicroseconds;
+
+  int get hashCode => _duration.hashCode;
+
+  /**
+   * Compares this [Duration] to [other], returning zero if the values are equal.
+   *
+   * Returns a negative integer if this `Duration` is shorter than
+   * [other], or a positive integer if it is longer.
+   *
+   * A negative `Duration` is always considered shorter than a positive one.
+   *
+   * It is always the case that `duration1.compareTo(duration2) < 0` iff
+   * `(someDate + duration1).compareTo(someDate + duration2) < 0`.
+   */
+  int compareTo(Duration other) => _duration.compareTo(other._duration);
+
+  /**
+   * Returns a string representation of this `Duration`.
+   *
+   * Returns a string with hours, minutes, seconds, and microseconds, in the
+   * following format: `HH:MM:SS.mmmmmm`. For example,
+   *
+   *     var d = new Duration(days:1, hours:1, minutes:33, microseconds: 500);
+   *     d.toString();  // "25:33:00.000500"
+   */
+  String toString() {
+    String sixDigits(int n) {
+      if (n >= 100000) return "$n";
+      if (n >= 10000) return "0$n";
+      if (n >= 1000) return "00$n";
+      if (n >= 100) return "000$n";
+      if (n >= 10) return "0000$n";
+      return "00000$n";
+    }
+
+    String twoDigits(int n) {
+      if (n >= 10) return "$n";
+      return "0$n";
+    }
+
+    if (inMicroseconds < 0) {
+      return "-${-this}";
+    }
+    String twoDigitMinutes = twoDigits(inMinutes.remainder(minutesPerHour));
+    String twoDigitSeconds = twoDigits(inSeconds.remainder(secondsPerMinute));
+    String sixDigitUs =
+        sixDigits(inMicroseconds.remainder(microsecondsPerSecond));
+    return "$inHours:$twoDigitMinutes:$twoDigitSeconds.$sixDigitUs";
+  }
+
+  /**
+   * Returns whether this `Duration` is negative.
+   *
+   * A negative `Duration` represents the difference from a later time to an
+   * earlier time.
+   */
+  bool get isNegative => _duration < 0;
+
+  /**
+   * Returns a new `Duration` representing the absolute value of this
+   * `Duration`.
+   *
+   * The returned `Duration` has the same length as this one, but is always
+   * positive.
+   */
+  Duration abs() => Duration._microseconds(_duration.abs());
+
+  /**
+   * Returns a new `Duration` representing this `Duration` negated.
+   *
+   * The returned `Duration` has the same length as this one, but will have the
+   * opposite sign of this one.
+   */
+  // Using subtraction helps dart2js avoid negative zeros.
+  Duration operator -() => Duration._microseconds(0 - _duration);
+}
diff --git a/sdk_nnbd/lib/core/errors.dart b/sdk_nnbd/lib/core/errors.dart
new file mode 100644
index 0000000..53f3d35
--- /dev/null
+++ b/sdk_nnbd/lib/core/errors.dart
@@ -0,0 +1,588 @@
+// Copyright (c) 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 dart.core;
+
+/**
+ * Error objects thrown in the case of a program failure.
+ *
+ * An `Error` object represents a program failure that the programmer
+ * should have avoided.
+ *
+ * Examples include calling a function with invalid arguments,
+ * or even with the wrong number of arguments,
+ * or calling it at a time when it is not allowed.
+ *
+ * These are not errors that a caller should expect or catch -
+ * if they occur, the program is erroneous,
+ * and terminating the program may be the safest response.
+ *
+ * When deciding that a function throws an error,
+ * the conditions where it happens should be clearly described,
+ * and they should be detectable and predictable,
+ * so the programmer using the function can avoid triggering the error.
+ *
+ * Such descriptions often uses words like
+ * "must" or "must not" to describe the condition,
+ * and if you see words like that in a function's documentation,
+ * then not satisfying the requirement
+ * is very likely to cause an error to be thrown.
+ *
+ * Example (from [String.contains]):
+ *
+ *        `startIndex` must not be negative or greater than `length`.
+ *
+ * In this case, an error will be thrown if `startIndex` is negative
+ * or too large.
+ *
+ * If the conditions are not detectable before calling a function,
+ * the called function should not throw an `Error`.
+ * It may still throw a value,
+ * but the caller will have to catch the thrown value,
+ * effectively making it an alternative result rather than an error.
+ * The thrown object can choose to implement [Exception]
+ * to document that it represents an exceptional, but not erroneous, occurrence,
+ * but it has no other effect than documentation.
+ *
+ * All non-`null` values can be thrown in Dart.
+ * Objects extending `Error` are handled specially:
+ * The first time they are thrown,
+ * the stack trace at the throw point is recorded
+ * and stored in the error object.
+ * It can be retrieved using the [stackTrace] getter.
+ * An error object that merely implements `Error`, and doesn't extend it,
+ * will not store the stack trace automatically.
+ *
+ * Error objects are also used for system wide failures
+ * like stack overflow or an out-of-memory situation.
+ *
+ * Since errors are not created to be caught,
+ * there is no need for subclasses to distinguish the errors.
+ * Instead subclasses have been created in order to make groups
+ * of related errors easy to create with consistent error messages.
+ * For example, the [String.contains] method will use a [RangeError]
+ * if its `startIndex` isn't in the range `0..length`,
+ * which is easily created by `new RangeError.range(startIndex, 0, length)`.
+ */
+class Error {
+  Error(); // Prevent use as mixin.
+
+  /**
+   * Safely convert a value to a [String] description.
+   *
+   * The conversion is guaranteed to not throw, so it won't use the object's
+   * toString method.
+   */
+  static String safeToString(Object object) {
+    if (object is num || object is bool || null == object) {
+      return object.toString();
+    }
+    if (object is String) {
+      return _stringToSafeString(object);
+    }
+    return _objectToString(object);
+  }
+
+  /** Convert string to a valid string literal with no control characters. */
+  external static String _stringToSafeString(String string);
+
+  external static String _objectToString(Object object);
+
+  external StackTrace get stackTrace;
+}
+
+/**
+ * Error thrown by the runtime system when an assert statement fails.
+ */
+class AssertionError extends Error {
+  /** Message describing the assertion error. */
+  final Object message;
+  AssertionError([this.message]);
+  String toString() => "Assertion failed";
+}
+
+/**
+ * Error thrown by the runtime system when a type assertion fails.
+ */
+class TypeError extends AssertionError {}
+
+/**
+ * Error thrown by the runtime system when a cast operation fails.
+ */
+class CastError extends Error {}
+
+/**
+ * Error thrown when attempting to throw [:null:].
+ */
+class NullThrownError extends Error {
+  @pragma("vm:entry-point")
+  NullThrownError();
+  String toString() => "Throw of null.";
+}
+
+/**
+ * Error thrown when a function is passed an unacceptable argument.
+ */
+class ArgumentError extends Error {
+  /** Whether value was provided. */
+  final bool _hasValue;
+  /** The invalid value. */
+  final invalidValue;
+  /** Name of the invalid argument, if available. */
+  final String name;
+  /** Message describing the problem. */
+  final message;
+
+  /**
+   * The [message] describes the erroneous argument.
+   *
+   * Existing code may be using `message` to hold the invalid value.
+   * If the `message` is not a [String], it is assumed to be a value instead
+   * of a message.
+   */
+  @pragma("vm:entry-point")
+  ArgumentError([this.message])
+      : invalidValue = null,
+        _hasValue = false,
+        name = null;
+
+  /**
+   * Creates error containing the invalid [value].
+   *
+   * A message is built by suffixing the [message] argument with
+   * the [name] argument (if provided) and the value. Example
+   *
+   *    "Invalid argument (foo): null"
+   *
+   * The `name` should match the argument name of the function, but if
+   * the function is a method implementing an interface, and its argument
+   * names differ from the interface, it might be more useful to use the
+   * interface method's argument name (or just rename arguments to match).
+   */
+  @pragma("vm:entry-point")
+  ArgumentError.value(value, [this.name, this.message])
+      : invalidValue = value,
+        _hasValue = true;
+
+  /**
+   * Create an argument error for a `null` argument that must not be `null`.
+   */
+  ArgumentError.notNull([this.name])
+      : _hasValue = false,
+        message = "Must not be null",
+        invalidValue = null;
+
+  /**
+   * Throws if [argument] is `null`.
+   */
+  @Since("2.1")
+  static void checkNotNull(Object argument, [String name]) {
+    if (argument == null) throw ArgumentError.notNull(name);
+  }
+
+  // Helper functions for toString overridden in subclasses.
+  String get _errorName => "Invalid argument${!_hasValue ? "(s)" : ""}";
+  String get _errorExplanation => "";
+
+  String toString() {
+    String nameString = "";
+    if (name != null) {
+      nameString = " ($name)";
+    }
+    var message = (this.message == null) ? "" : ": ${this.message}";
+    String prefix = "$_errorName$nameString$message";
+    if (!_hasValue) return prefix;
+    // If we know the invalid value, we can try to describe the problem.
+    String explanation = _errorExplanation;
+    String errorValue = Error.safeToString(invalidValue);
+    return "$prefix$explanation: $errorValue";
+  }
+}
+
+/**
+ * Error thrown due to an index being outside a valid range.
+ */
+class RangeError extends ArgumentError {
+  /** The minimum value that [value] is allowed to assume. */
+  final num start;
+  /** The maximum value that [value] is allowed to assume. */
+  final num end;
+
+  // TODO(lrn): This constructor should be called only with string values.
+  // It currently isn't in all cases.
+  /**
+   * Create a new [RangeError] with the given [message].
+   */
+  @pragma("vm:entry-point")
+  RangeError(var message)
+      : start = null,
+        end = null,
+        super(message);
+
+  /**
+   * Create a new [RangeError] with a message for the given [value].
+   *
+   * An optional [name] can specify the argument name that has the
+   * invalid value, and the [message] can override the default error
+   * description.
+   */
+  RangeError.value(num value, [String name, String message])
+      : start = null,
+        end = null,
+        super.value(
+            value, name, (message != null) ? message : "Value not in range");
+
+  /**
+   * Create a new [RangeError] for a value being outside the valid range.
+   *
+   * The allowed range is from [minValue] to [maxValue], inclusive.
+   * If `minValue` or `maxValue` are `null`, the range is infinite in
+   * that direction.
+   *
+   * For a range from 0 to the length of something, end exclusive, use
+   * [RangeError.index].
+   *
+   * An optional [name] can specify the argument name that has the
+   * invalid value, and the [message] can override the default error
+   * description.
+   */
+  @pragma("vm:entry-point")
+  RangeError.range(num invalidValue, int minValue, int maxValue,
+      [String name, String message])
+      : start = minValue,
+        end = maxValue,
+        super.value(
+            invalidValue, name, (message != null) ? message : "Invalid value");
+
+  /**
+   * Creates a new [RangeError] stating that [index] is not a valid index
+   * into [indexable].
+   *
+   * An optional [name] can specify the argument name that has the
+   * invalid value, and the [message] can override the default error
+   * description.
+   *
+   * The [length] is the length of [indexable] at the time of the error.
+   * If `length` is omitted, it defaults to `indexable.length`.
+   */
+  factory RangeError.index(int index, dynamic indexable,
+      [String name, String message, int length]) = IndexError;
+
+  /**
+   * Check that a [value] lies in a specific interval.
+   *
+   * Throws if [value] is not in the interval.
+   * The interval is from [minValue] to [maxValue], both inclusive.
+   */
+  static void checkValueInInterval(int value, int minValue, int maxValue,
+      [String name, String message]) {
+    if (value < minValue || value > maxValue) {
+      throw RangeError.range(value, minValue, maxValue, name, message);
+    }
+  }
+
+  /**
+   * Check that a value is a valid index into an indexable object.
+   *
+   * Throws if [index] is not a valid index into [indexable].
+   *
+   * An indexable object is one that has a `length` and a and index-operator
+   * `[]` that accepts an index if `0 <= index < length`.
+   *
+   * If [length] is provided, it is used as the length of the indexable object,
+   * otherwise the length is found as `indexable.length`.
+   */
+  static void checkValidIndex(int index, dynamic indexable,
+      [String name, int length, String message]) {
+    length ??= indexable.length;
+    // Comparing with `0` as receiver produces better dart2js type inference.
+    if (0 > index || index >= length) {
+      name ??= "index";
+      throw RangeError.index(index, indexable, name, message, length);
+    }
+  }
+
+  /**
+   * Check that a range represents a slice of an indexable object.
+   *
+   * Throws if the range is not valid for an indexable object with
+   * the given [length].
+   * A range is valid for an indexable object with a given [length]
+   *
+   * if `0 <= [start] <= [end] <= [length]`.
+   * An `end` of `null` is considered equivalent to `length`.
+   *
+   * The [startName] and [endName] defaults to `"start"` and `"end"`,
+   * respectively.
+   *
+   * Returns the actual `end` value, which is `length` if `end` is `null`,
+   * and `end` otherwise.
+   */
+  static int checkValidRange(int start, int end, int length,
+      [String startName, String endName, String message]) {
+    // Comparing with `0` as receiver produces better dart2js type inference.
+    // Ditto `start > end` below.
+    if (0 > start || start > length) {
+      startName ??= "start";
+      throw RangeError.range(start, 0, length, startName, message);
+    }
+    if (end != null) {
+      if (start > end || end > length) {
+        endName ??= "end";
+        throw RangeError.range(end, start, length, endName, message);
+      }
+      return end;
+    }
+    return length;
+  }
+
+  /**
+   * Check that an integer value isn't negative.
+   *
+   * Throws if the value is negative.
+   */
+  static void checkNotNegative(int value, [String name, String message]) {
+    if (value < 0) throw RangeError.range(value, 0, null, name, message);
+  }
+
+  String get _errorName => "RangeError";
+  String get _errorExplanation {
+    assert(_hasValue);
+    String explanation = "";
+    if (start == null) {
+      if (end != null) {
+        explanation = ": Not less than or equal to $end";
+      }
+      // If both are null, we don't add a description of the limits.
+    } else if (end == null) {
+      explanation = ": Not greater than or equal to $start";
+    } else if (end > start) {
+      explanation = ": Not in range $start..$end, inclusive";
+    } else if (end < start) {
+      explanation = ": Valid value range is empty";
+    } else {
+      // end == start.
+      explanation = ": Only valid value is $start";
+    }
+    return explanation;
+  }
+}
+
+/**
+ * A specialized [RangeError] used when an index is not in the range
+ * `0..indexable.length-1`.
+ *
+ * Also contains the indexable object, its length at the time of the error,
+ * and the invalid index itself.
+ */
+class IndexError extends ArgumentError implements RangeError {
+  /** The indexable object that [invalidValue] was not a valid index into. */
+  final indexable;
+  /** The length of [indexable] at the time of the error. */
+  final int length;
+
+  /**
+   * Creates a new [IndexError] stating that [invalidValue] is not a valid index
+   * into [indexable].
+   *
+   * The [length] is the length of [indexable] at the time of the error.
+   * If `length` is omitted, it defaults to `indexable.length`.
+   *
+   * The message is used as part of the string representation of the error.
+   */
+  IndexError(int invalidValue, dynamic indexable,
+      [String name, String message, int length])
+      : this.indexable = indexable,
+        this.length = length ?? indexable.length,
+        super.value(invalidValue, name,
+            (message != null) ? message : "Index out of range");
+
+  // Getters inherited from RangeError.
+  int get start => 0;
+  int get end => length - 1;
+
+  String get _errorName => "RangeError";
+  String get _errorExplanation {
+    assert(_hasValue);
+    int invalidValue = this.invalidValue;
+    if (invalidValue < 0) {
+      return ": index must not be negative";
+    }
+    if (length == 0) {
+      return ": no indices are valid";
+    }
+    return ": index should be less than $length";
+  }
+}
+
+/**
+ * Error thrown when control reaches the end of a switch case.
+ *
+ * The Dart specification requires this error to be thrown when
+ * control reaches the end of a switch case (except the last case
+ * of a switch) without meeting a break or similar end of the control
+ * flow.
+ */
+class FallThroughError extends Error {
+  FallThroughError();
+  @pragma("vm:entry-point")
+  external FallThroughError._create(String url, int line);
+
+  external String toString();
+}
+
+/**
+ * Error thrown when trying to instantiate an abstract class.
+ */
+class AbstractClassInstantiationError extends Error {
+  final String _className;
+  AbstractClassInstantiationError(String className) : _className = className;
+
+  external String toString();
+}
+
+/**
+ * Error thrown by the default implementation of [:noSuchMethod:] on [Object].
+ */
+class NoSuchMethodError extends Error {
+  /**
+   * Create a [NoSuchMethodError] corresponding to a failed method call.
+   *
+   * The [receiver] is the receiver of the method call.
+   * That is, the object on which the method was attempted called.
+   *
+   * The [invocation] represents the method call that failed. It
+   * should not be `null`.
+   */
+  external NoSuchMethodError.withInvocation(
+      Object receiver, Invocation invocation);
+
+  // Deprecated constructor to be removed after dart2js updates to the above.
+  /**
+   * Create a [NoSuchMethodError] corresponding to a failed method call.
+   *
+   * The [receiver] is the receiver of the method call.
+   * That is, the object on which the method was attempted called.
+   * If the receiver is `null`, it is interpreted as a call to a top-level
+   * function of a library.
+   *
+   * The [memberName] is a [Symbol] representing the name of the called method
+   * or accessor. It should not be `null`.
+   *
+   * The [positionalArguments] is a list of the positional arguments that the
+   * method was called with. If `null`, it is considered equivalent to the
+   * empty list.
+   *
+   * The [namedArguments] is a map from [Symbol]s to the values of named
+   * arguments that the method was called with.
+   *
+   * This constructor does not handle type arguments.
+   * To include type variables, create an [Invocation] and use
+   * [NoSuchMethodError.withInvocation].
+   */
+  @Deprecated("Use NoSuchMethod.withInvocation instead")
+  external NoSuchMethodError(Object receiver, Symbol memberName,
+      List positionalArguments, Map<Symbol, dynamic> namedArguments,
+      [@deprecated List existingArgumentNames]);
+
+  external String toString();
+}
+
+/**
+ * The operation was not allowed by the object.
+ *
+ * This [Error] is thrown when an instance cannot implement one of the methods
+ * in its signature.
+ */
+@pragma("vm:entry-point")
+class UnsupportedError extends Error {
+  final String message;
+  @pragma("vm:entry-point")
+  UnsupportedError(this.message);
+  String toString() => "Unsupported operation: $message";
+}
+
+/**
+ * Thrown by operations that have not been implemented yet.
+ *
+ * This [Error] is thrown by unfinished code that hasn't yet implemented
+ * all the features it needs.
+ *
+ * If a class is not intending to implement the feature, it should throw
+ * an [UnsupportedError] instead. This error is only intended for
+ * use during development.
+ */
+class UnimplementedError extends Error implements UnsupportedError {
+  final String message;
+  UnimplementedError([this.message]);
+  String toString() => (this.message != null
+      ? "UnimplementedError: $message"
+      : "UnimplementedError");
+}
+
+/**
+ * The operation was not allowed by the current state of the object.
+ *
+ * This is a generic error used for a variety of different erroneous
+ * actions. The message should be descriptive.
+ */
+class StateError extends Error {
+  final String message;
+  StateError(this.message);
+  String toString() => "Bad state: $message";
+}
+
+/**
+ * Error occurring when a collection is modified during iteration.
+ *
+ * Some modifications may be allowed for some collections, so each collection
+ * ([Iterable] or similar collection of values) should declare which operations
+ * are allowed during an iteration.
+ */
+class ConcurrentModificationError extends Error {
+  /** The object that was modified in an incompatible way. */
+  final Object modifiedObject;
+
+  ConcurrentModificationError([this.modifiedObject]);
+
+  String toString() {
+    if (modifiedObject == null) {
+      return "Concurrent modification during iteration.";
+    }
+    return "Concurrent modification during iteration: "
+        "${Error.safeToString(modifiedObject)}.";
+  }
+}
+
+class OutOfMemoryError implements Error {
+  @pragma("vm:entry-point")
+  const OutOfMemoryError();
+  String toString() => "Out of Memory";
+
+  StackTrace get stackTrace => null;
+}
+
+class StackOverflowError implements Error {
+  @pragma("vm:entry-point")
+  const StackOverflowError();
+  String toString() => "Stack Overflow";
+
+  StackTrace get stackTrace => null;
+}
+
+/**
+ * Error thrown when a lazily initialized variable cannot be initialized.
+ *
+ * A static/library variable with an initializer expression is initialized
+ * the first time it is read. If evaluating the initializer expression causes
+ * another read of the variable, this error is thrown.
+ */
+class CyclicInitializationError extends Error {
+  final String variableName;
+  @pragma("vm:entry-point")
+  CyclicInitializationError([this.variableName]);
+  String toString() => variableName == null
+      ? "Reading static variable during its initialization"
+      : "Reading static variable '$variableName' during its initialization";
+}
diff --git a/sdk_nnbd/lib/core/exceptions.dart b/sdk_nnbd/lib/core/exceptions.dart
new file mode 100644
index 0000000..2e137e5
--- /dev/null
+++ b/sdk_nnbd/lib/core/exceptions.dart
@@ -0,0 +1,184 @@
+// Copyright (c) 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 dart.core;
+
+// Exceptions are thrown either by the VM or from Dart code.
+
+/**
+ * A marker interface implemented by all core library exceptions.
+ *
+ * An [Exception] is intended to convey information to the user about a failure,
+ * so that the error can be addressed programmatically. It is intended to be
+ * caught, and it should contain useful data fields.
+ *
+ * Creating instances of [Exception] directly with [:new Exception("message"):]
+ * is discouraged, and only included as a temporary measure during development,
+ * until the actual exceptions used by a library are done.
+ */
+abstract class Exception {
+  factory Exception([var message]) => _Exception(message);
+}
+
+/** Default implementation of [Exception] which carries a message. */
+class _Exception implements Exception {
+  final message;
+
+  _Exception([this.message]);
+
+  String toString() {
+    if (message == null) return "Exception";
+    return "Exception: $message";
+  }
+}
+
+/**
+ * Exception thrown when a string or some other data does not have an expected
+ * format and cannot be parsed or processed.
+ */
+class FormatException implements Exception {
+  /**
+   * A message describing the format error.
+   */
+  final String message;
+
+  /**
+   * The actual source input which caused the error.
+   *
+   * This is usually a [String], but can be other types too.
+   * If it is a string, parts of it may be included in the [toString] message.
+   *
+   * The source is `null` if omitted or unknown.
+   */
+  final source;
+
+  /**
+   * The offset in [source] where the error was detected.
+   *
+   * A zero-based offset into the source that marks the format error causing
+   * this exception to be created. If `source` is a string, this should be a
+   * string index in the range `0 <= offset <= source.length`.
+   *
+   * If input is a string, the [toString] method may represent this offset as
+   * a line and character position. The offset should be inside the string,
+   * or at the end of the string.
+   *
+   * May be omitted. If present, [source] should also be present if possible.
+   */
+  final int offset;
+
+  /**
+   * Creates a new FormatException with an optional error [message].
+   *
+   * Optionally also supply the actual [source] with the incorrect format,
+   * and the [offset] in the format where a problem was detected.
+   */
+  @pragma("vm:entry-point")
+  const FormatException([this.message = "", this.source, this.offset]);
+
+  /**
+   * Returns a description of the format exception.
+   *
+   * The description always contains the [message].
+   *
+   * If [source] is present and is a string, the description will contain
+   * (at least a part of) the source.
+   * If [offset] is also provided, the part of the source included will
+   * contain that offset, and the offset will be marked.
+   *
+   * If the source is a string and it contains a line break before offset,
+   * only the line containing offset will be included, and its line number
+   * will also be part of the description. Line and character offsets are
+   * 1-based.
+   */
+  String toString() {
+    String report = "FormatException";
+    if (message != null && "" != message) {
+      report = "$report: $message";
+    }
+    int offset = this.offset;
+    Object objectSource = this.source;
+    if (objectSource is String) {
+      String source = objectSource;
+      if (offset != null && (offset < 0 || offset > source.length)) {
+        offset = null;
+      }
+      // Source is string and offset is null or valid.
+      if (offset == null) {
+        if (source.length > 78) {
+          source = source.substring(0, 75) + "...";
+        }
+        return "$report\n$source";
+      }
+      int lineNum = 1;
+      int lineStart = 0;
+      bool previousCharWasCR = false;
+      for (int i = 0; i < offset; i++) {
+        int char = source.codeUnitAt(i);
+        if (char == 0x0a) {
+          if (lineStart != i || !previousCharWasCR) {
+            lineNum++;
+          }
+          lineStart = i + 1;
+          previousCharWasCR = false;
+        } else if (char == 0x0d) {
+          lineNum++;
+          lineStart = i + 1;
+          previousCharWasCR = true;
+        }
+      }
+      if (lineNum > 1) {
+        report += " (at line $lineNum, character ${offset - lineStart + 1})\n";
+      } else {
+        report += " (at character ${offset + 1})\n";
+      }
+      int lineEnd = source.length;
+      for (int i = offset; i < source.length; i++) {
+        int char = source.codeUnitAt(i);
+        if (char == 0x0a || char == 0x0d) {
+          lineEnd = i;
+          break;
+        }
+      }
+      int length = lineEnd - lineStart;
+      int start = lineStart;
+      int end = lineEnd;
+      String prefix = "";
+      String postfix = "";
+      if (length > 78) {
+        // Can't show entire line. Try to anchor at the nearest end, if
+        // one is within reach.
+        int index = offset - lineStart;
+        if (index < 75) {
+          end = start + 75;
+          postfix = "...";
+        } else if (end - offset < 75) {
+          start = end - 75;
+          prefix = "...";
+        } else {
+          // Neither end is near, just pick an area around the offset.
+          start = offset - 36;
+          end = offset + 36;
+          prefix = postfix = "...";
+        }
+      }
+      String slice = source.substring(start, end);
+      int markOffset = offset - start + prefix.length;
+      return "$report$prefix$slice$postfix\n${" " * markOffset}^\n";
+    } else {
+      // The source is not a string.
+      if (offset != null) {
+        report += " (at offset $offset)";
+      }
+      return report;
+    }
+  }
+}
+
+// Exception thrown when doing integer division with a zero divisor.
+class IntegerDivisionByZeroException implements Exception {
+  @pragma("vm:entry-point")
+  const IntegerDivisionByZeroException();
+  String toString() => "IntegerDivisionByZeroException";
+}
diff --git a/sdk_nnbd/lib/core/expando.dart b/sdk_nnbd/lib/core/expando.dart
new file mode 100644
index 0000000..92cf90c
--- /dev/null
+++ b/sdk_nnbd/lib/core/expando.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 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 dart.core;
+
+/**
+ * An [Expando] allows adding new properties to objects.
+ *
+ * Does not work on numbers, strings, booleans or null.
+ *
+ * An `Expando` does not hold on to the added property value after an object
+ * becomes inaccessible.
+ *
+ * Since you can always create a new number that is identical to an existing
+ * number, it means that an expando property on a number could never be
+ * released. To avoid this, expando properties cannot be added to numbers.
+ * The same argument applies to strings, booleans and null, which also have
+ * literals that evaluate to identical values when they occur more than once.
+ *
+ * There is no restriction on other classes, even for compile time constant
+ * objects. Be careful if adding expando properties to compile time constants,
+ * since they will stay alive forever.
+ */
+class Expando<T> {
+  /**
+   * The name of the this [Expando] as passed to the constructor. If
+   * no name was passed to the constructor, the name is [:null:].
+   */
+  final String name;
+
+  /**
+   * Creates a new [Expando]. The optional name is only used for
+   * debugging purposes and creating two different [Expando]s with the
+   * same name yields two [Expando]s that work on different properties
+   * of the objects they are used on.
+   */
+  external Expando([String name]);
+
+  /**
+   * Expando toString method override.
+   */
+  String toString() => "Expando:$name";
+
+  /**
+   * Gets the value of this [Expando]'s property on the given
+   * object. If the object hasn't been expanded, the method returns
+   * [:null:].
+   *
+   * The object must not be a number, a string, a boolean or null.
+   */
+  external T operator [](Object object);
+
+  /**
+   * Sets the value of this [Expando]'s property on the given
+   * object. Properties can effectively be removed again by setting
+   * their value to null.
+   *
+   * The object must not be a number, a string, a boolean or null.
+   */
+  external void operator []=(Object object, T value);
+}
diff --git a/sdk_nnbd/lib/core/function.dart b/sdk_nnbd/lib/core/function.dart
new file mode 100644
index 0000000..7ff40e9
--- /dev/null
+++ b/sdk_nnbd/lib/core/function.dart
@@ -0,0 +1,67 @@
+// 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.
+
+part of dart.core;
+
+/**
+ * The base class for all function types.
+ *
+ * A function value, or an instance of a class with a "call" method, is a
+ * subtype of a function type, and as such, a subtype of [Function].
+ */
+abstract class Function {
+  /**
+   * Dynamically call [function] with the specified arguments.
+   *
+   * Acts the same as calling function with positional arguments
+   * corresponding to the elements of [positionalArguments] and
+   * named arguments corresponding to the elements of [namedArguments].
+   *
+   * This includes giving the same errors if [function] isn't callable or
+   * if it expects different parameters.
+   *
+   * Example:
+   * ```
+   * Function.apply(foo, [1,2,3], {#f: 4, #g: 5});
+   * ```
+   *
+   * gives exactly the same result as
+   * ```
+   * foo(1, 2, 3, f: 4, g: 5).
+   * ```
+   *
+   * If [positionalArguments] is null, it's considered an empty list.
+   * If [namedArguments] is omitted or null, it is considered an empty map.
+   */
+  external static apply(Function function, List positionalArguments,
+      [Map<Symbol, dynamic> namedArguments]);
+
+  /**
+   * Returns a hash code value that is compatible with `operator==`.
+   */
+  int get hashCode;
+
+  /**
+   * Test whether another object is equal to this function.
+   *
+   * System-created function objects are only equal to other functions.
+   *
+   * Two function objects are known to represent the same function if
+   *
+   * - It is the same object. Static and top-level functions are compile time
+   *   constants when used as values, so referring to the same function twice
+   *   always give the same object,
+   * - or if they refer to the same member method extracted from the same object.
+   *   Extracting a member method as a function value twice gives equal, but
+   *   not necessarily identical, function values.
+   *
+   * Function expressions never give rise to equal function objects. Each time
+   * a function expression is evaluated, it creates a new closure value that
+   * is not known to be equal to other closures created by the same expression.
+   *
+   * Classes implementing `Function` by having a `call` method should have their
+   * own `operator==` and `hashCode` depending on the object.
+   */
+  bool operator ==(Object other);
+}
diff --git a/sdk_nnbd/lib/core/identical.dart b/sdk_nnbd/lib/core/identical.dart
new file mode 100644
index 0000000..68da9f3
--- /dev/null
+++ b/sdk_nnbd/lib/core/identical.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 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 dart.core;
+
+/**
+ * Check whether two references are to the same object.
+ */
+external bool identical(Object a, Object b);
+
+/**
+ * Returns the identity hash code of `object`.
+ *
+ * Returns the same value as `object.hashCode` if [object] has not overridden
+ * [Object.hashCode]. Returns the value that [Object.hashCode] would return
+ * on this object, even if `hashCode` has been overridden.
+ *
+ * This hash code is compatible with [identical].
+ */
+@pragma("vm:entry-point")
+external int identityHashCode(Object object);
diff --git a/sdk_nnbd/lib/core/int.dart b/sdk_nnbd/lib/core/int.dart
new file mode 100644
index 0000000..bc493fb
--- /dev/null
+++ b/sdk_nnbd/lib/core/int.dart
@@ -0,0 +1,355 @@
+// Copyright (c) 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 dart.core;
+
+/**
+ * An integer number.
+ *
+ * The default implementation of `int` is 64-bit two's complement integers
+ * with operations that wrap to that range on overflow.
+ *
+ * **Note:** When compiling to JavaScript, integers are restricted to values
+ * that can be represented exactly by double-precision floating point values.
+ * The available integer values include all integers between -2^53 and 2^53,
+ * and some integers with larger magnitude. That includes some integers larger
+ * than 2^63.
+ * The behavior of the operators and methods in the [int]
+ * class therefore sometimes differs between the Dart VM and Dart code
+ * compiled to JavaScript. For example, the bitwise operators truncate their
+ * operands to 32-bit integers when compiled to JavaScript.
+ *
+ * Classes cannot extend, implement, or mix in `int`.
+ */
+abstract class int extends num {
+  /**
+   * Returns the integer value of the given environment declaration [name].
+   *
+   * The result is the same as would be returned by:
+   * ```
+   * int.tryParse(const String.fromEnvironment(name, defaultValue: ""))
+   *     ?? defaultValue
+   * ```
+   * Example:
+   * ```
+   * const int.fromEnvironment("defaultPort", defaultValue: 80)
+   * ```
+   */
+  // The .fromEnvironment() constructors are special in that we do not want
+  // users to call them using "new". We prohibit that by giving them bodies
+  // that throw, even though const constructors are not allowed to have bodies.
+  // Disable those static errors.
+  //ignore: const_constructor_with_body
+  //ignore: const_factory
+  external const factory int.fromEnvironment(String name, {int defaultValue});
+
+  /**
+   * Bit-wise and operator.
+   *
+   * Treating both `this` and [other] as sufficiently large two's component
+   * integers, the result is a number with only the bits set that are set in
+   * both `this` and [other]
+   *
+   * Of both operands are negative, the result is negative, otherwise
+   * the result is non-negative.
+   */
+  int operator &(int other);
+
+  /**
+   * Bit-wise or operator.
+   *
+   * Treating both `this` and [other] as sufficiently large two's component
+   * integers, the result is a number with the bits set that are set in either
+   * of `this` and [other]
+   *
+   * If both operands are non-negative, the result is non-negative,
+   * otherwise the result is negative.
+   */
+  int operator |(int other);
+
+  /**
+   * Bit-wise exclusive-or operator.
+   *
+   * Treating both `this` and [other] as sufficiently large two's component
+   * integers, the result is a number with the bits set that are set in one,
+   * but not both, of `this` and [other]
+   *
+   * If the operands have the same sign, the result is non-negative,
+   * otherwise the result is negative.
+   */
+  int operator ^(int other);
+
+  /**
+   * The bit-wise negate operator.
+   *
+   * Treating `this` as a sufficiently large two's component integer,
+   * the result is a number with the opposite bits set.
+   *
+   * This maps any integer `x` to `-x - 1`.
+   */
+  int operator ~();
+
+  /**
+   * Shift the bits of this integer to the left by [shiftAmount].
+   *
+   * Shifting to the left makes the number larger, effectively multiplying
+   * the number by `pow(2, shiftIndex)`.
+   *
+   * There is no limit on the size of the result. It may be relevant to
+   * limit intermediate values by using the "and" operator with a suitable
+   * mask.
+   *
+   * It is an error if [shiftAmount] is negative.
+   */
+  int operator <<(int shiftAmount);
+
+  /**
+   * Shift the bits of this integer to the right by [shiftAmount].
+   *
+   * Shifting to the right makes the number smaller and drops the least
+   * significant bits, effectively doing an integer division by
+   *`pow(2, shiftIndex)`.
+   *
+   * It is an error if [shiftAmount] is negative.
+   */
+  int operator >>(int shiftAmount);
+
+  /**
+   * Returns this integer to the power of [exponent] modulo [modulus].
+   *
+   * The [exponent] must be non-negative and [modulus] must be
+   * positive.
+   */
+  int modPow(int exponent, int modulus);
+
+  /**
+   * Returns the modular multiplicative inverse of this integer
+   * modulo [modulus].
+   *
+   * The [modulus] must be positive.
+   *
+   * It is an error if no modular inverse exists.
+   */
+  int modInverse(int modulus);
+
+  /**
+   * Returns the greatest common divisor of this integer and [other].
+   *
+   * If either number is non-zero, the result is the numerically greatest
+   * integer dividing both `this` and `other`.
+   *
+   * The greatest common divisor is independent of the order,
+   * so `x.gcd(y)` is  always the same as `y.gcd(x)`.
+   *
+   * For any integer `x`, `x.gcd(x)` is `x.abs()`.
+   *
+   * If both `this` and `other` is zero, the result is also zero.
+   */
+  int gcd(int other);
+
+  /** Returns true if and only if this integer is even. */
+  bool get isEven;
+
+  /** Returns true if and only if this integer is odd. */
+  bool get isOdd;
+
+  /**
+   * Returns the minimum number of bits required to store this integer.
+   *
+   * The number of bits excludes the sign bit, which gives the natural length
+   * for non-negative (unsigned) values.  Negative values are complemented to
+   * return the bit position of the first bit that differs from the sign bit.
+   *
+   * To find the number of bits needed to store the value as a signed value,
+   * add one, i.e. use `x.bitLength + 1`.
+   * ```
+   * x.bitLength == (-x-1).bitLength
+   *
+   * 3.bitLength == 2;     // 00000011
+   * 2.bitLength == 2;     // 00000010
+   * 1.bitLength == 1;     // 00000001
+   * 0.bitLength == 0;     // 00000000
+   * (-1).bitLength == 0;  // 11111111
+   * (-2).bitLength == 1;  // 11111110
+   * (-3).bitLength == 2;  // 11111101
+   * (-4).bitLength == 2;  // 11111100
+   * ```
+   */
+  int get bitLength;
+
+  /**
+   * Returns the least significant [width] bits of this integer as a
+   * non-negative number (i.e. unsigned representation).  The returned value has
+   * zeros in all bit positions higher than [width].
+   * ```
+   * (-1).toUnsigned(5) == 31   // 11111111  ->  00011111
+   * ```
+   * This operation can be used to simulate arithmetic from low level languages.
+   * For example, to increment an 8 bit quantity:
+   * ```
+   * q = (q + 1).toUnsigned(8);
+   * ```
+   * `q` will count from `0` up to `255` and then wrap around to `0`.
+   *
+   * If the input fits in [width] bits without truncation, the result is the
+   * same as the input.  The minimum width needed to avoid truncation of `x` is
+   * given by `x.bitLength`, i.e.
+   * ```
+   * x == x.toUnsigned(x.bitLength);
+   * ```
+   */
+  int toUnsigned(int width);
+
+  /**
+   * Returns the least significant [width] bits of this integer, extending the
+   * highest retained bit to the sign.  This is the same as truncating the value
+   * to fit in [width] bits using an signed 2-s complement representation.  The
+   * returned value has the same bit value in all positions higher than [width].
+   *
+   * ```
+   *                                V--sign bit-V
+   * 16.toSigned(5) == -16   //  00010000 -> 11110000
+   * 239.toSigned(5) == 15   //  11101111 -> 00001111
+   *                                ^           ^
+   * ```
+   * This operation can be used to simulate arithmetic from low level languages.
+   * For example, to increment an 8 bit signed quantity:
+   * ```
+   * q = (q + 1).toSigned(8);
+   * ```
+   * `q` will count from `0` up to `127`, wrap to `-128` and count back up to
+   * `127`.
+   *
+   * If the input value fits in [width] bits without truncation, the result is
+   * the same as the input.  The minimum width needed to avoid truncation of `x`
+   * is `x.bitLength + 1`, i.e.
+   * ```
+   * x == x.toSigned(x.bitLength + 1);
+   * ```
+   */
+  int toSigned(int width);
+
+  /**
+   * Return the negative value of this integer.
+   *
+   * The result of negating an integer always has the opposite sign, except
+   * for zero, which is its own negation.
+   */
+  int operator -();
+
+  /**
+   * Returns the absolute value of this integer.
+   *
+   * For any integer `x`, the result is the same as `x < 0 ? -x : x`.
+   */
+  int abs();
+
+  /**
+   * Returns the sign of this integer.
+   *
+   * Returns 0 for zero, -1 for values less than zero and
+   * +1 for values greater than zero.
+   */
+  int get sign;
+
+  /** Returns `this`. */
+  int round();
+
+  /** Returns `this`. */
+  int floor();
+
+  /** Returns `this`. */
+  int ceil();
+
+  /** Returns `this`. */
+  int truncate();
+
+  /** Returns `this.toDouble()`. */
+  double roundToDouble();
+
+  /** Returns `this.toDouble()`. */
+  double floorToDouble();
+
+  /** Returns `this.toDouble()`. */
+  double ceilToDouble();
+
+  /** Returns `this.toDouble()`. */
+  double truncateToDouble();
+
+  /**
+   * Returns a string representation of this integer.
+   *
+   * The returned string is parsable by [parse].
+   * For any `int` `i`, it is guaranteed that
+   * `i == int.parse(i.toString())`.
+   */
+  String toString();
+
+  /**
+   * Converts [this] to a string representation in the given [radix].
+   *
+   * In the string representation, lower-case letters are used for digits above
+   * '9', with 'a' being 10 an 'z' being 35.
+   *
+   * The [radix] argument must be an integer in the range 2 to 36.
+   */
+  String toRadixString(int radix);
+
+  /**
+   * Parse [source] as a, possibly signed, integer literal and return its value.
+   *
+   * The [source] must be a non-empty sequence of base-[radix] digits,
+   * optionally prefixed with a minus or plus sign ('-' or '+').
+   * It must not be `null`.
+   *
+   * The [radix] must be in the range 2..36. The digits used are
+   * first the decimal digits 0..9, and then the letters 'a'..'z' with
+   * values 10 through 35. Also accepts upper-case letters with the same
+   * values as the lower-case ones.
+   *
+   * If no [radix] is given then it defaults to 10. In this case, the [source]
+   * digits may also start with `0x`, in which case the number is interpreted
+   * as a hexadecimal integer literal,
+   * When `int` is implemented by 64-bit signed integers,
+   * hexadecimal integer literals may represent values larger than
+   * 2<sup>63</sup>, in which case the value is parsed as if it is an
+   * *unsigned* number, and the resulting value is the corresponding
+   * signed integer value.
+   *
+   * For any int `n` and valid radix `r`, it is guaranteed that
+   * `n == int.parse(n.toRadixString(r), radix: r)`.
+   *
+   * If the [source] string does not contain a valid integer literal,
+   * optionally prefixed by a sign, a [FormatException] is thrown
+   * (unless the deprecated [onError] parameter is used, see below).
+   *
+   * Instead of throwing and immediately catching the [FormatException],
+   * instead use [tryParse] to handle a parsing error.
+   * Example:
+   * ```dart
+   * var value = int.tryParse(text);
+   * if (value == null) ... handle the problem
+   * ```
+   *
+   * The [onError] parameter is deprecated and will be removed.
+   * Instead of `int.parse(string, onError: (string) => ...)`,
+   * you should use `int.tryParse(string) ?? (...)`.
+   *
+   * When the source string is not valid and [onError] is provided,
+   * whenever a [FormatException] would be thrown,
+   * [onError] is instead called with [source] as argument,
+   * and the result of that call is returned by [parse].
+   */
+  external static int parse(String source,
+      {int radix, @deprecated int onError(String source)});
+
+  /**
+   * Parse [source] as a, possibly signed, integer literal and return its value.
+   *
+   * Like [parse] except that this function returns `null` where a
+   * similar call to [parse] would throw a [FormatException],
+   * and the [source] must still not be `null`.
+   */
+  external static int tryParse(String source, {int radix});
+}
diff --git a/sdk_nnbd/lib/core/invocation.dart b/sdk_nnbd/lib/core/invocation.dart
new file mode 100644
index 0000000..e9ea57e
--- /dev/null
+++ b/sdk_nnbd/lib/core/invocation.dart
@@ -0,0 +1,162 @@
+// Copyright (c) 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 dart.core;
+
+/**
+ * Representation of the invocation of a member on an object.
+ *
+ * This is the type of objects passed to [Object.noSuchMethod] when
+ * an object doesn't support the member invocation that was attempted
+ * on it.
+ */
+abstract class Invocation {
+  Invocation();
+
+  /**
+   * Creates an invocation corresponding to a method invocation.
+   *
+   * The method invocation has no type arguments.
+   * If the named arguments are omitted, they default to no named arguments.
+   */
+  factory Invocation.method(
+          Symbol memberName, Iterable<Object> positionalArguments,
+          [Map<Symbol, Object> namedArguments]) =>
+      _Invocation.method(memberName, null, positionalArguments, namedArguments);
+
+  /**
+   * Creates an invocation corresponding to a generic method invocation.
+   *
+   * If [typeArguments] is `null` or empty, the constructor is equivalent to
+   * calling [Invocation.method] with the remaining arguments.
+   * All the individual type arguments must be non-null.
+   *
+   * If the named arguments are omitted, they default to no named arguments.
+   */
+  factory Invocation.genericMethod(Symbol memberName,
+          Iterable<Type> typeArguments, Iterable<Object> positionalArguments,
+          [Map<Symbol, Object> namedArguments]) =>
+      _Invocation.method(
+          memberName, typeArguments, positionalArguments, namedArguments);
+
+  /**
+   * Creates an invocation corresponding to a getter invocation.
+   */
+  factory Invocation.getter(Symbol name) = _Invocation.getter;
+
+  /**
+   * Creates an invocation corresponding to a setter invocation.
+   *
+   * This constructor accepts any [Symbol] as [memberName], but remember that
+   * *actual setter names* end in `=`, so the invocation corresponding
+   * to `object.member = value` is
+   * ```dart
+   * Invocation.setter(const Symbol("member="), value)
+   * ```
+   */
+  factory Invocation.setter(Symbol memberName, Object argument) =
+      _Invocation.setter;
+
+  /** The name of the invoked member. */
+  Symbol get memberName;
+
+  /**
+   * An unmodifiable view of the type arguments of the call.
+   *
+   * If the member is a getter, setter or operator,
+   * the type argument list is always empty.
+   */
+  List<Type> get typeArguments => const <Type>[];
+
+  /**
+   * An unmodifiable view of the positional arguments of the call.
+   *
+   * If the member is a getter, the positional arguments list is
+   * always empty.
+   */
+  List<dynamic> get positionalArguments;
+
+  /**
+   * An unmodifiable view of the named arguments of the call.
+   *
+   * If the member is a getter, setter or operator,
+   * the named arguments map is always empty.
+   */
+  Map<Symbol, dynamic> get namedArguments;
+
+  /** Whether the invocation was a method call. */
+  bool get isMethod;
+
+  /**
+   * Whether the invocation was a getter call.
+   * If so, all three types of arguments lists are empty.
+   */
+  bool get isGetter;
+
+  /**
+   * Whether the invocation was a setter call.
+   *
+   * If so, [positionalArguments] has exactly one positional
+   * argument, [namedArguments] is empty, and typeArguments is
+   * empty.
+   */
+  bool get isSetter;
+
+  /** Whether the invocation was a getter or a setter call. */
+  bool get isAccessor => isGetter || isSetter;
+}
+
+/** Implementation of [Invocation] used by its factory constructors. */
+class _Invocation implements Invocation {
+  final Symbol memberName;
+  final List<Type> typeArguments;
+  // Positional arguments is `null` for getters only.
+  final List<Object> _positional;
+  // Named arguments is `null` for accessors only.
+  final Map<Symbol, Object> _named;
+
+  _Invocation.method(this.memberName, Iterable<Type> types,
+      Iterable<Object> positional, Map<Symbol, Object> named)
+      : typeArguments = _ensureNonNullTypes(_makeUnmodifiable<Type>(types)),
+        _positional = _makeUnmodifiable<Object>(positional) ?? const <Object>[],
+        _named = (named == null || named.isEmpty)
+            ? const <Symbol, Object>{}
+            : Map<Symbol, Object>.unmodifiable(named);
+
+  _Invocation.getter(this.memberName)
+      : typeArguments = const <Type>[],
+        _positional = null,
+        _named = null;
+
+  _Invocation.setter(this.memberName, Object argument)
+      : typeArguments = const <Type>[],
+        _positional = List<Object>.unmodifiable([argument]),
+        _named = null;
+
+  List<dynamic> get positionalArguments => _positional ?? const <Object>[];
+
+  Map<Symbol, dynamic> get namedArguments => _named ?? const <Symbol, Object>{};
+
+  bool get isMethod => _named != null;
+  bool get isGetter => _positional == null;
+  bool get isSetter => _positional != null && _named == null;
+  bool get isAccessor => _named == null;
+
+  /// Checks that the elements of [types] are not null.
+  static List<Type> _ensureNonNullTypes(List<Type> types) {
+    if (types == null) return const <Type>[];
+    for (int i = 0; i < types.length; i++) {
+      if (types[i] == null) {
+        throw ArgumentError(
+            "Type arguments must be non-null, was null at index $i.");
+      }
+    }
+    return types;
+  }
+
+  static List<T> _makeUnmodifiable<T>(Iterable<T> elements) {
+    if (elements == null) return null;
+    return List<T>.unmodifiable(elements);
+  }
+}
diff --git a/sdk_nnbd/lib/core/iterable.dart b/sdk_nnbd/lib/core/iterable.dart
new file mode 100644
index 0000000..0744937
--- /dev/null
+++ b/sdk_nnbd/lib/core/iterable.dart
@@ -0,0 +1,707 @@
+// 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.
+
+part of dart.core;
+
+/**
+ * A collection of values, or "elements", that can be accessed sequentially.
+ *
+ * The elements of the iterable are accessed by getting an [Iterator]
+ * using the [iterator] getter, and using it to step through the values.
+ * Stepping with the iterator is done by calling [Iterator.moveNext],
+ * and if the call returns `true`,
+ * the iterator has now moved to the next element,
+ * which is then available as [Iterator.current].
+ * If the call returns `false`, there are no more elements,
+ * and `iterator.current` returns `null`.
+ *
+ * You can create more than one iterator from the same `Iterable`.
+ * Each time `iterator` is read, it returns a new iterator,
+ * and different iterators can be stepped through independently,
+ * each giving access to all the elements of the iterable.
+ * The iterators of the same iterable *should* provide the same values
+ * in the same order (unless the underlying collection is modified between
+ * the iterations, which some collections allow).
+ *
+ * You can also iterate over the elements of an `Iterable`
+ * using the for-in loop construct, which uses the `iterator` getter behind the
+ * scenes.
+ * For example, you can iterate over all of the keys of a [Map],
+ * because `Map` keys are iterable.
+ *
+ *     Map kidsBooks = {'Matilda': 'Roald Dahl',
+ *                      'Green Eggs and Ham': 'Dr Seuss',
+ *                      'Where the Wild Things Are': 'Maurice Sendak'};
+ *     for (var book in kidsBooks.keys) {
+ *       print('$book was written by ${kidsBooks[book]}');
+ *     }
+ *
+ * The [List] and [Set] classes are both `Iterable`,
+ * as are most classes in the `dart:collection` library.
+ *
+ * Some [Iterable] collections can be modified.
+ * Adding an element to a `List` or `Set` will change which elements it
+ * contains, and adding a new key to a `Map` changes the elements of [Map.keys].
+ * Iterators created after the change will provide the new elements, and may
+ * or may not preserve the order of existing elements
+ * (for example, a [HashSet] may completely change its order when a single
+ * element is added).
+ *
+ * Changing a collection *while* it is being iterated
+ * is generally *not* allowed.
+ * Doing so will break the iteration, which is typically signalled
+ * by throwing a [ConcurrentModificationError]
+ * the next time [Iterator.moveNext] is called.
+ * The current value of [Iterator.current] getter
+ * should not be affected by the change in the collection,
+ * the `current` value was set by the previous call to [Iterator.moveNext].
+ *
+ * Some iterables compute their elements dynamically every time they are
+ * iterated, like the one returned by [Iterable.generate] or the iterable
+ * returned by a `sync*` generator function. If the computation doesn't depend
+ * on other objects that may change, then the generated sequence should be
+ * the same one every time it's iterated.
+ *
+ * The members of `Iterable`, other than `iterator` itself,
+ * work by looking at the elements of the iterable.
+ * This can be implemented by running through the [iterator], but some classes
+ * may have more efficient ways of finding the result
+ * (like [last] or [length] on a [List], or [contains] on a [Set]).
+ *
+ * The methods that return another `Iterable` (like [map] and [where])
+ * are all *lazy* - they will iterate the original (as necessary)
+ * every time the returned iterable is iterated, and not before.
+ *
+ * Since an iterable may be iterated more than once, it's not recommended to
+ * have detectable side-effects in the iterator.
+ * For methods like [map] and [where], the returned iterable will execute the
+ * argument function on every iteration, so those functions should also not
+ * have side effects.
+ */
+abstract class Iterable<E> {
+  // TODO(lrn): When we allow forwarding const constructors through
+  // mixin applications, make this class implement [IterableMixin].
+  const Iterable();
+
+  /**
+   * Creates an `Iterable` which generates its elements dynamically.
+   *
+   * The generated iterable has [count] elements,
+   * and the element at index `n` is computed by calling `generator(n)`.
+   * Values are not cached, so each iteration computes the values again.
+   *
+   * If [generator] is omitted, it defaults to an identity function
+   * on integers `(int x) => x`, so it may only be omitted if the type
+   * parameter allows integer values. That is, if [E] is a super-type
+   * of [int].
+   *
+   * As an `Iterable`, `new Iterable.generate(n, generator))` is equivalent to
+   * `const [0, ..., n - 1].map(generator)`.
+   */
+  factory Iterable.generate(int count, [E generator(int index)]) {
+    if (count <= 0) return EmptyIterable<E>();
+    return _GeneratorIterable<E>(count, generator);
+  }
+
+  /**
+   * Creates an empty iterable.
+   *
+   * The empty iterable has no elements, and iterating it always stops
+   * immediately.
+   */
+  const factory Iterable.empty() = EmptyIterable<E>;
+
+  /**
+   * Adapts [source] to be an `Iterable<T>`.
+   *
+   * Any time the iterable would produce an element that is not a [T],
+   * the element access will throw. If all elements of [source] are actually
+   * instances of [T], or if only elements that are actually instances of [T]
+   * are accessed, then the resulting iterable can be used as an `Iterable<T>`.
+   */
+  static Iterable<T> castFrom<S, T>(Iterable<S> source) =>
+      CastIterable<S, T>(source);
+
+  /**
+   * Returns a new `Iterator` that allows iterating the elements of this
+   * `Iterable`.
+   *
+   * Iterable classes may specify the iteration order of their elements
+   * (for example [List] always iterate in index order),
+   * or they may leave it unspecified (for example a hash-based [Set]
+   * may iterate in any order).
+   *
+   * Each time `iterator` is read, it returns a new iterator,
+   * which can be used to iterate through all the elements again.
+   * The iterators of the same iterable can be stepped through independently,
+   * but should return the same elements in the same order,
+   * as long as the underlying collection isn't changed.
+   *
+   * Modifying the collection may cause new iterators to produce
+   * different elements, and may change the order of existing elements.
+   * A [List] specifies its iteration order precisely,
+   * so modifying the list changes the iteration order predictably.
+   * A hash-based [Set] may change its iteration order completely
+   * when adding a new element to the set.
+   *
+   * Modifying the underlying collection after creating the new iterator
+   * may cause an error the next time [Iterator.moveNext] is called
+   * on that iterator.
+   * Any *modifiable* iterable class should specify which operations will
+   * break iteration.
+   */
+  Iterator<E> get iterator;
+
+  /**
+   * Provides a view of this iterable as an iterable of [R] instances.
+   *
+   * If this iterable only contains instances of [R], all operations
+   * will work correctly. If any operation tries to access an element
+   * that is not an instance of [R], the access will throw instead.
+   *
+   * When the returned iterable creates a new object that depends on
+   * the type [R], e.g., from [toList], it will have exactly the type [R].
+   */
+  Iterable<R> cast<R>() => Iterable.castFrom<E, R>(this);
+  /**
+   * Returns the lazy concatentation of this iterable and [other].
+   *
+   * The returned iterable will provide the same elements as this iterable,
+   * and, after that, the elements of [other], in the same order as in the
+   * original iterables.
+   */
+  Iterable<E> followedBy(Iterable<E> other) {
+    if (this is EfficientLengthIterable<E>) {
+      return FollowedByIterable<E>.firstEfficient(this, other);
+    }
+    return FollowedByIterable<E>(this, other);
+  }
+
+  /**
+   * Returns a new lazy [Iterable] with elements that are created by
+   * calling `f` on each element of this `Iterable` in iteration order.
+   *
+   * This method returns a view of the mapped elements. As long as the
+   * returned [Iterable] is not iterated over, the supplied function [f] will
+   * not be invoked. The transformed elements will not be cached. Iterating
+   * multiple times over the returned [Iterable] will invoke the supplied
+   * function [f] multiple times on the same element.
+   *
+   * Methods on the returned iterable are allowed to omit calling `f`
+   * on any element where the result isn't needed.
+   * For example, [elementAt] may call `f` only once.
+   */
+  Iterable<T> map<T>(T f(E e)) => MappedIterable<E, T>(this, f);
+
+  /**
+   * Returns a new lazy [Iterable] with all elements that satisfy the
+   * predicate [test].
+   *
+   * The matching elements have the same order in the returned iterable
+   * as they have in [iterator].
+   *
+   * This method returns a view of the mapped elements.
+   * As long as the returned [Iterable] is not iterated over,
+   * the supplied function [test] will not be invoked.
+   * Iterating will not cache results, and thus iterating multiple times over
+   * the returned [Iterable] may invoke the supplied
+   * function [test] multiple times on the same element.
+   */
+  Iterable<E> where(bool test(E element)) => WhereIterable<E>(this, test);
+
+  /**
+   * Returns a new lazy [Iterable] with all elements that have type [T].
+   *
+   * The matching elements have the same order in the returned iterable
+   * as they have in [iterator].
+   *
+   * This method returns a view of the mapped elements.
+   * Iterating will not cache results, and thus iterating multiple times over
+   * the returned [Iterable] may yield different results,
+   * if the underlying elements change between iterations.
+   */
+  Iterable<T> whereType<T>() => WhereTypeIterable<T>(this);
+
+  /**
+   * Expands each element of this [Iterable] into zero or more elements.
+   *
+   * The resulting Iterable runs through the elements returned
+   * by [f] for each element of this, in iteration order.
+   *
+   * The returned [Iterable] is lazy, and calls [f] for each element
+   * of this every time it's iterated.
+   *
+   * Example:
+   *
+   *     var pairs = [[1, 2], [3, 4]];
+   *     var flattened = pairs.expand((pair) => pair).toList();
+   *     print(flattened); // => [1, 2, 3, 4];
+   *
+   *     var input = [1, 2, 3];
+   *     var duplicated = input.expand((i) => [i, i]).toList();
+   *     print(duplicated); // => [1, 1, 2, 2, 3, 3]
+   *
+   */
+  Iterable<T> expand<T>(Iterable<T> f(E element)) =>
+      ExpandIterable<E, T>(this, f);
+
+  /**
+   * Returns true if the collection contains an element equal to [element].
+   *
+   * This operation will check each element in order for being equal to
+   * [element], unless it has a more efficient way to find an element
+   * equal to [element].
+   *
+   * The equality used to determine whether [element] is equal to an element of
+   * the iterable defaults to the [Object.==] of the element.
+   *
+   * Some types of iterable may have a different equality used for its elements.
+   * For example, a [Set] may have a custom equality
+   * (see [Set.identity]) that its `contains` uses.
+   * Likewise the `Iterable` returned by a [Map.keys] call
+   * should use the same equality that the `Map` uses for keys.
+   */
+  bool contains(Object element) {
+    for (E e in this) {
+      if (e == element) return true;
+    }
+    return false;
+  }
+
+  /**
+   * Applies the function [f] to each element of this collection in iteration
+   * order.
+   */
+  void forEach(void f(E element)) {
+    for (E element in this) f(element);
+  }
+
+  /**
+   * Reduces a collection to a single value by iteratively combining elements
+   * of the collection using the provided function.
+   *
+   * The iterable must have at least one element.
+   * If it has only one element, that element is returned.
+   *
+   * Otherwise this method starts with the first element from the iterator,
+   * and then combines it with the remaining elements in iteration order,
+   * as if by:
+   *
+   *     E value = iterable.first;
+   *     iterable.skip(1).forEach((element) {
+   *       value = combine(value, element);
+   *     });
+   *     return value;
+   *
+   * Example of calculating the sum of an iterable:
+   *
+   *     iterable.reduce((value, element) => value + element);
+   *
+   */
+  E reduce(E combine(E value, E element)) {
+    Iterator<E> iterator = this.iterator;
+    if (!iterator.moveNext()) {
+      throw IterableElementError.noElement();
+    }
+    E value = iterator.current;
+    while (iterator.moveNext()) {
+      value = combine(value, iterator.current);
+    }
+    return value;
+  }
+
+  /**
+   * Reduces a collection to a single value by iteratively combining each
+   * element of the collection with an existing value
+   *
+   * Uses [initialValue] as the initial value,
+   * then iterates through the elements and updates the value with
+   * each element using the [combine] function, as if by:
+   *
+   *     var value = initialValue;
+   *     for (E element in this) {
+   *       value = combine(value, element);
+   *     }
+   *     return value;
+   *
+   * Example of calculating the sum of an iterable:
+   *
+   *     iterable.fold(0, (prev, element) => prev + element);
+   *
+   */
+  T fold<T>(T initialValue, T combine(T previousValue, E element)) {
+    var value = initialValue;
+    for (E element in this) value = combine(value, element);
+    return value;
+  }
+
+  /**
+   * Checks whether every element of this iterable satisfies [test].
+   *
+   * Checks every element in iteration order, and returns `false` if
+   * any of them make [test] return `false`, otherwise returns `true`.
+   */
+  bool every(bool test(E element)) {
+    for (E element in this) {
+      if (!test(element)) return false;
+    }
+    return true;
+  }
+
+  /**
+   * Converts each element to a [String] and concatenates the strings.
+   *
+   * Iterates through elements of this iterable,
+   * converts each one to a [String] by calling [Object.toString],
+   * and then concatenates the strings, with the
+   * [separator] string interleaved between the elements.
+   */
+  String join([String separator = ""]) {
+    Iterator<E> iterator = this.iterator;
+    if (!iterator.moveNext()) return "";
+    StringBuffer buffer = StringBuffer();
+    if (separator == null || separator == "") {
+      do {
+        buffer.write("${iterator.current}");
+      } while (iterator.moveNext());
+    } else {
+      buffer.write("${iterator.current}");
+      while (iterator.moveNext()) {
+        buffer.write(separator);
+        buffer.write("${iterator.current}");
+      }
+    }
+    return buffer.toString();
+  }
+
+  /**
+   * Checks whether any element of this iterable satisfies [test].
+   *
+   * Checks every element in iteration order, and returns `true` if
+   * any of them make [test] return `true`, otherwise returns false.
+   */
+  bool any(bool test(E element)) {
+    for (E element in this) {
+      if (test(element)) return true;
+    }
+    return false;
+  }
+
+  /**
+   * Creates a [List] containing the elements of this [Iterable].
+   *
+   * The elements are in iteration order.
+   * The list is fixed-length if [growable] is false.
+   */
+  List<E> toList({bool growable = true}) {
+    return List<E>.from(this, growable: growable);
+  }
+
+  /**
+   * Creates a [Set] containing the same elements as this iterable.
+   *
+   * The set may contain fewer elements than the iterable,
+   * if the iterable contains an element more than once,
+   * or it contains one or more elements that are equal.
+   * The order of the elements in the set is not guaranteed to be the same
+   * as for the iterable.
+   */
+  Set<E> toSet() => Set<E>.from(this);
+
+  /**
+   * Returns the number of elements in [this].
+   *
+   * Counting all elements may involve iterating through all elements and can
+   * therefore be slow.
+   * Some iterables have a more efficient way to find the number of elements.
+   */
+  int get length {
+    assert(this is! EfficientLengthIterable);
+    int count = 0;
+    Iterator it = iterator;
+    while (it.moveNext()) {
+      count++;
+    }
+    return count;
+  }
+
+  /**
+   * Returns `true` if there are no elements in this collection.
+   *
+   * May be computed by checking if `iterator.moveNext()` returns `false`.
+   */
+  bool get isEmpty => !iterator.moveNext();
+
+  /**
+   * Returns true if there is at least one element in this collection.
+   *
+   * May be computed by checking if `iterator.moveNext()` returns `true`.
+   */
+  bool get isNotEmpty => !isEmpty;
+
+  /**
+   * Returns a lazy iterable of the [count] first elements of this iterable.
+   *
+   * The returned `Iterable` may contain fewer than `count` elements, if `this`
+   * contains fewer than `count` elements.
+   *
+   * The elements can be computed by stepping through [iterator] until [count]
+   * elements have been seen.
+   *
+   * The `count` must not be negative.
+   */
+  Iterable<E> take(int count) {
+    return TakeIterable<E>(this, count);
+  }
+
+  /**
+   * Returns a lazy iterable of the leading elements satisfying [test].
+   *
+   * The filtering happens lazily. Every new iterator of the returned
+   * iterable starts iterating over the elements of `this`.
+   *
+   * The elements can be computed by stepping through [iterator] until an
+   * element is found where `test(element)` is false. At that point,
+   * the returned iterable stops (its `moveNext()` returns false).
+   */
+  Iterable<E> takeWhile(bool test(E value)) {
+    return TakeWhileIterable<E>(this, test);
+  }
+
+  /**
+   * Returns an [Iterable] that provides all but the first [count] elements.
+   *
+   * When the returned iterable is iterated, it starts iterating over `this`,
+   * first skipping past the initial [count] elements.
+   * If `this` has fewer than `count` elements, then the resulting Iterable is
+   * empty.
+   * After that, the remaining elements are iterated in the same order as
+   * in this iterable.
+   *
+   * Some iterables may be able to find later elements without first iterating
+   * through earlier elements, for example when iterating a [List].
+   * Such iterables are allowed to ignore the initial skipped elements.
+   *
+   * The [count] must not be negative.
+   */
+  Iterable<E> skip(int count) {
+    return SkipIterable<E>(this, count);
+  }
+
+  /**
+   * Returns an `Iterable` that skips leading elements while [test] is satisfied.
+   *
+   * The filtering happens lazily. Every new [Iterator] of the returned
+   * iterable iterates over all elements of `this`.
+   *
+   * The returned iterable provides elements by iterating this iterable,
+   * but skipping over all initial elements where `test(element)` returns
+   * true. If all elements satisfy `test` the resulting iterable is empty,
+   * otherwise it iterates the remaining elements in their original order,
+   * starting with the first element for which `test(element)` returns `false`.
+   */
+  Iterable<E> skipWhile(bool test(E value)) {
+    return SkipWhileIterable<E>(this, test);
+  }
+
+  /**
+   * Returns the first element.
+   *
+   * Throws a [StateError] if `this` is empty.
+   * Otherwise returns the first element in the iteration order,
+   * equivalent to `this.elementAt(0)`.
+   */
+  E get first {
+    Iterator<E> it = iterator;
+    if (!it.moveNext()) {
+      throw IterableElementError.noElement();
+    }
+    return it.current;
+  }
+
+  /**
+   * Returns the last element.
+   *
+   * Throws a [StateError] if `this` is empty.
+   * Otherwise may iterate through the elements and returns the last one
+   * seen.
+   * Some iterables may have more efficient ways to find the last element
+   * (for example a list can directly access the last element,
+   * without iterating through the previous ones).
+   */
+  E get last {
+    Iterator<E> it = iterator;
+    if (!it.moveNext()) {
+      throw IterableElementError.noElement();
+    }
+    E result;
+    do {
+      result = it.current;
+    } while (it.moveNext());
+    return result;
+  }
+
+  /**
+   * Checks that this iterable has only one element, and returns that element.
+   *
+   * Throws a [StateError] if `this` is empty or has more than one element.
+   */
+  E get single {
+    Iterator<E> it = iterator;
+    if (!it.moveNext()) throw IterableElementError.noElement();
+    E result = it.current;
+    if (it.moveNext()) throw IterableElementError.tooMany();
+    return result;
+  }
+
+  /**
+   * Returns the first element that satisfies the given predicate [test].
+   *
+   * Iterates through elements and returns the first to satisfy [test].
+   *
+   * If no element satisfies [test], the result of invoking the [orElse]
+   * function is returned.
+   * If [orElse] is omitted, it defaults to throwing a [StateError].
+   */
+  E firstWhere(bool test(E element), {E orElse()}) {
+    for (E element in this) {
+      if (test(element)) return element;
+    }
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  /**
+   * Returns the last element that satisfies the given predicate [test].
+   *
+   * An iterable that can access its elements directly may check its
+   * elements in any order (for example a list starts by checking the
+   * last element and then moves towards the start of the list).
+   * The default implementation iterates elements in iteration order,
+   * checks `test(element)` for each,
+   * and finally returns that last one that matched.
+   *
+   * If no element satisfies [test], the result of invoking the [orElse]
+   * function is returned.
+   * If [orElse] is omitted, it defaults to throwing a [StateError].
+   */
+  E lastWhere(bool test(E element), {E orElse()}) {
+    E result;
+    bool foundMatching = false;
+    for (E element in this) {
+      if (test(element)) {
+        result = element;
+        foundMatching = true;
+      }
+    }
+    if (foundMatching) return result;
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  /**
+   * Returns the single element that satisfies [test].
+   *
+   * Checks elements to see if `test(element)` returns true.
+   * If exactly one element satisfies [test], that element is returned.
+   * If more than one matching element is found, throws [StateError].
+   * If no matching element is found, returns the result of [orElse].
+   * If [orElse] is omitted, it defaults to throwing a [StateError].
+   */
+  E singleWhere(bool test(E element), {E orElse()}) {
+    E result;
+    bool foundMatching = false;
+    for (E element in this) {
+      if (test(element)) {
+        if (foundMatching) {
+          throw IterableElementError.tooMany();
+        }
+        result = element;
+        foundMatching = true;
+      }
+    }
+    if (foundMatching) return result;
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  /**
+   * Returns the [index]th element.
+   *
+   * The [index] must be non-negative and less than [length].
+   * Index zero represents the first element (so `iterable.elementAt(0)` is
+   * equivalent to `iterable.first`).
+   *
+   * May iterate through the elements in iteration order, ignoring the
+   * first [index] elements and then returning the next.
+   * Some iterables may have more a efficient way to find the element.
+   */
+  E elementAt(int index) {
+    ArgumentError.checkNotNull(index, "index");
+    RangeError.checkNotNegative(index, "index");
+    int elementIndex = 0;
+    for (E element in this) {
+      if (index == elementIndex) return element;
+      elementIndex++;
+    }
+    throw RangeError.index(index, this, "index", null, elementIndex);
+  }
+
+  /**
+   * Returns a string representation of (some of) the elements of `this`.
+   *
+   * Elements are represented by their own `toString` results.
+   *
+   * The default representation always contains the first three elements.
+   * If there are less than a hundred elements in the iterable, it also
+   * contains the last two elements.
+   *
+   * If the resulting string isn't above 80 characters, more elements are
+   * included from the start of the iterable.
+   *
+   * The conversion may omit calling `toString` on some elements if they
+   * are known to not occur in the output, and it may stop iterating after
+   * a hundred elements.
+   */
+  String toString() => IterableBase.iterableToShortString(this, '(', ')');
+}
+
+typedef _Generator<E> = E Function(int index);
+
+class _GeneratorIterable<E> extends ListIterable<E> {
+  /// The length of the generated iterable.
+  final int length;
+
+  /// The function mapping indices to values.
+  final _Generator<E> _generator;
+
+  /// Creates the generated iterable.
+  ///
+  /// If [generator] is `null`, it is checked that `int` is assignable to [E].
+  _GeneratorIterable(this.length, E generator(int index))
+      : // The `as` below is used as check to make sure that `int` is assignable
+        // to [E].
+        _generator = (generator != null) ? generator : _id as _Generator<E>;
+
+  E elementAt(int index) {
+    RangeError.checkValidIndex(index, this);
+    return _generator(index);
+  }
+
+  /// Helper function used as default _generator function.
+  static int _id(int n) => n;
+}
+
+/**
+ * An Iterator that allows moving backwards as well as forwards.
+ */
+abstract class BidirectionalIterator<E> implements Iterator<E> {
+  /**
+   * Move back to the previous element.
+   *
+   * Returns true and updates [current] if successful. Returns false
+   * and sets [current] to null if there is no previous element.
+   */
+  bool movePrevious();
+}
diff --git a/sdk_nnbd/lib/core/iterator.dart b/sdk_nnbd/lib/core/iterator.dart
new file mode 100644
index 0000000..cd0ad32
--- /dev/null
+++ b/sdk_nnbd/lib/core/iterator.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 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 dart.core;
+
+/**
+ * An interface for getting items, one at a time, from an object.
+ *
+ * The for-in construct transparently uses `Iterator` to test for the end
+ * of the iteration, and to get each item (or _element_).
+ *
+ * If the object iterated over is changed during the iteration, the
+ * behavior is unspecified.
+ *
+ * The `Iterator` is initially positioned before the first element.
+ * Before accessing the first element the iterator must thus be advanced using
+ * [moveNext] to point to the first element.
+ * If no element is left, then [moveNext] returns false, [current]
+ * returns `null`, and all further calls to [moveNext] will also return false.
+ *
+ * A typical usage of an Iterator looks as follows:
+ *
+ *     var it = obj.iterator;
+ *     while (it.moveNext()) {
+ *       use(it.current);
+ *     }
+ *
+ * **See also:**
+ * [Iteration](http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#iteration)
+ * in the [library tour](http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html)
+ */
+abstract class Iterator<E> {
+  /**
+   * Moves to the next element.
+   *
+   * Returns true if [current] contains the next element.
+   * Returns false if no elements are left.
+   *
+   * It is safe to invoke [moveNext] even when the iterator is already
+   * positioned after the last element.
+   * In this case [moveNext] returns false again and has no effect.
+   *
+   * A call to `moveNext` may throw if iteration has been broken by
+   * changing the underlying collection.
+   */
+  bool moveNext();
+
+  /**
+   * Returns the current element.
+   *
+   * Returns `null` if the iterator has not yet been moved to the first
+   * element, or if the iterator has been moved past the last element of the
+   * [Iterable].
+   *
+   * The `current` getter should keep its value until the next call to
+   * [moveNext], even if an underlying collection changes.
+   * After a successful call to `moveNext`, the user doesn't need to cache
+   * the current value, but can keep reading it from the iterator.
+   */
+  E get current;
+}
diff --git a/sdk_nnbd/lib/core/list.dart b/sdk_nnbd/lib/core/list.dart
new file mode 100644
index 0000000..27e1653
--- /dev/null
+++ b/sdk_nnbd/lib/core/list.dart
@@ -0,0 +1,731 @@
+// Copyright (c) 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 dart.core;
+
+/**
+ * An indexable collection of objects with a length.
+ *
+ * Subclasses of this class implement different kinds of lists.
+ * The most common kinds of lists are:
+ *
+ * * Fixed-length list.
+ *   An error occurs when attempting to use operations
+ *   that can change the length of the list.
+ *
+ * * Growable list. Full implementation of the API defined in this class.
+ *
+ * The default growable list, as returned by `new List()` or `[]`, keeps
+ * an internal buffer, and grows that buffer when necessary. This guarantees
+ * that a sequence of [add] operations will each execute in amortized constant
+ * time. Setting the length directly may take time proportional to the new
+ * length, and may change the internal capacity so that a following add
+ * operation will need to immediately increase the buffer capacity.
+ * Other list implementations may have different performance behavior.
+ *
+ * The following code illustrates that some List implementations support
+ * only a subset of the API.
+ *
+ *     List<int> fixedLengthList = new List(5);
+ *     fixedLengthList.length = 0;  // Error
+ *     fixedLengthList.add(499);    // Error
+ *     fixedLengthList[0] = 87;
+ *     List<int> growableList = [1, 2];
+ *     growableList.length = 0;
+ *     growableList.add(499);
+ *     growableList[0] = 87;
+ *
+ * Lists are [Iterable]. Iteration occurs over values in index order. Changing
+ * the values does not affect iteration, but changing the valid
+ * indices&mdash;that is, changing the list's length&mdash;between iteration
+ * steps causes a [ConcurrentModificationError]. This means that only growable
+ * lists can throw ConcurrentModificationError. If the length changes
+ * temporarily and is restored before continuing the iteration, the iterator
+ * does not detect it.
+ *
+ * It is generally not allowed to modify the list's length (adding or removing
+ * elements) while an operation on the list is being performed,
+ * for example during a call to [forEach] or [sort].
+ * Changing the list's length while it is being iterated, either by iterating it
+ * directly or through iterating an [Iterable] that is backed by the list, will
+ * break the iteration.
+ */
+abstract class List<E> implements EfficientLengthIterable<E> {
+  /**
+   * Creates a list of the given length.
+   *
+   * The created list is fixed-length if [length] is provided.
+   *
+   *     List fixedLengthList = new List(3);
+   *     fixedLengthList.length;     // 3
+   *     fixedLengthList.length = 1; // Error
+   *
+   * The list has length 0 and is growable if [length] is omitted.
+   *
+   *     List growableList = new List();
+   *     growableList.length; // 0;
+   *     growableList.length = 3;
+   *
+   * To create a growable list with a given length, just assign the length
+   * right after creation:
+   *
+   *     List growableList = new List()..length = 500;
+   *
+   * The [length] must not be negative or null, if it is provided.
+   */
+  external factory List([int length]);
+
+  /**
+   * Creates a list of the given length with [fill] at each position.
+   *
+   * The [length] must be a non-negative integer.
+   *
+   * Example:
+   * ```dart
+   * new List<int>.filled(3, 0, growable: true); // [0, 0, 0]
+   * ```
+   *
+   * The created list is fixed-length if [growable] is false (the default)
+   * and growable if [growable] is true.
+   * If the list is growable, changing its length will not initialize new
+   * entries with [fill].
+   * After being created and filled, the list is no different from any other
+   * growable or fixed-length list created using [List].
+   *
+   * All elements of the returned list share the same [fill] value.
+   * ```
+   * var shared = new List.filled(3, []);
+   * shared[0].add(499);
+   * print(shared);  // => [[499], [499], [499]]
+   * ```
+   *
+   * You can use [List.generate] to create a list with a new object at
+   * each position.
+   * ```
+   * var unique = new List.generate(3, (_) => []);
+   * unique[0].add(499);
+   * print(unique); // => [[499], [], []]
+   * ```
+   */
+  external factory List.filled(int length, E fill, {bool growable = false});
+
+  /**
+   * Creates a list containing all [elements].
+   *
+   * The [Iterator] of [elements] provides the order of the elements.
+   *
+   * All the [elements] should be instances of [E].
+   * The `elements` iterable itself may have any element type, so this
+   * constructor can be used to down-cast a `List`, for example as:
+   * ```dart
+   * List<SuperType> superList = ...;
+   * List<SubType> subList =
+   *     new List<SubType>.from(superList.whereType<SubType>());
+   * ```
+   *
+   * This constructor creates a growable list when [growable] is true;
+   * otherwise, it returns a fixed-length list.
+   */
+  external factory List.from(Iterable elements, {bool growable = true});
+
+  /**
+   * Creates a list from [elements].
+   *
+   * The [Iterator] of [elements] provides the order of the elements.
+   *
+   * This constructor creates a growable list when [growable] is true;
+   * otherwise, it returns a fixed-length list.
+   */
+  factory List.of(Iterable<E> elements, {bool growable = true}) =>
+      List<E>.from(elements, growable: growable);
+
+  /**
+   * Generates a list of values.
+   *
+   * Creates a list with [length] positions and fills it with values created by
+   * calling [generator] for each index in the range `0` .. `length - 1`
+   * in increasing order.
+   *
+   *     new List<int>.generate(3, (int index) => index * index); // [0, 1, 4]
+   *
+   * The created list is fixed-length unless [growable] is true.
+   */
+  factory List.generate(int length, E generator(int index),
+      {bool growable = true}) {
+    List<E> result;
+    if (growable) {
+      result = <E>[]..length = length;
+    } else {
+      result = List<E>(length);
+    }
+    for (int i = 0; i < length; i++) {
+      result[i] = generator(i);
+    }
+    return result;
+  }
+
+  /**
+   * Creates an unmodifiable list containing all [elements].
+   *
+   * The [Iterator] of [elements] provides the order of the elements.
+   *
+   * An unmodifiable list cannot have its length or elements changed.
+   * If the elements are themselves immutable, then the resulting list
+   * is also immutable.
+   */
+  external factory List.unmodifiable(Iterable elements);
+
+  /**
+   * Adapts [source] to be a `List<T>`.
+   *
+   * Any time the list would produce an element that is not a [T],
+   * the element access will throw.
+   *
+   * Any time a [T] value is attempted stored into the adapted list,
+   * the store will throw unless the value is also an instance of [S].
+   *
+   * If all accessed elements of [source] are actually instances of [T],
+   * and if all elements stored into the returned list are actually instance
+   * of [S],
+   * then the returned list can be used as a `List<T>`.
+   */
+  static List<T> castFrom<S, T>(List<S> source) => CastList<S, T>(source);
+
+  /**
+   * Copy a range of one list into another list.
+   *
+   * This is a utility function that can be used to implement methods like
+   * [setRange].
+   *
+   * The range from [start] to [end] must be a valid range of [source],
+   * and there must be room for `end - start` elements from position [at].
+   * If [start] is omitted, it defaults to zero.
+   * If [end] is omitted, it defaults to [source.length].
+   *
+   * If [source] and [target] is the same list, overlapping source and target
+   * ranges are respected so that the target range ends up containing the
+   * initial content of the source range.
+   * Otherwise the order of element copying is not guaranteed.
+   */
+  static void copyRange<T>(List<T> target, int at, List<T> source,
+      [int start, int end]) {
+    start ??= 0;
+    end = RangeError.checkValidRange(start, end, source.length);
+    int length = end - start;
+    if (target.length < at + length) {
+      throw ArgumentError.value(target, "target",
+          "Not big enough to hold $length elements at position $at");
+    }
+    if (!identical(source, target) || start >= at) {
+      for (int i = 0; i < length; i++) {
+        target[at + i] = source[start + i];
+      }
+    } else {
+      for (int i = length; --i >= 0;) {
+        target[at + i] = source[start + i];
+      }
+    }
+  }
+
+  /**
+   * Write the elements of an iterable into a list.
+   *
+   * This is a utility function that can be used to implement methods like
+   * [setAll].
+   *
+   * The elements of [source] are written into [target] from position [at].
+   * The [source] must not contain more elements after writing the last
+   * position of [target].
+   *
+   * If the source is a list, the [copyRange] function is likely to be more
+   * efficient.
+   */
+  static void writeIterable<T>(List<T> target, int at, Iterable<T> source) {
+    RangeError.checkValueInInterval(at, 0, target.length, "at");
+    int index = at;
+    int targetLength = target.length;
+    for (var element in source) {
+      if (index == targetLength) {
+        throw IndexError(targetLength, target);
+      }
+      target[index] = element;
+      index++;
+    }
+  }
+
+  /**
+   * Returns a view of this list as a list of [R] instances.
+   *
+   * If this list contains only instances of [R], all read operations
+   * will work correctly. If any operation tries to access an element
+   * that is not an instance of [R], the access will throw instead.
+   *
+   * Elements added to the list (e.g., by using [add] or [addAll])
+   * must be instance of [R] to be valid arguments to the adding function,
+   * and they must be instances of [E] as well to be accepted by
+   * this list as well.
+   *
+   * Typically implemented as `List.castFrom<E, R>(this)`.
+   */
+  List<R> cast<R>();
+  /**
+   * Returns the object at the given [index] in the list
+   * or throws a [RangeError] if [index] is out of bounds.
+   */
+  E operator [](int index);
+
+  /**
+   * Sets the value at the given [index] in the list to [value]
+   * or throws a [RangeError] if [index] is out of bounds.
+   */
+  void operator []=(int index, E value);
+
+  /**
+   * Updates the first position of the list to contain [value].
+   *
+   * Equivalent to `theList[0] = value;`.
+   *
+   * The list must be non-empty.
+   */
+  void set first(E value);
+
+  /**
+   * Updates the last position of the list to contain [value].
+   *
+   * Equivalent to `theList[theList.length - 1] = value;`.
+   *
+   * The list must be non-empty.
+   */
+  void set last(E value);
+
+  /**
+   * Returns the number of objects in this list.
+   *
+   * The valid indices for a list are `0` through `length - 1`.
+   */
+  int get length;
+
+  /**
+   * Changes the length of this list.
+   *
+   * If [newLength] is greater than
+   * the current length, entries are initialized to [:null:].
+   *
+   * Throws an [UnsupportedError] if the list is fixed-length.
+   */
+  set length(int newLength);
+
+  /**
+   * Adds [value] to the end of this list,
+   * extending the length by one.
+   *
+   * Throws an [UnsupportedError] if the list is fixed-length.
+   */
+  void add(E value);
+
+  /**
+   * Appends all objects of [iterable] to the end of this list.
+   *
+   * Extends the length of the list by the number of objects in [iterable].
+   * Throws an [UnsupportedError] if this list is fixed-length.
+   */
+  void addAll(Iterable<E> iterable);
+
+  /**
+   * Returns an [Iterable] of the objects in this list in reverse order.
+   */
+  Iterable<E> get reversed;
+
+  /**
+   * Sorts this list according to the order specified by the [compare] function.
+   *
+   * The [compare] function must act as a [Comparator].
+   *
+   *     List<String> numbers = ['two', 'three', 'four'];
+   *     // Sort from shortest to longest.
+   *     numbers.sort((a, b) => a.length.compareTo(b.length));
+   *     print(numbers);  // [two, four, three]
+   *
+   * The default List implementations use [Comparable.compare] if
+   * [compare] is omitted.
+   *
+   *     List<int> nums = [13, 2, -11];
+   *     nums.sort();
+   *     print(nums);  // [-11, 2, 13]
+   *
+   * A [Comparator] may compare objects as equal (return zero), even if they
+   * are distinct objects.
+   * The sort function is not guaranteed to be stable, so distinct objects
+   * that compare as equal may occur in any order in the result:
+   *
+   *     List<String> numbers = ['one', 'two', 'three', 'four'];
+   *     numbers.sort((a, b) => a.length.compareTo(b.length));
+   *     print(numbers);  // [one, two, four, three] OR [two, one, four, three]
+   */
+  void sort([int compare(E a, E b)]);
+
+  /**
+   * Shuffles the elements of this list randomly.
+   */
+  void shuffle([Random random]);
+
+  /**
+   * Returns the first index of [element] in this list.
+   *
+   * Searches the list from index [start] to the end of the list.
+   * The first time an object [:o:] is encountered so that [:o == element:],
+   * the index of [:o:] is returned.
+   *
+   *     List<String> notes = ['do', 're', 'mi', 're'];
+   *     notes.indexOf('re');    // 1
+   *     notes.indexOf('re', 2); // 3
+   *
+   * Returns -1 if [element] is not found.
+   *
+   *     notes.indexOf('fa');    // -1
+   */
+  int indexOf(E element, [int start = 0]);
+
+  /**
+   * Returns the first index in the list that satisfies the provided [test].
+   *
+   * Searches the list from index [start] to the end of the list.
+   * The first time an object `o` is encountered so that `test(o)` is true,
+   * the index of `o` is returned.
+   *
+   * ```
+   * List<String> notes = ['do', 're', 'mi', 're'];
+   * notes.indexWhere((note) => note.startsWith('r'));       // 1
+   * notes.indexWhere((note) => note.startsWith('r'), 2);    // 3
+   * ```
+   *
+   * Returns -1 if [element] is not found.
+   * ```
+   * notes.indexWhere((note) => note.startsWith('k'));    // -1
+   * ```
+   */
+  int indexWhere(bool test(E element), [int start = 0]);
+
+  /**
+   * Returns the last index in the list that satisfies the provided [test].
+   *
+   * Searches the list from index [start] to 0.
+   * The first time an object `o` is encountered so that `test(o)` is true,
+   * the index of `o` is returned.
+   *
+   * ```
+   * List<String> notes = ['do', 're', 'mi', 're'];
+   * notes.lastIndexWhere((note) => note.startsWith('r'));       // 3
+   * notes.lastIndexWhere((note) => note.startsWith('r'), 2);    // 1
+   * ```
+   *
+   * Returns -1 if [element] is not found.
+   * ```
+   * notes.lastIndexWhere((note) => note.startsWith('k'));    // -1
+   * ```
+   */
+  int lastIndexWhere(bool test(E element), [int start]);
+
+  /**
+   * Returns the last index of [element] in this list.
+   *
+   * Searches the list backwards from index [start] to 0.
+   *
+   * The first time an object [:o:] is encountered so that [:o == element:],
+   * the index of [:o:] is returned.
+   *
+   *     List<String> notes = ['do', 're', 'mi', 're'];
+   *     notes.lastIndexOf('re', 2); // 1
+   *
+   * If [start] is not provided, this method searches from the end of the
+   * list./Returns
+   *
+   *     notes.lastIndexOf('re');  // 3
+   *
+   * Returns -1 if [element] is not found.
+   *
+   *     notes.lastIndexOf('fa');  // -1
+   */
+  int lastIndexOf(E element, [int start]);
+
+  /**
+   * Removes all objects from this list;
+   * the length of the list becomes zero.
+   *
+   * Throws an [UnsupportedError], and retains all objects, if this
+   * is a fixed-length list.
+   */
+  void clear();
+
+  /**
+   * Inserts the object at position [index] in this list.
+   *
+   * This increases the length of the list by one and shifts all objects
+   * at or after the index towards the end of the list.
+   *
+   * The list must be growable.
+   * The [index] value must be non-negative and no greater than [length].
+   */
+  void insert(int index, E element);
+
+  /**
+   * Inserts all objects of [iterable] at position [index] in this list.
+   *
+   * This increases the length of the list by the length of [iterable] and
+   * shifts all later objects towards the end of the list.
+   *
+   * The list must be growable.
+   * The [index] value must be non-negative and no greater than [length].
+   */
+  void insertAll(int index, Iterable<E> iterable);
+
+  /**
+   * Overwrites objects of `this` with the objects of [iterable], starting
+   * at position [index] in this list.
+   *
+   *     List<String> list = ['a', 'b', 'c'];
+   *     list.setAll(1, ['bee', 'sea']);
+   *     list.join(', '); // 'a, bee, sea'
+   *
+   * This operation does not increase the length of `this`.
+   *
+   * The [index] must be non-negative and no greater than [length].
+   *
+   * The [iterable] must not have more elements than what can fit from [index]
+   * to [length].
+   *
+   * If `iterable` is based on this list, its values may change /during/ the
+   * `setAll` operation.
+   */
+  void setAll(int index, Iterable<E> iterable);
+
+  /**
+   * Removes the first occurrence of [value] from this list.
+   *
+   * Returns true if [value] was in the list, false otherwise.
+   *
+   *     List<String> parts = ['head', 'shoulders', 'knees', 'toes'];
+   *     parts.remove('head'); // true
+   *     parts.join(', ');     // 'shoulders, knees, toes'
+   *
+   * The method has no effect if [value] was not in the list.
+   *
+   *     // Note: 'head' has already been removed.
+   *     parts.remove('head'); // false
+   *     parts.join(', ');     // 'shoulders, knees, toes'
+   *
+   * An [UnsupportedError] occurs if the list is fixed-length.
+   */
+  bool remove(Object value);
+
+  /**
+   * Removes the object at position [index] from this list.
+   *
+   * This method reduces the length of `this` by one and moves all later objects
+   * down by one position.
+   *
+   * Returns the removed object.
+   *
+   * The [index] must be in the range `0 ≤ index < length`.
+   *
+   * Throws an [UnsupportedError] if this is a fixed-length list. In that case
+   * the list is not modified.
+   */
+  E removeAt(int index);
+
+  /**
+   * Pops and returns the last object in this list.
+   *
+   * The list must not be empty.
+   *
+   * Throws an [UnsupportedError] if this is a fixed-length list.
+   */
+  E removeLast();
+
+  /**
+   * Removes all objects from this list that satisfy [test].
+   *
+   * An object [:o:] satisfies [test] if [:test(o):] is true.
+   *
+   *     List<String> numbers = ['one', 'two', 'three', 'four'];
+   *     numbers.removeWhere((item) => item.length == 3);
+   *     numbers.join(', '); // 'three, four'
+   *
+   * Throws an [UnsupportedError] if this is a fixed-length list.
+   */
+  void removeWhere(bool test(E element));
+
+  /**
+   * Removes all objects from this list that fail to satisfy [test].
+   *
+   * An object [:o:] satisfies [test] if [:test(o):] is true.
+   *
+   *     List<String> numbers = ['one', 'two', 'three', 'four'];
+   *     numbers.retainWhere((item) => item.length == 3);
+   *     numbers.join(', '); // 'one, two'
+   *
+   * Throws an [UnsupportedError] if this is a fixed-length list.
+   */
+  void retainWhere(bool test(E element));
+
+  /**
+   * Returns the concatenation of this list and [other].
+   *
+   * Returns a new list containing the elements of this list followed by
+   * the elements of [other].
+   *
+   * The default behavior is to return a normal growable list.
+   * Some list types may choose to return a list of the same type as themselves
+   * (see [Uint8List.+]);
+   */
+  List<E> operator +(List<E> other);
+
+  /**
+   * Returns a new list containing the elements between [start] and [end].
+   *
+   * The new list is a `List<E>` containing the elements of this list at
+   * positions greater than or equal to [start] and less than [end] in the same
+   * order as they occur in this list.
+   *
+   * ```dart
+   * var colors = ["red", "green", "blue", "orange", "pink"];
+   * print(colors.sublist(1, 3)); // [green, blue]
+   * ```
+   *
+   * If [end] is omitted, it defaults to the [length] of this list.
+   *
+   * ```dart
+   * print(colors.sublist(1)); // [green, blue, orange, pink]
+   * ```
+   *
+   * The `start` and `end` positions must satisfy the relations
+   * 0 ≤ `start` ≤ `end` ≤ `this.length`
+   * If `end` is equal to `start`, then the returned list is empty.
+   */
+  List<E> sublist(int start, [int end]);
+
+  /**
+   * Returns an [Iterable] that iterates over the objects in the range
+   * [start] inclusive to [end] exclusive.
+   *
+   * The provided range, given by [start] and [end], must be valid at the time
+   * of the call.
+   *
+   * A range from [start] to [end] is valid if `0 <= start <= end <= len`, where
+   * `len` is this list's `length`. The range starts at `start` and has length
+   * `end - start`. An empty range (with `end == start`) is valid.
+   *
+   * The returned [Iterable] behaves like `skip(start).take(end - start)`.
+   * That is, it does *not* throw if this list changes size.
+   *
+   *     List<String> colors = ['red', 'green', 'blue', 'orange', 'pink'];
+   *     Iterable<String> range = colors.getRange(1, 4);
+   *     range.join(', ');  // 'green, blue, orange'
+   *     colors.length = 3;
+   *     range.join(', ');  // 'green, blue'
+   */
+  Iterable<E> getRange(int start, int end);
+
+  /**
+   * Copies the objects of [iterable], skipping [skipCount] objects first,
+   * into the range [start], inclusive, to [end], exclusive, of the list.
+   *
+   *     List<int> list1 = [1, 2, 3, 4];
+   *     List<int> list2 = [5, 6, 7, 8, 9];
+   *     // Copies the 4th and 5th items in list2 as the 2nd and 3rd items
+   *     // of list1.
+   *     list1.setRange(1, 3, list2, 3);
+   *     list1.join(', '); // '1, 8, 9, 4'
+   *
+   * The provided range, given by [start] and [end], must be valid.
+   * A range from [start] to [end] is valid if `0 <= start <= end <= len`, where
+   * `len` is this list's `length`. The range starts at `start` and has length
+   * `end - start`. An empty range (with `end == start`) is valid.
+   *
+   * The [iterable] must have enough objects to fill the range from `start`
+   * to `end` after skipping [skipCount] objects.
+   *
+   * If `iterable` is this list, the operation copies the elements
+   * originally in the range from `skipCount` to `skipCount + (end - start)` to
+   * the range `start` to `end`, even if the two ranges overlap.
+   *
+   * If `iterable` depends on this list in some other way, no guarantees are
+   * made.
+   */
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]);
+
+  /**
+   * Removes the objects in the range [start] inclusive to [end] exclusive.
+   *
+   * The provided range, given by [start] and [end], must be valid.
+   * A range from [start] to [end] is valid if `0 <= start <= end <= len`, where
+   * `len` is this list's `length`. The range starts at `start` and has length
+   * `end - start`. An empty range (with `end == start`) is valid.
+   *
+   * Throws an [UnsupportedError] if this is a fixed-length list. In that case
+   * the list is not modified.
+   */
+  void removeRange(int start, int end);
+
+  /**
+   * Sets the objects in the range [start] inclusive to [end] exclusive
+   * to the given [fillValue].
+   *
+   * The provided range, given by [start] and [end], must be valid.
+   * A range from [start] to [end] is valid if `0 <= start <= end <= len`, where
+   * `len` is this list's `length`. The range starts at `start` and has length
+   * `end - start`. An empty range (with `end == start`) is valid.
+   *
+   * Example:
+   * ```dart
+   *  List<int> list = new List(3);
+   *     list.fillRange(0, 2, 1);
+   *     print(list); //  [1, 1, null]
+   * ```
+   *
+   */
+  void fillRange(int start, int end, [E fillValue]);
+
+  /**
+   * Removes the objects in the range [start] inclusive to [end] exclusive
+   * and inserts the contents of [replacement] in its place.
+   *
+   *     List<int> list = [1, 2, 3, 4, 5];
+   *     list.replaceRange(1, 4, [6, 7]);
+   *     list.join(', '); // '1, 6, 7, 5'
+   *
+   * The provided range, given by [start] and [end], must be valid.
+   * A range from [start] to [end] is valid if `0 <= start <= end <= len`, where
+   * `len` is this list's `length`. The range starts at `start` and has length
+   * `end - start`. An empty range (with `end == start`) is valid.
+   *
+   * This method does not work on fixed-length lists, even when [replacement]
+   * has the same number of elements as the replaced range. In that case use
+   * [setRange] instead.
+   */
+  void replaceRange(int start, int end, Iterable<E> replacement);
+
+  /**
+   * Returns an unmodifiable [Map] view of `this`.
+   *
+   * The map uses the indices of this list as keys and the corresponding objects
+   * as values. The `Map.keys` [Iterable] iterates the indices of this list
+   * in numerical order.
+   *
+   *     List<String> words = ['fee', 'fi', 'fo', 'fum'];
+   *     Map<int, String> map = words.asMap();
+   *     map[0] + map[1];   // 'feefi';
+   *     map.keys.toList(); // [0, 1, 2, 3]
+   */
+  Map<int, E> asMap();
+
+  /**
+  * Whether this list is equal to [other].
+  *
+  * Lists are, by default, only equal to themselves.
+  * Even if [other] is also a list, the equality comparison
+  * does not compare the elements of the two lists.
+  */
+ bool operator ==(Object other);
+}
diff --git a/sdk_nnbd/lib/core/map.dart b/sdk_nnbd/lib/core/map.dart
new file mode 100644
index 0000000..f914fe1
--- /dev/null
+++ b/sdk_nnbd/lib/core/map.dart
@@ -0,0 +1,404 @@
+// 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.
+
+part of dart.core;
+
+/**
+ * A collection of key/value pairs, from which you retrieve a value
+ * using its associated key.
+ *
+ * There is a finite number of keys in the map,
+ * and each key has exactly one value associated with it.
+ *
+ * Maps, and their keys and values, can be iterated.
+ * The order of iteration is defined by the individual type of map.
+ * Examples:
+ *
+ * * The plain [HashMap] is unordered (no order is guaranteed),
+ * * the [LinkedHashMap] iterates in key insertion order,
+ * * and a sorted map like [SplayTreeMap] iterates the keys in sorted order.
+ *
+ * It is generally not allowed to modify the map (add or remove keys) while
+ * an operation is being performed on the map, for example in functions called
+ * during a [forEach] or [putIfAbsent] call.
+ * Modifying the map while iterating the keys or values
+ * may also break the iteration.
+ *
+ * It is generally not allowed to modify the equality of keys (and thus not
+ * their hashcode) while they are in the map. Some specialized subtypes may be
+ * more permissive, in which case they should document this behavior.
+ */
+abstract class Map<K, V> {
+  /**
+   * Creates a Map instance with the default implementation, [LinkedHashMap].
+   *
+   * This constructor is equivalent to the non-const map literal `<K,V>{}`.
+   *
+   * A `LinkedHashMap` requires the keys to implement compatible
+   * `operator==` and `hashCode`, and it allows null as a key.
+   * It iterates in key insertion order.
+   */
+  external factory Map();
+
+  /**
+   * Creates a [LinkedHashMap] instance that contains all key/value pairs of
+   * [other].
+   *
+   * The keys must all be instances of [K] and the values of [V].
+   * The [other] map itself can have any type.
+   *
+   * A `LinkedHashMap` requires the keys to implement compatible
+   * `operator==` and `hashCode`, and it allows `null` as a key.
+   * It iterates in key insertion order.
+   */
+  factory Map.from(Map other) = LinkedHashMap<K, V>.from;
+
+  /**
+   * Creates a [LinkedHashMap] with the same keys and values as [other].
+   *
+   * A `LinkedHashMap` requires the keys to implement compatible
+   * `operator==` and `hashCode`, and it allows `null` as a key.
+   * It iterates in key insertion order.
+   */
+  factory Map.of(Map<K, V> other) = LinkedHashMap<K, V>.of;
+
+  /**
+   * Creates an unmodifiable hash based map containing the entries of [other].
+   *
+   * The keys must all be instances of [K] and the values of [V].
+   * The [other] map itself can have any type.
+   *
+   * The map requires the keys to implement compatible
+   * `operator==` and `hashCode`, and it allows `null` as a key.
+   * The created map iterates keys in a fixed order,
+   * preserving the order provided by [other].
+   *
+   * The resulting map behaves like the result of [Map.from],
+   * except that the map returned by this constructor is not modifiable.
+   */
+  external factory Map.unmodifiable(Map other);
+
+  /**
+   * Creates an identity map with the default implementation, [LinkedHashMap].
+   *
+   * An identity map uses [identical] for equality and [identityHashCode]
+   * for hash codes of keys instead of the intrinsic [Object.operator==] and
+   * [Object.hashCode] of the keys.
+   *
+   * The returned map allows `null` as a key.
+   * It iterates in key insertion order.
+   */
+  factory Map.identity() = LinkedHashMap<K, V>.identity;
+
+  /**
+   * Creates a Map instance in which the keys and values are computed from the
+   * [iterable].
+   *
+   * The created map is a [LinkedHashMap].
+   * A `LinkedHashMap` requires the keys to implement compatible
+   * `operator==` and `hashCode`, and it allows null as a key.
+   * It iterates in key insertion order.
+   *
+   * For each element of the [iterable] this constructor computes a key/value
+   * pair, by applying [key] and [value] respectively.
+   *
+   * The example below creates a new Map from a List. The keys of `map` are
+   * `list` values converted to strings, and the values of the `map` are the
+   * squares of the `list` values:
+   *
+   *     List<int> list = [1, 2, 3];
+   *     Map<String, int> map = new Map.fromIterable(list,
+   *         key: (item) => item.toString(),
+   *         value: (item) => item * item);
+   *
+   *     map['1'] + map['2']; // 1 + 4
+   *     map['3'] - map['2']; // 9 - 4
+   *
+   * If no values are specified for [key] and [value] the default is the
+   * identity function.
+   *
+   * In the following example, the keys and corresponding values of `map`
+   * are `list` values:
+   *
+   *     map = new Map.fromIterable(list);
+   *     map[1] + map[2]; // 1 + 2
+   *     map[3] - map[2]; // 3 - 2
+   *
+   * The keys computed by the source [iterable] do not need to be unique. The
+   * last occurrence of a key will simply overwrite any previous value.
+   */
+  factory Map.fromIterable(Iterable iterable,
+      {K key(element), V value(element)}) = LinkedHashMap<K, V>.fromIterable;
+
+  /**
+   * Creates a Map instance associating the given [keys] to [values].
+   *
+   * The created map is a [LinkedHashMap].
+   * A `LinkedHashMap` requires the keys to implement compatible
+   * `operator==` and `hashCode`, and it allows null as a key.
+   * It iterates in key insertion order.
+   *
+   * This constructor iterates over [keys] and [values] and maps each element of
+   * [keys] to the corresponding element of [values].
+   *
+   *     List<String> letters = ['b', 'c'];
+   *     List<String> words = ['bad', 'cat'];
+   *     Map<String, String> map = new Map.fromIterables(letters, words);
+   *     map['b'] + map['c'];  // badcat
+   *
+   * If [keys] contains the same object multiple times, the last occurrence
+   * overwrites the previous value.
+   *
+   * The two [Iterable]s must have the same length.
+   */
+  factory Map.fromIterables(Iterable<K> keys, Iterable<V> values) =
+      LinkedHashMap<K, V>.fromIterables;
+
+  /**
+   * Adapts [source] to be a `Map<K2, V2>`.
+   *
+   * Any time the set would produce a key or value that is not a [K2] or [V2],
+   * the access will throw.
+   *
+   * Any time [K2] key or [V2] value is attempted added into the adapted map,
+   * the store will throw unless the key is also an instance of [K] and
+   * the value is also an instance of [V].
+   *
+   * If all accessed entries of [source] are have [K2] keys and [V2] values
+   * and if all entries added to the returned map have [K] keys and [V]] values,
+   * then the returned map can be used as a `Map<K2, V2>`.
+   */
+  static Map<K2, V2> castFrom<K, V, K2, V2>(Map<K, V> source) =>
+      CastMap<K, V, K2, V2>(source);
+
+  /**
+   * Creates a new map and adds all entries.
+   *
+   * Returns a new `Map<K, V>` where all entries of [entries]
+   * have been added in iteration order.
+   *
+   * If multiple [entries] have the same key,
+   * later occurrences overwrite the earlier ones.
+   */
+  factory Map.fromEntries(Iterable<MapEntry<K, V>> entries) =>
+      <K, V>{}..addEntries(entries);
+
+  /**
+   * Provides a view of this map as having [RK] keys and [RV] instances,
+   * if necessary.
+   *
+   * If this map is already a `Map<RK, RV>`, it is returned unchanged.
+   *
+   * If this set contains only keys of type [RK] and values of type [RV],
+   * all read operations will work correctly.
+   * If any operation exposes a non-[RK] key or non-[RV] value,
+   * the operation will throw instead.
+   *
+   * Entries added to the map must be valid for both a `Map<K, V>` and a
+   * `Map<RK, RV>`.
+   */
+  Map<RK, RV> cast<RK, RV>();
+  /**
+   * Returns true if this map contains the given [value].
+   *
+   * Returns true if any of the values in the map are equal to `value`
+   * according to the `==` operator.
+   */
+  bool containsValue(Object value);
+
+  /**
+   * Returns true if this map contains the given [key].
+   *
+   * Returns true if any of the keys in the map are equal to `key`
+   * according to the equality used by the map.
+   */
+  bool containsKey(Object key);
+
+  /**
+   * Returns the value for the given [key] or null if [key] is not in the map.
+   *
+   * Some maps allow keys to have `null` as a value.
+   * For those maps, a lookup using this operator cannot distinguish between a
+   * key not being in the map and the key having a `null` value.
+   * Methods like [containsKey] or [putIfAbsent] can be used if the distinction
+   * is important.
+   */
+  V operator [](Object key);
+
+  /**
+   * Associates the [key] with the given [value].
+   *
+   * If the key was already in the map, its associated value is changed.
+   * Otherwise the key/value pair is added to the map.
+   */
+  void operator []=(K key, V value);
+
+  /**
+   * The map entries of [this].
+   */
+  Iterable<MapEntry<K, V>> get entries;
+
+  /**
+   * Returns a new map where all entries of this map are transformed by
+   * the given [f] function.
+   */
+  Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> f(K key, V value));
+
+  /**
+   * Adds all key/value pairs of [newEntries] to this map.
+   *
+   * If a key of [newEntries] is already in this map,
+   * the corresponding value is overwritten.
+   *
+   * The operation is equivalent to doing `this[entry.key] = entry.value`
+   * for each [MapEntry] of the iterable.
+   */
+  void addEntries(Iterable<MapEntry<K, V>> newEntries);
+
+  /**
+   * Updates the value for the provided [key].
+   *
+   * Returns the new value of the key.
+   *
+   * If the key is present, invokes [update] with the current value and stores
+   * the new value in the map.
+   *
+   * If the key is not present and [ifAbsent] is provided, calls [ifAbsent]
+   * and adds the key with the returned value to the map.
+   *
+   * It's an error if the key is not present and [ifAbsent] is not provided.
+   */
+  V update(K key, V update(V value), {V ifAbsent()});
+
+  /**
+   * Updates all values.
+   *
+   * Iterates over all entries in the map and updates them with the result
+   * of invoking [update].
+   */
+  void updateAll(V update(K key, V value));
+
+  /**
+   * Removes all entries of this map that satisfy the given [predicate].
+   */
+  void removeWhere(bool predicate(K key, V value));
+
+  /**
+   * Look up the value of [key], or add a new value if it isn't there.
+   *
+   * Returns the value associated to [key], if there is one.
+   * Otherwise calls [ifAbsent] to get a new value, associates [key] to
+   * that value, and then returns the new value.
+   *
+   *     Map<String, int> scores = {'Bob': 36};
+   *     for (var key in ['Bob', 'Rohan', 'Sophena']) {
+   *       scores.putIfAbsent(key, () => key.length);
+   *     }
+   *     scores['Bob'];      // 36
+   *     scores['Rohan'];    //  5
+   *     scores['Sophena'];  //  7
+   *
+   * Calling [ifAbsent] must not add or remove keys from the map.
+   */
+  V putIfAbsent(K key, V ifAbsent());
+
+  /**
+   * Adds all key/value pairs of [other] to this map.
+   *
+   * If a key of [other] is already in this map, its value is overwritten.
+   *
+   * The operation is equivalent to doing `this[key] = value` for each key
+   * and associated value in other. It iterates over [other], which must
+   * therefore not change during the iteration.
+   */
+  void addAll(Map<K, V> other);
+
+  /**
+   * Removes [key] and its associated value, if present, from the map.
+   *
+   * Returns the value associated with `key` before it was removed.
+   * Returns `null` if `key` was not in the map.
+   *
+   * Note that values can be `null` and a returned `null` value doesn't
+   * always mean that the key was absent.
+   */
+  V remove(Object key);
+
+  /**
+   * Removes all pairs from the map.
+   *
+   * After this, the map is empty.
+   */
+  void clear();
+
+  /**
+   * Applies [f] to each key/value pair of the map.
+   *
+   * Calling `f` must not add or remove keys from the map.
+   */
+  void forEach(void f(K key, V value));
+
+  /**
+   * The keys of [this].
+   *
+   * The returned iterable has efficient `length` and `contains` operations,
+   * based on [length] and [containsKey] of the map.
+   *
+   * The order of iteration is defined by the individual `Map` implementation,
+   * but must be consistent between changes to the map.
+   *
+   * Modifying the map while iterating the keys
+   * may break the iteration.
+   */
+  Iterable<K> get keys;
+
+  /**
+   * The values of [this].
+   *
+   * The values are iterated in the order of their corresponding keys.
+   * This means that iterating [keys] and [values] in parallel will
+   * provide matching pairs of keys and values.
+   *
+   * The returned iterable has an efficient `length` method based on the
+   * [length] of the map. Its [Iterable.contains] method is based on
+   * `==` comparison.
+   *
+   * Modifying the map while iterating the
+   * values may break the iteration.
+   */
+  Iterable<V> get values;
+
+  /**
+   * The number of key/value pairs in the map.
+   */
+  int get length;
+
+  /**
+   * Returns true if there is no key/value pair in the map.
+   */
+  bool get isEmpty;
+
+  /**
+   * Returns true if there is at least one key/value pair in the map.
+   */
+  bool get isNotEmpty;
+}
+
+/**
+ * A key/value pair representing an entry in a [Map].
+ */
+class MapEntry<K, V> {
+  /** The key of the entry. */
+  final K key;
+
+  /** The value associated to [key] in the map. */
+  final V value;
+
+  /** Creates an entry with [key] and [value]. */
+  const factory MapEntry(K key, V value) = MapEntry<K, V>._;
+
+  const MapEntry._(this.key, this.value);
+
+  String toString() => "MapEntry($key: $value)";
+}
diff --git a/sdk_nnbd/lib/core/null.dart b/sdk_nnbd/lib/core/null.dart
new file mode 100644
index 0000000..af7d86d
--- /dev/null
+++ b/sdk_nnbd/lib/core/null.dart
@@ -0,0 +1,24 @@
+// 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 dart.core;
+
+/**
+ * The reserved word [:null:] denotes an object that is the sole instance of 
+ * this class.
+ * 
+ * It is a compile-time error for a class to attempt to extend or implement
+ * Null.
+ */
+@pragma("vm:entry-point")
+class Null {
+  factory Null._uninstantiable() {
+    throw UnsupportedError('class Null cannot be instantiated');
+  }
+
+  external int get hashCode;
+
+  /** Returns the string `"null"`. */
+  String toString() => "null";
+}
diff --git a/sdk_nnbd/lib/core/num.dart b/sdk_nnbd/lib/core/num.dart
new file mode 100644
index 0000000..e04112c
--- /dev/null
+++ b/sdk_nnbd/lib/core/num.dart
@@ -0,0 +1,493 @@
+// Copyright (c) 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 dart.core;
+
+/**
+ * An integer or floating-point number.
+ *
+ * It is a compile-time error for any type other than [int] or [double]
+ * to attempt to extend or implement num.
+ */
+abstract class num implements Comparable<num> {
+  /**
+   * Test whether this value is numerically equal to `other`.
+   *
+   * If both operands are doubles, they are equal if they have the same
+   * representation, except that:
+   *
+   *   * zero and minus zero (0.0 and -0.0) are considered equal. They
+   *     both have the numerical value zero.
+   *   * NaN is not equal to anything, including NaN. If either operand is
+   *     NaN, the result is always false.
+   *
+   * If one operand is a double and the other is an int, they are equal if
+   * the double has an integer value (finite with no fractional part) and
+   * `identical(doubleValue.toInt(), intValue)` is true.
+   *
+   * If both operands are integers, they are equal if they have the same value.
+   *
+   * Returns false if `other` is not a [num].
+   *
+   * Notice that the behavior for NaN is non-reflexive. This means that
+   * equality of double values is not a proper equality relation, as is
+   * otherwise required of `operator==`. Using NaN in, e.g., a [HashSet]
+   * will fail to work. The behavior is the standard IEEE-754 equality of
+   * doubles.
+   *
+   * If you can avoid NaN values, the remaining doubles do have a proper
+   * equality relation, and can be used safely.
+   *
+   * Use [compareTo] for a comparison that distinguishes zero and minus zero,
+   * and that considers NaN values as equal.
+   */
+  bool operator ==(Object other);
+
+  /**
+   * Returns a hash code for a numerical value.
+   *
+   * The hash code is compatible with equality. It returns the same value
+   * for an [int] and a [double] with the same numerical value, and therefore
+   * the same value for the doubles zero and minus zero.
+   *
+   * No guarantees are made about the hash code of NaN values.
+   */
+  int get hashCode;
+
+  /**
+   * Compares this to `other`.
+   *
+   * Returns a negative number if `this` is less than `other`, zero if they are
+   * equal, and a positive number if `this` is greater than `other`.
+   *
+   * The ordering represented by this method is a total ordering of [num]
+   * values. All distinct doubles are non-equal, as are all distinct integers,
+   * but integers are equal to doubles if they have the same numerical
+   * value.
+   *
+   * For doubles, the `compareTo` operation is different from the partial
+   * ordering given by [operator==], [operator<] and [operator>]. For example,
+   * IEEE doubles impose that `0.0 == -0.0` and all comparison operations on
+   * NaN return false.
+   *
+   * This function imposes a complete ordering for doubles. When using
+   * `compareTo` the following properties hold:
+   *
+   * - All NaN values are considered equal, and greater than any numeric value.
+   * - -0.0 is less than 0.0 (and the integer 0), but greater than any non-zero
+   *    negative value.
+   * - Negative infinity is less than all other values and positive infinity is
+   *   greater than all non-NaN values.
+   * - All other values are compared using their numeric value.
+   *
+   * Examples:
+   * ```
+   * print(1.compareTo(2)); // => -1
+   * print(2.compareTo(1)); // => 1
+   * print(1.compareTo(1)); // => 0
+   *
+   * // The following comparisons yield different results than the
+   * // corresponding comparison operators.
+   * print((-0.0).compareTo(0.0));  // => -1
+   * print(double.nan.compareTo(double.nan));  // => 0
+   * print(double.infinity.compareTo(double.nan)); // => -1
+   *
+   * // -0.0, and NaN comparison operators have rules imposed by the IEEE
+   * // standard.
+   * print(-0.0 == 0.0); // => true
+   * print(double.nan == double.nan);  // => false
+   * print(double.infinity < double.nan);  // => false
+   * print(double.nan < double.infinity);  // => false
+   * print(double.nan == double.infinity);  // => false
+   * ```
+   */
+  int compareTo(num other);
+
+  /** Addition operator. */
+  num operator +(num other);
+
+  /** Subtraction operator. */
+  num operator -(num other);
+
+  /** Multiplication operator. */
+  num operator *(num other);
+
+  /**
+   * Euclidean modulo operator.
+   *
+   * Returns the remainder of the Euclidean division. The Euclidean division of
+   * two integers `a` and `b` yields two integers `q` and `r` such that
+   * `a == b * q + r` and `0 <= r < b.abs()`.
+   *
+   * The Euclidean division is only defined for integers, but can be easily
+   * extended to work with doubles. In that case `r` may have a non-integer
+   * value, but it still verifies `0 <= r < |b|`.
+   *
+   * The sign of the returned value `r` is always positive.
+   *
+   * See [remainder] for the remainder of the truncating division.
+   */
+  num operator %(num other);
+
+  /** Division operator. */
+  double operator /(num other);
+
+  /**
+   * Truncating division operator.
+   *
+   * If either operand is a [double] then the result of the truncating division
+   * `a ~/ b` is equivalent to `(a / b).truncate().toInt()`.
+   *
+   * If both operands are [int]s then `a ~/ b` performs the truncating
+   * integer division.
+   */
+  int operator ~/(num other);
+
+  /** Negate operator. */
+  num operator -();
+
+  /**
+   * Returns the remainder of the truncating division of `this` by [other].
+   *
+   * The result `r` of this operation satisfies:
+   * `this == (this ~/ other) * other + r`.
+   * As a consequence the remainder `r` has the same sign as the divider `this`.
+   */
+  num remainder(num other);
+
+  /** Relational less than operator. */
+  bool operator <(num other);
+
+  /** Relational less than or equal operator. */
+  bool operator <=(num other);
+
+  /** Relational greater than operator. */
+  bool operator >(num other);
+
+  /** Relational greater than or equal operator. */
+  bool operator >=(num other);
+
+  /** True if the number is the double Not-a-Number value; otherwise, false. */
+  bool get isNaN;
+
+  /**
+   * True if the number is negative; otherwise, false.
+   *
+   * Negative numbers are those less than zero, and the double `-0.0`.
+   */
+  bool get isNegative;
+
+  /**
+   * True if the number is positive infinity or negative infinity; otherwise,
+   * false.
+   */
+  bool get isInfinite;
+
+  /**
+   * True if the number is finite; otherwise, false.
+   *
+   * The only non-finite numbers are NaN, positive infinity, and
+   * negative infinity.
+   */
+  bool get isFinite;
+
+  /** Returns the absolute value of this [num]. */
+  num abs();
+
+  /**
+   * Returns minus one, zero or plus one depending on the sign and
+   * numerical value of the number.
+   *
+   * Returns minus one if the number is less than zero,
+   * plus one if the number is greater than zero,
+   * and zero if the number is equal to zero.
+   *
+   * Returns NaN if the number is the double NaN value.
+   *
+   * Returns a number of the same type as this number.
+   * For doubles, `-0.0.sign == -0.0`.
+
+   * The result satisfies:
+   *
+   *     n == n.sign * n.abs()
+   *
+   * for all numbers `n` (except NaN, because NaN isn't `==` to itself).
+   */
+  num get sign;
+
+  /**
+   * Returns the integer closest to `this`.
+   *
+   * Rounds away from zero when there is no closest integer:
+   *  `(3.5).round() == 4` and `(-3.5).round() == -4`.
+   *
+   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
+   */
+  int round();
+
+  /**
+   * Returns the greatest integer no greater than `this`.
+   *
+   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
+   */
+  int floor();
+
+  /**
+   * Returns the least integer no smaller than `this`.
+   *
+   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
+   */
+  int ceil();
+
+  /**
+   * Returns the integer obtained by discarding any fractional
+   * digits from `this`.
+   *
+   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
+   */
+  int truncate();
+
+  /**
+   * Returns the double integer value closest to `this`.
+   *
+   * Rounds away from zero when there is no closest integer:
+   *  `(3.5).roundToDouble() == 4` and `(-3.5).roundToDouble() == -4`.
+   *
+   * If this is already an integer valued double, including `-0.0`, or it is a
+   * non-finite double value, the value is returned unmodified.
+   *
+   * For the purpose of rounding, `-0.0` is considered to be below `0.0`,
+   * and `-0.0` is therefore considered closer to negative numbers than `0.0`.
+   * This means that for a value, `d` in the range `-0.5 < d < 0.0`,
+   * the result is `-0.0`.
+   *
+   * The result is always a double.
+   * If this is a numerically large integer, the result may be an infinite
+   * double.
+   */
+  double roundToDouble();
+
+  /**
+   * Returns the greatest double integer value no greater than `this`.
+   *
+   * If this is already an integer valued double, including `-0.0`, or it is a
+   * non-finite double value, the value is returned unmodified.
+   *
+   * For the purpose of rounding, `-0.0` is considered to be below `0.0`.
+   * A number `d` in the range `0.0 < d < 1.0` will return `0.0`.
+   *
+   * The result is always a double.
+   * If this is a numerically large integer, the result may be an infinite
+   * double.
+   */
+  double floorToDouble();
+
+  /**
+   * Returns the least double integer value no smaller than `this`.
+   *
+   * If this is already an integer valued double, including `-0.0`, or it is a
+   * non-finite double value, the value is returned unmodified.
+   *
+   * For the purpose of rounding, `-0.0` is considered to be below `0.0`.
+   * A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`.
+   *
+   * The result is always a double.
+   * If this is a numerically large integer, the result may be an infinite
+   * double.
+   */
+  double ceilToDouble();
+
+  /**
+   * Returns the double integer value obtained by discarding any fractional
+   * digits from the double value of `this`.
+   *
+   * If this is already an integer valued double, including `-0.0`, or it is a
+   * non-finite double value, the value is returned unmodified.
+   *
+   * For the purpose of rounding, `-0.0` is considered to be below `0.0`.
+   * A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`, and
+   * in the range `0.0 < d < 1.0` it will return 0.0.
+   *
+   * The result is always a double.
+   * If this is a numerically large integer, the result may be an infinite
+   * double.
+   */
+  double truncateToDouble();
+
+  /**
+   * Returns this [num] clamped to be in the range [lowerLimit]-[upperLimit].
+   *
+   * The comparison is done using [compareTo] and therefore takes `-0.0` into
+   * account. This also implies that [double.nan] is treated as the maximal
+   * double value.
+   *
+   * The arguments [lowerLimit] and [upperLimit] must form a valid range where
+   * `lowerLimit.compareTo(upperLimit) <= 0`.
+   */
+  num clamp(num lowerLimit, num upperLimit);
+
+  /** Truncates this [num] to an integer and returns the result as an [int]. */
+  int toInt();
+
+  /**
+   * Return this [num] as a [double].
+   *
+   * If the number is not representable as a [double], an
+   * approximation is returned. For numerically large integers, the
+   * approximation may be infinite.
+   */
+  double toDouble();
+
+  /**
+   * Returns a decimal-point string-representation of `this`.
+   *
+   * Converts `this` to a [double] before computing the string representation.
+   *
+   * If the absolute value of `this` is greater or equal to `10^21` then this
+   * methods returns an exponential representation computed by
+   * `this.toStringAsExponential()`. Otherwise the result
+   * is the closest string representation with exactly [fractionDigits] digits
+   * after the decimal point. If [fractionDigits] equals 0 then the decimal
+   * point is omitted.
+   *
+   * The parameter [fractionDigits] must be an integer satisfying:
+   * `0 <= fractionDigits <= 20`.
+   *
+   * Examples:
+   *
+   *     1.toStringAsFixed(3);  // 1.000
+   *     (4321.12345678).toStringAsFixed(3);  // 4321.123
+   *     (4321.12345678).toStringAsFixed(5);  // 4321.12346
+   *     123456789012345678901.toStringAsFixed(3);  // 123456789012345683968.000
+   *     1000000000000000000000.toStringAsFixed(3); // 1e+21
+   *     5.25.toStringAsFixed(0); // 5
+   */
+  String toStringAsFixed(int fractionDigits);
+
+  /**
+   * Returns an exponential string-representation of `this`.
+   *
+   * Converts `this` to a [double] before computing the string representation.
+   *
+   * If [fractionDigits] is given then it must be an integer satisfying:
+   * `0 <= fractionDigits <= 20`. In this case the string contains exactly
+   * [fractionDigits] after the decimal point. Otherwise, without the parameter,
+   * the returned string uses the shortest number of digits that accurately
+   * represent [this].
+   *
+   * If [fractionDigits] equals 0 then the decimal point is omitted.
+   * Examples:
+   *
+   *     1.toStringAsExponential();       // 1e+0
+   *     1.toStringAsExponential(3);      // 1.000e+0
+   *     123456.toStringAsExponential();  // 1.23456e+5
+   *     123456.toStringAsExponential(3); // 1.235e+5
+   *     123.toStringAsExponential(0);    // 1e+2
+   */
+  String toStringAsExponential([int fractionDigits]);
+
+  /**
+   * Converts `this` to a double and returns a string representation with
+   * exactly [precision] significant digits.
+   *
+   * The parameter [precision] must be an integer satisfying:
+   * `1 <= precision <= 21`.
+   *
+   * Examples:
+   *
+   *     1.toStringAsPrecision(2);       // 1.0
+   *     1e15.toStringAsPrecision(3);    // 1.00e+15
+   *     1234567.toStringAsPrecision(3); // 1.23e+6
+   *     1234567.toStringAsPrecision(9); // 1234567.00
+   *     12345678901234567890.toStringAsPrecision(20); // 12345678901234567168
+   *     12345678901234567890.toStringAsPrecision(14); // 1.2345678901235e+19
+   *     0.00000012345.toStringAsPrecision(15); // 1.23450000000000e-7
+   *     0.0000012345.toStringAsPrecision(15);  // 0.00000123450000000000
+   */
+  String toStringAsPrecision(int precision);
+
+  /**
+   * Returns the shortest string that correctly represent the input number.
+   *
+   * All [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.negativeInfinity].
+   *
+   * An [int] is converted to a decimal representation with no decimal point.
+   *
+   * 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"
+   *     1.234e5.toString();   // 123400
+   *     1234.5e6.toString();  // 1234500000
+   *     12.345e67.toString(); // 1.2345e+68
+   *
+   * 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 uniquely identifying) `"9e59"`.
+   *
+   */
+  String toString();
+
+  /**
+   * Parses a string containing a number literal into a number.
+   *
+   * The method first tries to read the [input] as integer (similar to
+   * [int.parse] without a radix).
+   * If that fails, it tries to parse the [input] as a double (similar to
+   * [double.parse]).
+   * If that fails, too, it invokes [onError] with [input], and the result
+   * of that invocation becomes the result of calling `parse`.
+   *
+   * If no [onError] is supplied, it defaults to a function that throws a
+   * [FormatException].
+   *
+   * For any number `n`, this function satisfies
+   * `identical(n, num.parse(n.toString()))` (except when `n` is a NaN `double`
+   * with a payload).
+   *
+   * The [onError] parameter is deprecated and will be removed.
+   * Instead of `num.parse(string, (string) { ... })`,
+   * you should use `num.tryParse(string) ?? (...)`.
+   */
+  static num parse(String input, [@deprecated num onError(String input)]) {
+    num result = tryParse(input);
+    if (result != null) return result;
+    if (onError == null) throw FormatException(input);
+    return onError(input);
+  }
+
+  /**
+   * Parses a string containing a number literal into a number.
+   *
+   * Like [parse] except that this function returns `null` for invalid inputs
+   * instead of throwing.
+   */
+  static num tryParse(String input) {
+    String source = input.trim();
+    // TODO(lrn): Optimize to detect format and result type in one check.
+    return int.tryParse(source) ?? double.tryParse(source);
+  }
+
+  /** Helper functions for [parse]. */
+  static int _returnIntNull(String _) => null;
+  static double _returnDoubleNull(String _) => null;
+}
diff --git a/sdk_nnbd/lib/core/object.dart b/sdk_nnbd/lib/core/object.dart
new file mode 100644
index 0000000..505efdf
--- /dev/null
+++ b/sdk_nnbd/lib/core/object.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 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 dart.core;
+
+/**
+ * The base class for all Dart objects.
+ *
+ * Because Object is the root of the Dart class hierarchy,
+ * every other Dart class is a subclass of Object.
+ *
+ * When you define a class, you should override [toString]
+ * to return a string describing an instance of that class.
+ * You might also need to define [hashCode] and [operator ==], as described in the
+ * [Implementing map
+ * keys](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#implementing-map-keys)
+ * section of the [library
+ * tour](http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html).
+ */
+@pragma("vm:entry-point")
+class Object {
+  /**
+   * Creates a new [Object] instance.
+   *
+   * [Object] instances have no meaningful state, and are only useful
+   * through their identity. An [Object] instance is equal to itself
+   * only.
+   */
+  const Object();
+
+  /**
+   * The equality operator.
+   *
+   * The default behavior for all [Object]s is to return true if and
+   * only if `this` and [other] are the same object.
+   *
+   * Override this method to specify a different equality relation on
+   * a class. The overriding method must still be an equivalence relation.
+   * That is, it must be:
+   *
+   *  * Total: It must return a boolean for all arguments. It should never throw
+   *    or return `null`.
+   *
+   *  * Reflexive: For all objects `o`, `o == o` must be true.
+   *
+   *  * Symmetric: For all objects `o1` and `o2`, `o1 == o2` and `o2 == o1` must
+   *    either both be true, or both be false.
+   *
+   *  * Transitive: For all objects `o1`, `o2`, and `o3`, if `o1 == o2` and
+   *    `o2 == o3` are true, then `o1 == o3` must be true.
+   *
+   * The method should also be consistent over time,
+   * so whether two objects are equal should only change
+   * if at least one of the objects was modified.
+   *
+   * If a subclass overrides the equality operator it should override
+   * the [hashCode] method as well to maintain consistency.
+   */
+  external bool operator ==(other);
+
+  /**
+   * The hash code for this object.
+   *
+   * A hash code is a single integer which represents the state of the object
+   * that affects [operator ==] comparisons.
+   *
+   * All objects have hash codes.
+   * The default hash code represents only the identity of the object,
+   * the same way as the default [operator ==] implementation only considers objects
+   * equal if they are identical (see [identityHashCode]).
+   *
+   * If [operator ==] is overridden to use the object state instead,
+   * the hash code must also be changed to represent that state.
+   *
+   * Hash codes must be the same for objects that are equal to each other
+   * according to [operator ==].
+   * The hash code of an object should only change if the object changes
+   * in a way that affects equality.
+   * There are no further requirements for the hash codes.
+   * They need not be consistent between executions of the same program
+   * and there are no distribution guarantees.
+   *
+   * Objects that are not equal are allowed to have the same hash code,
+   * it is even technically allowed that all instances have the same hash code,
+   * but if clashes happen too often, it may reduce the efficiency of hash-based
+   * data structures like [HashSet] or [HashMap].
+   *
+   * If a subclass overrides [hashCode], it should override the
+   * [operator ==] operator as well to maintain consistency.
+   */
+  external int get hashCode;
+
+  /**
+   * Returns a string representation of this object.
+   */
+  external String toString();
+
+  /**
+   * Invoked when a non-existent method or property is accessed.
+   *
+   * Classes can override [noSuchMethod] to provide custom behavior.
+   *
+   * If a value is returned, it becomes the result of the original invocation.
+   *
+   * The default behavior is to throw a [NoSuchMethodError].
+   */
+  @pragma("vm:entry-point")
+  external dynamic noSuchMethod(Invocation invocation);
+
+  /**
+   * A representation of the runtime type of the object.
+   */
+  external Type get runtimeType;
+}
diff --git a/sdk_nnbd/lib/core/pattern.dart b/sdk_nnbd/lib/core/pattern.dart
new file mode 100644
index 0000000..6749340
--- /dev/null
+++ b/sdk_nnbd/lib/core/pattern.dart
@@ -0,0 +1,131 @@
+// 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.
+
+part of dart.core;
+
+/**
+ * An interface for basic searches within strings.
+ */
+abstract class Pattern {
+  // NOTE: When using "start" index from the language library, call
+  // without an argument if start is zero. This allows backwards compatibility
+  // with implementations of the older interface that didn't have the start
+  // index argument.
+  /**
+   * Match this pattern against the string repeatedly.
+   *
+   * If [start] is provided, matching will start at that index.
+   *
+   * The returned iterable lazily computes all the non-overlapping matches
+   * of the pattern on the string, ordered by start index.
+   * If a user only requests the first
+   * match, this function should not compute all possible matches.
+   *
+   * The matches are found by repeatedly finding the first match
+   * of the pattern on the string, starting from the end of the previous
+   * match, and initially starting from index zero.
+   *
+   * If the pattern matches the empty string at some point, the next
+   * match is found by starting at the previous match's end plus one.
+   */
+  Iterable<Match> allMatches(String string, [int start = 0]);
+
+  /**
+   * Match this pattern against the start of `string`.
+   *
+   * If [start] is provided, it must be an integer in the range `0` ..
+   * `string.length`. In that case, this patten is tested against the
+   * string at the [start] position. That is, a [Match] is returned if the
+   * pattern can match a part of the string starting from position [start].
+   * Returns `null` if the pattern doesn't match.
+   */
+  Match matchAsPrefix(String string, [int start = 0]);
+}
+
+/**
+ * A result from searching within a string.
+ *
+ * A Match or an [Iterable] of Match objects is returned from [Pattern]
+ * matching methods.
+ *
+ * The following example finds all matches of a [RegExp] in a [String]
+ * and iterates through the returned iterable of Match objects.
+ *
+ *     RegExp exp = new RegExp(r"(\w+)");
+ *     String str = "Parse my string";
+ *     Iterable<Match> matches = exp.allMatches(str);
+ *     for (Match m in matches) {
+ *       String match = m.group(0);
+ *       print(match);
+ *     }
+ *
+ * The output of the example is:
+ *
+ *     Parse
+ *     my
+ *     string
+ *
+ * Some patterns, regular expressions in particular, may record substrings
+ * that were part of the matching. These are called _groups_ in the Match
+ * object. Some patterns may never have any groups, and their matches always
+ * have zero [groupCount].
+ */
+abstract class Match {
+  /**
+   * Returns the index in the string where the match starts.
+   */
+  int get start;
+
+  /**
+   * Returns the index in the string after the last character of the
+   * match.
+   */
+  int get end;
+
+  /**
+   * Returns the string matched by the given [group].
+   *
+   * If [group] is 0, returns the match of the pattern.
+   *
+   * The result may be `null` if the pattern didn't assign a value to it
+   * as part of this match.
+   */
+  String group(int group);
+
+  /**
+   * Returns the string matched by the given [group].
+   *
+   * If [group] is 0, returns the match of the pattern.
+   *
+   * Short alias for [Match.group].
+   */
+  String operator [](int group);
+
+  /**
+   * Returns a list of the groups with the given indices.
+   *
+   * The list contains the strings returned by [group] for each index in
+   * [groupIndices].
+   */
+  List<String> groups(List<int> groupIndices);
+
+  /**
+   * Returns the number of captured groups in the match.
+   *
+   * Some patterns may capture parts of the input that was used to
+   * compute the full match. This is the number of captured groups,
+   * which is also the maximal allowed argument to the [group] method.
+   */
+  int get groupCount;
+
+  /**
+   * The string on which this match was computed.
+   */
+  String get input;
+
+  /**
+   * The pattern used to search in [input].
+   */
+  Pattern get pattern;
+}
diff --git a/sdk_nnbd/lib/core/print.dart b/sdk_nnbd/lib/core/print.dart
new file mode 100644
index 0000000..42c7d1c
--- /dev/null
+++ b/sdk_nnbd/lib/core/print.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 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 dart.core;
+
+/// Prints a string representation of the object to the console.
+void print(Object object) {
+  String line = "$object";
+  if (printToZone == null) {
+    printToConsole(line);
+  } else {
+    printToZone(line);
+  }
+}
diff --git a/sdk_nnbd/lib/core/regexp.dart b/sdk_nnbd/lib/core/regexp.dart
new file mode 100644
index 0000000..b3046cc
--- /dev/null
+++ b/sdk_nnbd/lib/core/regexp.dart
@@ -0,0 +1,189 @@
+// Copyright (c) 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 dart.core;
+
+/**
+ * A regular expression pattern.
+ *
+ * Regular expressions are [Pattern]s, and can as such be used to match strings
+ * or parts of strings.
+ *
+ * Dart regular expressions have the same syntax and semantics as
+ * JavaScript regular expressions. See
+ * <https://ecma-international.org/ecma-262/9.0/#sec-regexp-regular-expression-objects>
+ * for the specification of JavaScript regular expressions.
+ *
+ * [firstMatch] is the main implementation method that applies a regular
+ * expression to a string and returns the first [RegExpMatch]. All
+ * other methods in [RegExp] can build on it.
+ *
+ * Use [allMatches] to look for all matches of a regular expression in
+ * a string.
+ *
+ * The following example finds all matches of a regular expression in
+ * a string.
+ * ```dart
+ * RegExp exp = new RegExp(r"(\w+)");
+ * String str = "Parse my string";
+ * Iterable<RegExpMatch> matches = exp.allMatches(str);
+ * ```
+ *
+ * Note the use of a _raw string_ (a string prefixed with `r`)
+ * in the example above. Use a raw string to treat each character in a string
+ * as a literal character.
+ */
+abstract class RegExp implements Pattern {
+  /**
+   * Constructs a regular expression.
+   *
+   * Throws a [FormatException] if [source] is not valid regular
+   * expression syntax.
+   *
+   * If `multiLine` is enabled, then `^` and `$` will match the beginning and
+   * end of a _line_, in addition to matching beginning and end of input,
+   * respectively.
+   *
+   * If `caseSensitive` is disabled, then case is ignored.
+   *
+   * If `unicode` is enabled, then the pattern is treated as a Unicode
+   * pattern as described by the ECMAScript standard.
+   *
+   * If `dotAll` is enabled, then the `.` pattern will match _all_ characters,
+   * including line terminators.
+   *
+   * Example:
+   *
+   * ```dart
+   * var wordPattern = RegExp(r"(\w+)");
+   * var bracketedNumberValue = RegExp("$key: \\[\\d+\\]");
+   * ```
+   *
+   * Notice the use of a _raw string_ in the first example, and a regular
+   * string in the second. Because of the many character classes used in
+   * regular expressions, it is common to use a raw string here, unless string
+   * interpolation is required.
+   */
+  external factory RegExp(String source,
+      {bool multiLine = false,
+      bool caseSensitive = true,
+      @Since("2.4") bool unicode = false,
+      @Since("2.4") bool dotAll = false});
+
+  /**
+   * Returns a regular expression that matches [text].
+   *
+   * If [text] contains characters that are meaningful in regular expressions,
+   * the resulting regular expression will match those characters literally.
+   * If [text] contains no characters that have special meaning in a regular
+   * expression, it is returned unmodified.
+   *
+   * The characters that have special meaning in regular expressions are:
+   * `(`, `)`, `[`, `]`, `{`, `}`, `*`, `+`, `?`, `.`, `^`, `$`, `|` and `\`.
+   */
+  external static String escape(String text);
+
+  /**
+   * Searches for the first match of the regular expression
+   * in the string [input]. Returns `null` if there is no match.
+   */
+  RegExpMatch firstMatch(String input);
+
+  /**
+   * Returns an iterable of the matches of the regular expression on [input].
+   *
+   * If [start] is provided, only start looking for matches at `start`.
+   */
+  Iterable<RegExpMatch> allMatches(String input, [int start = 0]);
+
+  /**
+   * Returns whether the regular expression has a match in the string [input].
+   */
+  bool hasMatch(String input);
+
+  /**
+   * Returns the first substring match of this regular expression in [input].
+   */
+  String stringMatch(String input);
+
+  /**
+   * The source regular expression string used to create this `RegExp`.
+   */
+  String get pattern;
+
+  /**
+   * Whether this regular expression matches multiple lines.
+   *
+   * If the regexp does match multiple lines, the "^" and "$" characters
+   * match the beginning and end of lines. If not, the character match the
+   * beginning and end of the input.
+   */
+  bool get isMultiLine;
+
+  /**
+   * Whether this regular expression is case sensitive.
+   *
+   * If the regular expression is not case sensitive, it will match an input
+   * letter with a pattern letter even if the two letters are different case
+   * versions of the same letter.
+   */
+  bool get isCaseSensitive;
+
+  /**
+   * Whether this regular expression is in Unicode mode.
+   *
+   * In Unicode mode, UTF-16 surrogate pairs in the original string will be
+   * treated as a single code point and will not match separately. Otherwise,
+   * the target string will be treated purely as a sequence of individual code
+   * units and surrogates will not be treated specially.
+   *
+   * In Unicode mode, the syntax of the RegExp pattern is more restricted, but
+   * some pattern features, like Unicode property escapes, are only available in
+   * this mode.
+   */
+  @Since("2.4")
+  bool get isUnicode;
+
+  /**
+   * Whether "." in this regular expression matches line terminators.
+   *
+   * When false, the "." character matches a single character, unless that
+   * character is a line terminator. When true, then the "." character will
+   * match any single character including line terminators.
+   *
+   * This feature is distinct from [isMultiline], as they affect the behavior
+   * of different pattern characters, and so they can be used together or
+   * separately.
+   */
+  @Since("2.4")
+  bool get isDotAll;
+}
+
+/**
+ * A regular expression match.
+ *
+ * Regular expression matches are [Match]es, but also include the ability
+ * to retrieve the names for any named capture groups and to retrieve
+ * matches for named capture groups by name instead of their index.
+ */
+@Since("2.3")
+abstract class RegExpMatch implements Match {
+  /**
+   * The string matched by the group named [name].
+   *
+   * Returns the string matched by the capture group named [name], or
+   * `null` if no string was matched by that capture group as part of
+   * this match.
+   *
+   * The [name] must be the name of a named capture group in the regular
+   * expression creating this match (that is, the name must be in
+   * [groupNames]).
+   */
+  String namedGroup(String name);
+
+  /**
+   * The names of the captured groups in the match.
+   */
+  Iterable<String> get groupNames;
+}
diff --git a/sdk_nnbd/lib/core/set.dart b/sdk_nnbd/lib/core/set.dart
new file mode 100644
index 0000000..e57d974
--- /dev/null
+++ b/sdk_nnbd/lib/core/set.dart
@@ -0,0 +1,264 @@
+// 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.
+
+part of dart.core;
+
+/**
+ * A collection of objects in which each object can occur only once.
+ *
+ * That is, for each object of the element type, the object is either considered
+ * to be in the set, or to _not_ be in the set.
+ *
+ * Set implementations may consider some elements indistinguishable. These
+ * elements are treated as being the same for any operation on the set.
+ *
+ * The default [Set] implementation, [LinkedHashSet], considers objects
+ * indistinguishable if they are equal with regard to
+ * operator [Object.==].
+ *
+ * Iterating over elements of a set may be either unordered
+ * or ordered in some way. Examples:
+ *
+ * * A [HashSet] is unordered, which means that its iteration order is
+ *   unspecified,
+ * * [LinkedHashSet] iterates in the insertion order of its elements, and
+ * * a sorted set like [SplayTreeSet] iterates the elements in sorted order.
+ *
+ * It is generally not allowed to modify the set (add or remove elements) while
+ * an operation on the set is being performed, for example during a call to
+ * [forEach] or [containsAll]. Nor is it allowed to modify the set while
+ * iterating either the set itself or any [Iterable] that is backed by the set,
+ * such as the ones returned by methods like [where] and [map].
+ *
+ * It is generally not allowed to modify the equality of elements (and thus not
+ * their hashcode) while they are in the set. Some specialized subtypes may be
+ * more permissive, in which case they should document this behavior.
+ */
+abstract class Set<E> extends EfficientLengthIterable<E> {
+  /**
+   * Creates an empty [Set].
+   *
+   * The created [Set] is a plain [LinkedHashSet].
+   * As such, it considers elements that are equal (using [operator ==]) to be
+   * indistinguishable, and requires them to have a compatible
+   * [Object.hashCode] implementation.
+   *
+   * The set is equivalent to one created by `new LinkedHashSet<E>()`.
+   */
+  factory Set() = LinkedHashSet<E>;
+
+  /**
+   * Creates an empty identity [Set].
+   *
+   * The created [Set] is a [LinkedHashSet] that uses identity as equality
+   * relation.
+   *
+   * The set is equivalent to one created by `new LinkedHashSet<E>.identity()`.
+   */
+  factory Set.identity() = LinkedHashSet<E>.identity;
+
+  /**
+   * Creates a [Set] that contains all [elements].
+   *
+   * All the [elements] should be instances of [E].
+   * The `elements` iterable itself can have any type,
+   * so this constructor can be used to down-cast a `Set`, for example as:
+   *
+   *     Set<SuperType> superSet = ...;
+   *     Set<SubType> subSet =
+   *         new Set<SubType>.from(superSet.where((e) => e is SubType));
+   *
+   * The created [Set] is a [LinkedHashSet]. As such, it considers elements that
+   * are equal (using [operator ==]) to be indistinguishable, and requires them to
+   * have a compatible [Object.hashCode] implementation.
+   *
+   * The set is equivalent to one created by
+   * `new LinkedHashSet<E>.from(elements)`.
+   */
+  factory Set.from(Iterable elements) = LinkedHashSet<E>.from;
+
+  /**
+   * Creates a [Set] from [elements].
+   *
+   * The created [Set] is a [LinkedHashSet]. As such, it considers elements that
+   * are equal (using [operator ==]) to be indistinguishable, and requires them to
+   * have a compatible [Object.hashCode] implementation.
+   *
+   * The set is equivalent to one created by
+   * `new LinkedHashSet<E>.of(elements)`.
+   */
+  factory Set.of(Iterable<E> elements) = LinkedHashSet<E>.of;
+
+  /**
+   * Adapts [source] to be a `Set<T>`.
+   *
+   * If [newSet] is provided, it is used to create the new sets returned
+   * by [toSet], [union], and is also used for [intersection] and [difference].
+   * If [newSet] is omitted, it defaults to creating a new set using the
+   * default [Set] constructor, and [intersection] and [difference]
+   * returns an adapted version of calling the same method on the source.
+   *
+   * Any time the set would produce an element that is not a [T],
+   * the element access will throw.
+   *
+   * Any time a [T] value is attempted added into the adapted set,
+   * the store will throw unless the value is also an instance of [S].
+   *
+   * If all accessed elements of [source] are actually instances of [T],
+   * and if all elements added to the returned set are actually instance
+   * of [S],
+   * then the returned set can be used as a `Set<T>`.
+   */
+  static Set<T> castFrom<S, T>(Set<S> source, {Set<R> Function<R>() newSet}) =>
+      CastSet<S, T>(source, newSet);
+
+  /**
+   * Provides a view of this set as a set of [R] instances.
+   *
+   * If this set contains only instances of [R], all read operations
+   * will work correctly. If any operation tries to access an element
+   * that is not an instance of [R], the access will throw instead.
+   *
+   * Elements added to the set (e.g., by using [add] or [addAll])
+   * must be instance of [R] to be valid arguments to the adding function,
+   * and they must be instances of [E] as well to be accepted by
+   * this set as well.
+   */
+  Set<R> cast<R>();
+  /**
+   * Provides an iterator that iterates over the elements of this set.
+   *
+   * The order of iteration is defined by the individual `Set` implementation,
+   * but must be consistent between changes to the set.
+   */
+  Iterator<E> get iterator;
+
+  /**
+   * Returns true if [value] is in the set.
+   */
+  bool contains(Object value);
+
+  /**
+   * Adds [value] to the set.
+   *
+   * Returns `true` if [value] (or an equal value) was not yet in the set.
+   * Otherwise returns `false` and the set is not changed.
+   *
+   * Example:
+   *
+   *     var set = new Set();
+   *     var time1 = new DateTime.fromMillisecondsSinceEpoch(0);
+   *     var time2 = new DateTime.fromMillisecondsSinceEpoch(0);
+   *     // time1 and time2 are equal, but not identical.
+   *     Expect.isTrue(time1 == time2);
+   *     Expect.isFalse(identical(time1, time2));
+   *     set.add(time1);  // => true.
+   *     // A value equal to time2 exists already in the set, and the call to
+   *     // add doesn't change the set.
+   *     set.add(time2);  // => false.
+   *     Expect.isTrue(set.length == 1);
+   *     Expect.isTrue(identical(time1, set.first));
+   */
+  bool add(E value);
+
+  /**
+   * Adds all [elements] to this Set.
+   *
+   * Equivalent to adding each element in [elements] using [add],
+   * but some collections may be able to optimize it.
+   */
+  void addAll(Iterable<E> elements);
+
+  /**
+   * Removes [value] from the set. Returns true if [value] was
+   * in the set. Returns false otherwise. The method has no effect
+   * if [value] value was not in the set.
+   */
+  bool remove(Object value);
+
+  /**
+   * If an object equal to [object] is in the set, return it.
+   *
+   * Checks whether [object] is in the set, like [contains], and if so,
+   * returns the object in the set, otherwise returns `null`.
+   *
+   * If the equality relation used by the set is not identity,
+   * then the returned object may not be *identical* to [object].
+   * Some set implementations may not be able to implement this method.
+   * If the [contains] method is computed,
+   * rather than being based on an actual object instance,
+   * then there may not be a specific object instance representing the
+   * set element.
+   */
+  E lookup(Object object);
+
+  /**
+   * Removes each element of [elements] from this set.
+   */
+  void removeAll(Iterable<Object> elements);
+
+  /**
+   * Removes all elements of this set that are not elements in [elements].
+   *
+   * Checks for each element of [elements] whether there is an element in this
+   * set that is equal to it (according to `this.contains`), and if so, the
+   * equal element in this set is retained, and elements that are not equal
+   * to any element in `elements` are removed.
+   */
+  void retainAll(Iterable<Object> elements);
+
+  /**
+   * Removes all elements of this set that satisfy [test].
+   */
+  void removeWhere(bool test(E element));
+
+  /**
+   * Removes all elements of this set that fail to satisfy [test].
+   */
+  void retainWhere(bool test(E element));
+
+  /**
+   * Returns whether this Set contains all the elements of [other].
+   */
+  bool containsAll(Iterable<Object> other);
+
+  /**
+   * Returns a new set which is the intersection between this set and [other].
+   *
+   * That is, the returned set contains all the elements of this [Set] that
+   * are also elements of [other] according to `other.contains`.
+   */
+  Set<E> intersection(Set<Object> other);
+
+  /**
+   * Returns a new set which contains all the elements of this set and [other].
+   *
+   * That is, the returned set contains all the elements of this [Set] and
+   * all the elements of [other].
+   */
+  Set<E> union(Set<E> other);
+
+  /**
+   * Returns a new set with the elements of this that are not in [other].
+   *
+   * That is, the returned set contains all the elements of this [Set] that
+   * are not elements of [other] according to `other.contains`.
+   */
+  Set<E> difference(Set<Object> other);
+
+  /**
+   * Removes all elements in the set.
+   */
+  void clear();
+
+  /* Creates a [Set] with the same elements and behavior as this `Set`.
+   *
+   * The returned set behaves the same as this set
+   * with regard to adding and removing elements.
+   * It initially contains the same elements.
+   * If this set specifies an ordering of the elements,
+   * the returned set will have the same order.
+   */
+  Set<E> toSet();
+}
diff --git a/sdk_nnbd/lib/core/sink.dart b/sdk_nnbd/lib/core/sink.dart
new file mode 100644
index 0000000..c79214b
--- /dev/null
+++ b/sdk_nnbd/lib/core/sink.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.core;
+
+/**
+ * A generic destination for data.
+ *
+ * Multiple data values can be put into a sink, and when no more data is
+ * available, the sink should be closed.
+ *
+ * This is a generic interface that other data receivers can implement.
+ */
+abstract class Sink<T> {
+  /**
+   * Adds [data] to the sink.
+   *
+   * Must not be called after a call to [close].
+   */
+  void add(T data);
+
+  /**
+   * Closes the sink.
+   *
+   * The [add] method must not be called after this method.
+   *
+   * Calling this method more than once is allowed, but does nothing.
+   */
+  void close();
+}
diff --git a/sdk_nnbd/lib/core/stacktrace.dart b/sdk_nnbd/lib/core/stacktrace.dart
new file mode 100644
index 0000000..2eb1493
--- /dev/null
+++ b/sdk_nnbd/lib/core/stacktrace.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.
+
+part of dart.core;
+
+/**
+ * An interface implemented by all stack trace objects.
+ *
+ * A [StackTrace] is intended to convey information to the user about the call
+ * sequence that triggered an exception.
+ *
+ * These objects are created by the runtime, it is not possible to create
+ * them programmatically.
+ */
+abstract class StackTrace {
+  StackTrace(); // In case existing classes extend StackTrace.
+
+  /**
+   * Create a `StackTrace` object from [stackTraceString].
+   *
+   * The created stack trace will have a `toString` method returning
+   * `stackTraceString`.
+   *
+   * The `stackTraceString` can be a string returned by some other
+   * stack trace, or it can be any string at all.
+   * If the string doesn't look like a stack trace, code that interprets
+   * stack traces is likely to fail, so fake stack traces should be used
+   * with care.
+   */
+  factory StackTrace.fromString(String stackTraceString) = _StringStackTrace;
+
+  /**
+   * Returns a representation of the current stack trace.
+   *
+   * This is similar to what can be achieved by doing:
+   *
+   *     try { throw 0; } catch (_, stack) { return stack; }
+   *
+   * The getter achieves this without throwing, except on platforms that
+   * have no other way to get a stack trace.
+   */
+  external static StackTrace get current;
+
+  /**
+   * Returns a [String] representation of the stack trace.
+   *
+   * The string represents the full stack trace starting from
+   * the point where a throw occurred to the top of the current call sequence.
+   *
+   * The exact format of the string representation is not final.
+   */
+  String toString();
+}
+
+class _StringStackTrace implements StackTrace {
+  final String _stackTrace;
+  _StringStackTrace(this._stackTrace);
+  String toString() => _stackTrace;
+}
diff --git a/sdk_nnbd/lib/core/stopwatch.dart b/sdk_nnbd/lib/core/stopwatch.dart
new file mode 100644
index 0000000..45d71ca
--- /dev/null
+++ b/sdk_nnbd/lib/core/stopwatch.dart
@@ -0,0 +1,123 @@
+// 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.
+
+part of dart.core;
+
+/**
+ * A simple stopwatch interface to measure elapsed time.
+ */
+class Stopwatch {
+  /**
+   * Cached frequency of the system in Hz (ticks per second).
+   *
+   * Must be initialized in [_initTicker];
+   */
+  static int _frequency;
+
+  // The _start and _stop fields capture the time when [start] and [stop]
+  // are called respectively.
+  // If _stop is null, the stopwatch is running.
+  int _start = 0;
+  int _stop = 0;
+
+  /**
+   * Creates a [Stopwatch] in stopped state with a zero elapsed count.
+   *
+   * The following example shows how to start a [Stopwatch]
+   * immediately after allocation.
+   * ```
+   * var stopwatch = new Stopwatch()..start();
+   * ```
+   */
+  Stopwatch() {
+    if (_frequency == null) _initTicker();
+  }
+
+  /**
+   * Frequency of the elapsed counter in Hz.
+   */
+  int get frequency => _frequency;
+
+  /**
+   * Starts the [Stopwatch].
+   *
+   * The [elapsed] count is increasing monotonically. If the [Stopwatch] has
+   * been stopped, then calling start again restarts it without resetting the
+   * [elapsed] count.
+   *
+   * If the [Stopwatch] is currently running, then calling start does nothing.
+   */
+  void start() {
+    if (_stop != null) {
+      // (Re)start this stopwatch.
+      // Don't count the time while the stopwatch has been stopped.
+      _start += _now() - _stop;
+      _stop = null;
+    }
+  }
+
+  /**
+   * Stops the [Stopwatch].
+   *
+   * The [elapsedTicks] count stops increasing after this call. If the
+   * [Stopwatch] is currently not running, then calling this method has no
+   * effect.
+   */
+  void stop() {
+    _stop ??= _now();
+  }
+
+  /**
+   * Resets the [elapsed] count to zero.
+   *
+   * This method does not stop or start the [Stopwatch].
+   */
+  void reset() {
+    _start = _stop ?? _now();
+  }
+
+  /**
+   * The elapsed number of clock ticks since calling [start] while the
+   * [Stopwatch] is running.
+   *
+   * This is the elapsed number of clock ticks between calling [start] and
+   * calling [stop].
+   *
+   * Is 0 if the [Stopwatch] has never been started.
+   *
+   * The elapsed number of clock ticks increases by [frequency] every second.
+   */
+  int get elapsedTicks {
+    return (_stop ?? _now()) - _start;
+  }
+
+  /**
+   * The [elapsedTicks] counter converted to a [Duration].
+   */
+  Duration get elapsed {
+    return Duration(microseconds: elapsedMicroseconds);
+  }
+
+  /**
+   * The [elapsedTicks] counter converted to microseconds.
+   */
+  external int get elapsedMicroseconds;
+
+  /**
+   * The [elapsedTicks] counter converted to milliseconds.
+   */
+  external int get elapsedMilliseconds;
+
+  /**
+   * Whether the [Stopwatch] is currently running.
+   */
+  bool get isRunning => _stop == null;
+
+  /**
+   * Initializes the time-measuring system. *Must* initialize the [_frequency]
+   * variable.
+   */
+  external static void _initTicker();
+  external static int _now();
+}
diff --git a/sdk_nnbd/lib/core/string.dart b/sdk_nnbd/lib/core/string.dart
new file mode 100644
index 0000000..c611bd5
--- /dev/null
+++ b/sdk_nnbd/lib/core/string.dart
@@ -0,0 +1,829 @@
+// Copyright (c) 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 dart.core;
+
+/**
+ * A sequence of UTF-16 code units.
+ *
+ * Strings are mainly used to represent text. A character may be represented by
+ * multiple code points, each code point consisting of one or two code
+ * units. For example the Papua New Guinea flag character requires four code
+ * units to represent two code points, but should be treated like a single
+ * character: "🇵🇬". Platforms that do not support the flag character may show
+ * the letters "PG" instead. If the code points are swapped, it instead becomes
+ * the Guadeloupe flag "🇬🇵" ("GP").
+ *
+ * A string can be either single or multiline. Single line strings are
+ * written using matching single or double quotes, and multiline strings are
+ * written using triple quotes. The following are all valid Dart strings:
+ *
+ *     'Single quotes';
+ *     "Double quotes";
+ *     'Double quotes in "single" quotes';
+ *     "Single quotes in 'double' quotes";
+ *
+ *     '''A
+ *     multiline
+ *     string''';
+ *
+ *     """
+ *     Another
+ *     multiline
+ *     string""";
+ *
+ * Strings are immutable. Although you cannot change a string, you can perform
+ * an operation on a string and assign the result to a new string:
+ *
+ *     var string = 'Dart is fun';
+ *     var newString = string.substring(0, 5);
+ *
+ * You can use the plus (`+`) operator to concatenate strings:
+ *
+ *     'Dart ' + 'is ' + 'fun!'; // 'Dart is fun!'
+ *
+ * You can also use adjacent string literals for concatenation:
+ *
+ *     'Dart ' 'is ' 'fun!';    // 'Dart is fun!'
+ *
+ * You can use `${}` to interpolate the value of Dart expressions
+ * within strings. The curly braces can be omitted when evaluating identifiers:
+ *
+ *     string = 'dartlang';
+ *     '$string has ${string.length} letters'; // 'dartlang has 8 letters'
+ *
+ * A string is represented by a sequence of Unicode UTF-16 code units
+ * accessible through the [codeUnitAt] or the [codeUnits] members:
+ *
+ *     string = 'Dart';
+ *     string.codeUnitAt(0); // 68
+ *     string.codeUnits;     // [68, 97, 114, 116]
+ *
+ * The string representation of code units is accessible through the index
+ * operator:
+ *
+ *     string[0];            // 'D'
+ *
+ * The characters of a string are encoded in UTF-16. Decoding UTF-16, which
+ * combines surrogate pairs, yields Unicode code points. Following a similar
+ * terminology to Go, we use the name 'rune' for an integer representing a
+ * Unicode code point. Use the [runes] property to get the runes of a string:
+ *
+ *     string.runes.toList(); // [68, 97, 114, 116]
+ *
+ * For a character outside the Basic Multilingual Plane (plane 0) that is
+ * composed of a surrogate pair, [runes] combines the pair and returns a
+ * single integer.  For example, the Unicode character for a
+ * musical G-clef ('𝄞') with rune value 0x1D11E consists of a UTF-16 surrogate
+ * pair: `0xD834` and `0xDD1E`. Using [codeUnits] returns the surrogate pair,
+ * and using `runes` returns their combined value:
+ *
+ *     var clef = '\u{1D11E}';
+ *     clef.codeUnits;         // [0xD834, 0xDD1E]
+ *     clef.runes.toList();    // [0x1D11E]
+ *
+ * The String class can not be extended or implemented. Attempting to do so
+ * yields a compile-time error.
+ *
+ * ## Other resources
+ *
+ * See [StringBuffer] to efficiently build a string incrementally. See
+ * [RegExp] to work with regular expressions.
+ *
+ * Also see:
+ *
+ * * [Dart Cookbook](https://www.dartlang.org/docs/cookbook/#strings)
+ *   for String examples and recipes.
+ * * [Dart Up and Running](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#strings-and-regular-expressions)
+ */
+abstract class String implements Comparable<String>, Pattern {
+  /**
+   * Allocates a new String for the specified [charCodes].
+   *
+   * The [charCodes] can be UTF-16 code units or runes. If a char-code value is
+   * 16-bit, it is copied verbatim:
+   *
+   *     new String.fromCharCodes([68]); // 'D'
+   *
+   * If a char-code value is greater than 16-bits, it is decomposed into a
+   * surrogate pair:
+   *
+   *     var clef = new String.fromCharCodes([0x1D11E]);
+   *     clef.codeUnitAt(0); // 0xD834
+   *     clef.codeUnitAt(1); // 0xDD1E
+   *
+   * If [start] and [end] is provided, only the values of [charCodes]
+   * at positions from `start` to, but not including, `end`, are used.
+   * The `start` and `end` values must satisfy
+   * `0 <= start <= end <= charCodes.length`.
+   */
+  external factory String.fromCharCodes(Iterable<int> charCodes,
+      [int start = 0, int end]);
+
+  /**
+   * Allocates a new String for the specified [charCode].
+   *
+   * If the [charCode] can be represented by a single UTF-16 code unit, the new
+   * string contains a single code unit. Otherwise, the [length] is 2 and
+   * the code units form a surrogate pair. See documentation for
+   * [fromCharCodes].
+   *
+   * Creating a String with half of a surrogate pair is allowed.
+   */
+  external factory String.fromCharCode(int charCode);
+
+  /**
+   * Returns the string value of the environment declaration [name].
+   *
+   * Environment declarations are provided by the surrounding system compiling
+   * or running the Dart program. Declarations map a string key to a string
+   * value.
+   *
+   * If [name] is not declared in the environment, the result is instead
+   * [defaultValue].
+   *
+   * Example of getting a value:
+   *
+   *     const String.fromEnvironment("defaultFloo", defaultValue: "no floo")
+   *
+   * Example of checking whether a declaration is there at all:
+   *
+   *     var isDeclared = const String.fromEnvironment("maybeDeclared") != null;
+   */
+  // The .fromEnvironment() constructors are special in that we do not want
+  // users to call them using "new". We prohibit that by giving them bodies
+  // that throw, even though const constructors are not allowed to have bodies.
+  // Disable those static errors.
+  //ignore: const_constructor_with_body
+  //ignore: const_factory
+  external const factory String.fromEnvironment(String name,
+      {String defaultValue});
+
+  /**
+   * Gets the character (as a single-code-unit [String]) at the given [index].
+   *
+   * The returned string represents exactly one UTF-16 code unit, which may be
+   * half of a surrogate pair. A single member of a surrogate pair is an
+   * invalid UTF-16 string:
+   *
+   *     var clef = '\u{1D11E}';
+   *     // These represent invalid UTF-16 strings.
+   *     clef[0].codeUnits;      // [0xD834]
+   *     clef[1].codeUnits;      // [0xDD1E]
+   *
+   * This method is equivalent to
+   * `new String.fromCharCode(this.codeUnitAt(index))`.
+   */
+  String operator [](int index);
+
+  /**
+   * Returns the 16-bit UTF-16 code unit at the given [index].
+   */
+  int codeUnitAt(int index);
+
+  /**
+   * The length of the string.
+   *
+   * Returns the number of UTF-16 code units in this string. The number
+   * of [runes] might be fewer, if the string contains characters outside
+   * the Basic Multilingual Plane (plane 0):
+   *
+   *     'Dart'.length;          // 4
+   *     'Dart'.runes.length;    // 4
+   *
+   *     var clef = '\u{1D11E}';
+   *     clef.length;            // 2
+   *     clef.runes.length;      // 1
+   */
+  int get length;
+
+  /**
+   * Returns a hash code derived from the code units of the string.
+   *
+   * This is compatible with [operator ==]. Strings with the same sequence
+   * of code units have the same hash code.
+   */
+  int get hashCode;
+
+  /**
+   * Returns true if other is a `String` with the same sequence of code units.
+   *
+   * This method compares each individual code unit of the strings.
+   * It does not check for Unicode equivalence.
+   * For example, both the following strings represent the string 'Amélie',
+   * but due to their different encoding, are not equal:
+   *
+   *     'Am\xe9lie' == 'Ame\u{301}lie'; // false
+   *
+   * The first string encodes 'é' as a single unicode code unit (also
+   * a single rune), whereas the second string encodes it as 'e' with the
+   * combining accent character '◌́'.
+   */
+  bool operator ==(Object other);
+
+  /**
+   * Compares this string to [other].
+   *
+   * Returns a negative value if `this` is ordered before `other`,
+   * a positive value if `this` is ordered after `other`,
+   * or zero if `this` and `other` are equivalent.
+   *
+   * The ordering is the same as the ordering of the code points at the first
+   * position where the two strings differ.
+   * If one string is a prefix of the other,
+   * then the shorter string is ordered before the longer string.
+   * If the strings have exactly the same content, they are equivalent with
+   * regard to the ordering.
+   * Ordering does not check for Unicode equivalence.
+   * The comparison is case sensitive.
+   */
+  int compareTo(String other);
+
+  /**
+   * Returns true if this string ends with [other]. For example:
+   *
+   *     'Dart'.endsWith('t'); // true
+   */
+  bool endsWith(String other);
+
+  /**
+   * Returns true if this string starts with a match of [pattern].
+   *
+   *     var string = 'Dart';
+   *     string.startsWith('D');                       // true
+   *     string.startsWith(new RegExp(r'[A-Z][a-z]')); // true
+   *
+   * If [index] is provided, this method checks if the substring starting
+   * at that index starts with a match of [pattern]:
+   *
+   *     string.startsWith('art', 1);                  // true
+   *     string.startsWith(new RegExp(r'\w{3}'));      // true
+   *
+   * [index] must not be negative or greater than [length].
+   *
+   * A [RegExp] containing '^' does 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:
+   *
+   *     string.startsWith(new RegExp(r'^art'), 1);    // false
+   *     string.startsWith(new RegExp(r'art'), 1);     // true
+   */
+  bool startsWith(Pattern pattern, [int index = 0]);
+
+  /**
+   * Returns the position of the first match of [pattern] in this string,
+   * starting at [start], inclusive:
+   *
+   *     var string = 'Dartisans';
+   *     string.indexOf('art');                     // 1
+   *     string.indexOf(new RegExp(r'[A-Z][a-z]')); // 0
+   *
+   * Returns -1 if no match is found:
+   *
+   *     string.indexOf(new RegExp(r'dart'));       // -1
+   *
+   * [start] must be non-negative and not greater than [length].
+   */
+  int indexOf(Pattern pattern, [int start]);
+
+  /**
+   * Returns the position of the last match [pattern] in this string, searching
+   * backward starting at [start], inclusive:
+   *
+   *     var string = 'Dartisans';
+   *     string.lastIndexOf('a');                    // 6
+   *     string.lastIndexOf(new RegExp(r'a(r|n)'));  // 6
+   *
+   * Returns -1 if [pattern] could not be found in this string.
+   *
+   *     string.lastIndexOf(new RegExp(r'DART'));    // -1
+   *
+   * The [start] must be non-negative and not greater than [length].
+   */
+  int lastIndexOf(Pattern pattern, [int start]);
+
+  /**
+   * Returns true if this string is empty.
+   */
+  bool get isEmpty;
+
+  /**
+   * Returns true if this string is not empty.
+   */
+  bool get isNotEmpty;
+
+  /**
+   * Creates a new string by concatenating this string with [other].
+   *
+   *     'dart' + 'lang'; // 'dartlang'
+   */
+  String operator +(String other);
+
+  /**
+   * Returns the substring of this string that extends from [startIndex],
+   * inclusive, to [endIndex], exclusive.
+   *
+   *     var string = 'dartlang';
+   *     string.substring(1);    // 'artlang'
+   *     string.substring(1, 4); // 'art'
+   */
+  String substring(int startIndex, [int endIndex]);
+
+  /**
+   * Returns the string without any leading and trailing whitespace.
+   *
+   * If the string contains leading or trailing whitespace, a new string with no
+   * leading and no trailing whitespace is returned:
+   * ```dart
+   * '\tDart is fun\n'.trim(); // 'Dart is fun'
+   * ```
+   * Otherwise, the original string itself is returned:
+   * ```dart
+   * var str1 = 'Dart';
+   * var str2 = str1.trim();
+   * identical(str1, str2);    // true
+   * ```
+   * Whitespace is defined by the Unicode White_Space property (as defined in
+   * version 6.2 or later) and the BOM character, 0xFEFF.
+   *
+   * Here is the list of trimmed characters according to Unicode version 6.3:
+   * ```
+   *     0009..000D    ; White_Space # Cc   <control-0009>..<control-000D>
+   *     0020          ; White_Space # Zs   SPACE
+   *     0085          ; White_Space # Cc   <control-0085>
+   *     00A0          ; White_Space # Zs   NO-BREAK SPACE
+   *     1680          ; White_Space # Zs   OGHAM SPACE MARK
+   *     2000..200A    ; White_Space # Zs   EN QUAD..HAIR SPACE
+   *     2028          ; White_Space # Zl   LINE SEPARATOR
+   *     2029          ; White_Space # Zp   PARAGRAPH SEPARATOR
+   *     202F          ; White_Space # Zs   NARROW NO-BREAK SPACE
+   *     205F          ; White_Space # Zs   MEDIUM MATHEMATICAL SPACE
+   *     3000          ; White_Space # Zs   IDEOGRAPHIC SPACE
+   *
+   *     FEFF          ; BOM                ZERO WIDTH NO_BREAK SPACE
+   * ```
+   * Some later versions of Unicode do not include U+0085 as a whitespace
+   * character. Whether it is trimmed depends on the Unicode version
+   * used by the system.
+   */
+  String trim();
+
+  /**
+   * Returns the string without any leading whitespace.
+   *
+   * As [trim], but only removes leading whitespace.
+   */
+  String trimLeft();
+
+  /**
+   * Returns the string without any trailing whitespace.
+   *
+   * As [trim], but only removes trailing whitespace.
+   */
+  String trimRight();
+
+  /**
+   * Creates a new string by concatenating this string with itself a number
+   * of times.
+   *
+   * The result of `str * n` is equivalent to
+   * `str + str + ...`(n times)`... + str`.
+   *
+   * Returns an empty string if [times] is zero or negative.
+   */
+  String operator *(int times);
+
+  /**
+   * Pads this string on the left if it is shorter than [width].
+   *
+   * Return a new string that prepends [padding] onto this string
+   * one time for each position the length is less than [width].
+   *
+   * If [width] is already smaller than or equal to `this.length`,
+   * no padding is added. A negative `width` is treated as zero.
+   *
+   * If [padding] has length different from 1, the result will not
+   * have length `width`. This may be useful for cases where the
+   * padding is a longer string representing a single character, like
+   * `"&nbsp;"` or `"\u{10002}`".
+   * In that case, the user should make sure that `this.length` is
+   * the correct measure of the strings length.
+   */
+  String padLeft(int width, [String padding = ' ']);
+
+  /**
+   * Pads this string on the right if it is shorter than [width].
+   *
+   * Return a new string that appends [padding] after this string
+   * one time for each position the length is less than [width].
+   *
+   * If [width] is already smaller than or equal to `this.length`,
+   * no padding is added. A negative `width` is treated as zero.
+   *
+   * If [padding] has length different from 1, the result will not
+   * have length `width`. This may be useful for cases where the
+   * padding is a longer string representing a single character, like
+   * `"&nbsp;"` or `"\u{10002}`".
+   * In that case, the user should make sure that `this.length` is
+   * the correct measure of the strings length.
+   */
+  String padRight(int width, [String padding = ' ']);
+
+  /**
+   * Returns true if this string contains a match of [other]:
+   *
+   *     var string = 'Dart strings';
+   *     string.contains('D');                     // true
+   *     string.contains(new RegExp(r'[A-Z]'));    // true
+   *
+   * If [startIndex] is provided, this method matches only at or after that
+   * index:
+   *
+   *     string.contains('X', 1);                  // false
+   *     string.contains(new RegExp(r'[A-Z]'), 1); // false
+   *
+   * [startIndex] must not be negative or greater than [length].
+   */
+  bool contains(Pattern other, [int startIndex = 0]);
+
+  /**
+   * Returns a new string in which the first occurrence of [from] in this string
+   * is replaced with [to], starting from [startIndex]:
+   *
+   *     '0.0001'.replaceFirst(new RegExp(r'0'), ''); // '.0001'
+   *     '0.0001'.replaceFirst(new RegExp(r'0'), '7', 1); // '0.7001'
+   */
+  String replaceFirst(Pattern from, String to, [int startIndex = 0]);
+
+  /**
+   * Replace the first occurrence of [from] in this string.
+   *
+   * Returns a new string, which is this string
+   * except that the first match of [from], starting from [startIndex],
+   * is replaced by the result of calling [replace] with the match object.
+   *
+   * The optional [startIndex] is by default set to 0. If provided, it must be
+   * an integer in the range `[0 .. len]`, where `len` is this string's length.
+   */
+  String replaceFirstMapped(Pattern from, String replace(Match match),
+      [int startIndex = 0]);
+
+  /**
+   * Replaces all substrings that match [from] with [replace].
+   *
+   * Returns a new string in which the non-overlapping substrings matching
+   * [from] (the ones iterated by `from.allMatches(thisString)`) are replaced
+   * by the literal string [replace].
+   *
+   *     'resume'.replaceAll(new RegExp(r'e'), 'é'); // 'résumé'
+   *
+   * Notice that the [replace] string is not interpreted. If the replacement
+   * depends on the match (for example on a [RegExp]'s capture groups), use
+   * the [replaceAllMapped] method instead.
+   */
+  String replaceAll(Pattern from, String replace);
+
+  /**
+   * Replace all substrings that match [from] by a string computed from the
+   * match.
+   *
+   * Returns a new string in which the non-overlapping substrings that match
+   * [from] (the ones iterated by `from.allMatches(thisString)`) are replaced
+   * by the result of calling [replace] on the corresponding [Match] object.
+   *
+   * This can be used to replace matches with new content that depends on the
+   * match, unlike [replaceAll] where the replacement string is always the same.
+   *
+   * The [replace] function is called with the [Match] generated
+   * by the pattern, and its result is used as replacement.
+   *
+   * The function defined below converts each word in a string to simplified
+   * 'pig latin' using [replaceAllMapped]:
+   *
+   *     pigLatin(String words) => words.replaceAllMapped(
+   *         new RegExp(r'\b(\w*?)([aeiou]\w*)', caseSensitive: false),
+   *         (Match m) => "${m[2]}${m[1]}${m[1].isEmpty ? 'way' : 'ay'}");
+   *
+   *     pigLatin('I have a secret now!'); // 'Iway avehay away ecretsay ownay!'
+   */
+  String replaceAllMapped(Pattern from, String replace(Match match));
+
+  /**
+   * Replaces the substring from [start] to [end] with [replacement].
+   *
+   * Returns a new string equivalent to:
+   *
+   *     this.substring(0, start) + replacement + this.substring(end)
+   *
+   * The [start] and [end] indices must specify a valid range of this string.
+   * That is `0 <= start <= end <= this.length`.
+   * If [end] is `null`, it defaults to [length].
+   */
+  String replaceRange(int start, int end, String replacement);
+
+  /**
+   * Splits the string at matches of [pattern] and returns a list of substrings.
+   *
+   * Finds all the matches of `pattern` in this string,
+   * and returns the list of the substrings between the matches.
+   *
+   *     var string = "Hello world!";
+   *     string.split(" ");                      // ['Hello', 'world!'];
+   *
+   * Empty matches at the beginning and end of the strings are ignored,
+   * and so are empty matches right after another match.
+   *
+   *     var string = "abba";
+   *     string.split(new RegExp(r"b*"));        // ['a', 'a']
+   *                                             // not ['', 'a', 'a', '']
+   *
+   * If this string is empty, the result is an empty list if `pattern` matches
+   * the empty string, and it is `[""]` if the pattern doesn't match.
+   *
+   *     var string = '';
+   *     string.split('');                       // []
+   *     string.split("a");                      // ['']
+   *
+   * Splitting with an empty pattern splits the string into single-code unit
+   * strings.
+   *
+   *     var string = 'Pub';
+   *     string.split('');                       // ['P', 'u', 'b']
+   *
+   *     string.codeUnits.map((unit) {
+   *       return new String.fromCharCode(unit);
+   *     }).toList();                            // ['P', 'u', 'b']
+   *
+   * Splitting happens at UTF-16 code unit boundaries,
+   * and not at rune boundaries:
+   *
+   *     // String made up of two code units, but one rune.
+   *     string = '\u{1D11E}';
+   *     string.split('').length;                 // 2 surrogate values
+   *
+   * To get a list of strings containing the individual runes of a string,
+   * you should not use split. You can instead map each rune to a string
+   * as follows:
+   *
+   *     string.runes.map((rune) => new String.fromCharCode(rune)).toList();
+   */
+  List<String> split(Pattern pattern);
+
+  /**
+   * Splits the string, converts its parts, and combines them into a new
+   * string.
+   *
+   * [pattern] is used to split the string into parts and separating matches.
+   *
+   * Each match is converted to a string by calling [onMatch]. If [onMatch]
+   * is omitted, the matched string is used.
+   *
+   * Each non-matched part is converted by a call to [onNonMatch]. If
+   * [onNonMatch] is omitted, the non-matching part is used.
+   *
+   * Then all the converted parts are combined into the resulting string.
+   *
+   *     'Eats shoots leaves'.splitMapJoin((new RegExp(r'shoots')),
+   *         onMatch:    (m) => '${m.group(0)}',
+   *         onNonMatch: (n) => '*'); // *shoots*
+   */
+  String splitMapJoin(Pattern pattern,
+      {String onMatch(Match match), String onNonMatch(String nonMatch)});
+
+  /**
+   * Returns an unmodifiable list of the UTF-16 code units of this string.
+   */
+  List<int> get codeUnits;
+
+  /**
+   * Returns an [Iterable] of Unicode code-points of this string.
+   *
+   * If the string contains surrogate pairs, they are combined and returned
+   * as one integer by this iterator. Unmatched surrogate halves are treated
+   * like valid 16-bit code-units.
+   */
+  Runes get runes;
+
+  /**
+   * Converts all characters in this string to lower case.
+   * If the string is already in all lower case, this method returns [:this:].
+   *
+   *     'ALPHABET'.toLowerCase(); // 'alphabet'
+   *     'abc'.toLowerCase();      // 'abc'
+   *
+   * This function uses the language independent Unicode mapping and thus only
+   * works in some languages.
+   */
+  // TODO(floitsch): document better. (See EcmaScript for description).
+  String toLowerCase();
+
+  /**
+   * Converts all characters in this string to upper case.
+   * If the string is already in all upper case, this method returns [:this:].
+   *
+   *     'alphabet'.toUpperCase(); // 'ALPHABET'
+   *     'ABC'.toUpperCase();      // 'ABC'
+   *
+   * This function uses the language independent Unicode mapping and thus only
+   * works in some languages.
+   */
+  // TODO(floitsch): document better. (See EcmaScript for description).
+  String toUpperCase();
+}
+
+/**
+ * The runes (integer Unicode code points) of a [String].
+ */
+class Runes extends Iterable<int> {
+  final String string;
+  Runes(this.string);
+
+  RuneIterator get iterator => RuneIterator(string);
+
+  int get last {
+    if (string.length == 0) {
+      throw StateError('No elements.');
+    }
+    int length = string.length;
+    int code = string.codeUnitAt(length - 1);
+    if (_isTrailSurrogate(code) && string.length > 1) {
+      int previousCode = string.codeUnitAt(length - 2);
+      if (_isLeadSurrogate(previousCode)) {
+        return _combineSurrogatePair(previousCode, code);
+      }
+    }
+    return code;
+  }
+}
+
+// Is then code (a 16-bit unsigned integer) a UTF-16 lead surrogate.
+bool _isLeadSurrogate(int code) => (code & 0xFC00) == 0xD800;
+
+// Is then code (a 16-bit unsigned integer) a UTF-16 trail surrogate.
+bool _isTrailSurrogate(int code) => (code & 0xFC00) == 0xDC00;
+
+// Combine a lead and a trail surrogate value into a single code point.
+int _combineSurrogatePair(int start, int end) {
+  return 0x10000 + ((start & 0x3FF) << 10) + (end & 0x3FF);
+}
+
+/** [Iterator] for reading runes (integer Unicode code points) out of a Dart
+  * string.
+  */
+class RuneIterator implements BidirectionalIterator<int> {
+  /** String being iterated. */
+  final String string;
+  /** Position before the current code point. */
+  int _position;
+  /** Position after the current code point. */
+  int _nextPosition;
+  /**
+   * Current code point.
+   *
+   * If the iterator has hit either end, the [_currentCodePoint] is null
+   * and [: _position == _nextPosition :].
+   */
+  int _currentCodePoint;
+
+  /** Create an iterator positioned at the beginning of the string. */
+  RuneIterator(String string)
+      : this.string = string,
+        _position = 0,
+        _nextPosition = 0;
+
+  /**
+   * Create an iterator positioned before the [index]th code unit of the string.
+   *
+   * When created, there is no [current] value.
+   * A [moveNext] will use the rune starting at [index] the current value,
+   * and a [movePrevious] will use the rune ending just before [index] as the
+   * the current value.
+   *
+   * The [index] position must not be in the middle of a surrogate pair.
+   */
+  RuneIterator.at(String string, int index)
+      : string = string,
+        _position = index,
+        _nextPosition = index {
+    RangeError.checkValueInInterval(index, 0, string.length);
+    _checkSplitSurrogate(index);
+  }
+
+  /** Throw an error if the index is in the middle of a surrogate pair. */
+  void _checkSplitSurrogate(int index) {
+    if (index > 0 &&
+        index < string.length &&
+        _isLeadSurrogate(string.codeUnitAt(index - 1)) &&
+        _isTrailSurrogate(string.codeUnitAt(index))) {
+      throw ArgumentError('Index inside surrogate pair: $index');
+    }
+  }
+
+  /**
+   * Returns the starting position of the current rune in the string.
+   *
+   * Returns null if the [current] rune is null.
+   */
+  int get rawIndex => (_position != _nextPosition) ? _position : null;
+
+  /**
+   * Resets the iterator to the rune at the specified index of the string.
+   *
+   * Setting a negative [rawIndex], or one greater than or equal to
+   * [:string.length:],
+   * is an error. So is setting it in the middle of a surrogate pair.
+   *
+   * Setting the position to the end of then string will set [current] to null.
+   */
+  void set rawIndex(int rawIndex) {
+    RangeError.checkValidIndex(rawIndex, string, "rawIndex");
+    reset(rawIndex);
+    moveNext();
+  }
+
+  /**
+   * Resets the iterator to the given index into the string.
+   *
+   * After this the [current] value is unset.
+   * You must call [moveNext] make the rune at the position current,
+   * or [movePrevious] for the last rune before the position.
+   *
+   * Setting a negative [rawIndex], or one greater than [:string.length:],
+   * is an error. So is setting it in the middle of a surrogate pair.
+   */
+  void reset([int rawIndex = 0]) {
+    RangeError.checkValueInInterval(rawIndex, 0, string.length, "rawIndex");
+    _checkSplitSurrogate(rawIndex);
+    _position = _nextPosition = rawIndex;
+    _currentCodePoint = null;
+  }
+
+  /** The rune (integer Unicode code point) starting at the current position in
+   *  the string.
+   */
+  int get current => _currentCodePoint;
+
+  /**
+   * The number of code units comprising the current rune.
+   *
+   * Returns zero if there is no current rune ([current] is null).
+   */
+  int get currentSize => _nextPosition - _position;
+
+  /**
+   * A string containing the current rune.
+   *
+   * For runes outside the basic multilingual plane, this will be
+   * a String of length 2, containing two code units.
+   *
+   * Returns null if [current] is null.
+   */
+  String get currentAsString {
+    if (_position == _nextPosition) return null;
+    if (_position + 1 == _nextPosition) return string[_position];
+    return string.substring(_position, _nextPosition);
+  }
+
+  bool moveNext() {
+    _position = _nextPosition;
+    if (_position == string.length) {
+      _currentCodePoint = null;
+      return false;
+    }
+    int codeUnit = string.codeUnitAt(_position);
+    int nextPosition = _position + 1;
+    if (_isLeadSurrogate(codeUnit) && nextPosition < string.length) {
+      int nextCodeUnit = string.codeUnitAt(nextPosition);
+      if (_isTrailSurrogate(nextCodeUnit)) {
+        _nextPosition = nextPosition + 1;
+        _currentCodePoint = _combineSurrogatePair(codeUnit, nextCodeUnit);
+        return true;
+      }
+    }
+    _nextPosition = nextPosition;
+    _currentCodePoint = codeUnit;
+    return true;
+  }
+
+  bool movePrevious() {
+    _nextPosition = _position;
+    if (_position == 0) {
+      _currentCodePoint = null;
+      return false;
+    }
+    int position = _position - 1;
+    int codeUnit = string.codeUnitAt(position);
+    if (_isTrailSurrogate(codeUnit) && position > 0) {
+      int prevCodeUnit = string.codeUnitAt(position - 1);
+      if (_isLeadSurrogate(prevCodeUnit)) {
+        _position = position - 1;
+        _currentCodePoint = _combineSurrogatePair(prevCodeUnit, codeUnit);
+        return true;
+      }
+    }
+    _position = position;
+    _currentCodePoint = codeUnit;
+    return true;
+  }
+}
diff --git a/sdk_nnbd/lib/core/string_buffer.dart b/sdk_nnbd/lib/core/string_buffer.dart
new file mode 100644
index 0000000..8fe17f5
--- /dev/null
+++ b/sdk_nnbd/lib/core/string_buffer.dart
@@ -0,0 +1,50 @@
+// 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.
+
+part of dart.core;
+
+/**
+ * A class for concatenating strings efficiently.
+ *
+ * Allows for the incremental building of a string using write*() methods.
+ * The strings are concatenated to a single string only when [toString] is
+ * called.
+ */
+class StringBuffer implements StringSink {
+  /** Creates the string buffer with an initial content. */
+  external StringBuffer([Object content = ""]);
+
+  /**
+   * Returns the length of the content that has been accumulated so far.
+   * This is a constant-time operation.
+   */
+  external int get length;
+
+  /** Returns whether the buffer is empty. This is a constant-time operation. */
+  bool get isEmpty => length == 0;
+
+  /**
+   * Returns whether the buffer is not empty. This is a constant-time
+   * operation.
+   */
+  bool get isNotEmpty => !isEmpty;
+
+  /// Adds the contents of [obj], converted to a string, to the buffer.
+  external void write(Object obj);
+
+  /// Adds the string representation of [charCode] to the buffer.
+  external void writeCharCode(int charCode);
+
+  external void writeAll(Iterable objects, [String separator = ""]);
+
+  external void writeln([Object obj = ""]);
+
+  /**
+   * Clears the string buffer.
+   */
+  external void clear();
+
+  /// Returns the contents of buffer as a concatenated string.
+  external String toString();
+}
diff --git a/sdk_nnbd/lib/core/string_sink.dart b/sdk_nnbd/lib/core/string_sink.dart
new file mode 100644
index 0000000..e7d950c
--- /dev/null
+++ b/sdk_nnbd/lib/core/string_sink.dart
@@ -0,0 +1,31 @@
+// 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 dart.core;
+
+abstract class StringSink {
+  /**
+   * Converts [obj] to a String by invoking [Object.toString] and 
+   * adds the result to `this`.
+   */
+  void write(Object obj);
+
+  /**
+   * Iterates over the given [objects] and [write]s them in sequence.
+   */
+  void writeAll(Iterable objects, [String separator = ""]);
+
+  /**
+   * Converts [obj] to a String by invoking [Object.toString] and 
+   * adds the result to `this`, followed by a newline.
+   */
+  void writeln([Object obj = ""]);
+
+  /**
+   * Writes the [charCode] to `this`.
+   *
+   * This method is equivalent to `write(new String.fromCharCode(charCode))`.
+   */
+  void writeCharCode(int charCode);
+}
diff --git a/sdk_nnbd/lib/core/symbol.dart b/sdk_nnbd/lib/core/symbol.dart
new file mode 100644
index 0000000..a46ec97
--- /dev/null
+++ b/sdk_nnbd/lib/core/symbol.dart
@@ -0,0 +1,97 @@
+// 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 dart.core;
+
+/// Opaque name used by mirrors, invocations and [Function.apply].
+abstract class Symbol {
+  /** The symbol corresponding to the name of the unary minus operator. */
+  static const Symbol unaryMinus = Symbol("unary-");
+
+  /**
+   * The empty symbol.
+   *
+   * The empty symbol is the name of libraries with no library declaration,
+   * and the base-name of the unnamed constructor.
+   */
+  static const Symbol empty = Symbol("");
+
+  /**
+   * Constructs a new [Symbol] representing the provided name.
+   *
+   * The name must be a valid public Dart member name,
+   * public constructor name, or library name, optionally qualified.
+   *
+   * A qualified name is a valid name preceded by a public identifier name
+   * and a '`.`', e.g., `foo.bar.baz=` is a qualified version of `baz=`.
+   * That means that the content of the [name] String must be either
+   *
+   * * a valid public Dart identifier
+   *   (that is, an identifier not starting with "`_`"),
+   * * such an identifier followed by "=" (a setter name),
+   * * the name of a declarable operator
+   *   (one of "`+`", "`-`", "`*`", "`/`", "`%`", "`~/`", "`&`", "`|`",
+   *   "`^`", "`~`", "`<<`", "`>>`", "`<`", "`<=`", "`>`", "`>=`", "`==`",
+   *   "`[]`", "`[]=`", or "`unary-`"),
+   * * any of the above preceded by any number of qualifiers,
+   *   where a qualifier is a non-private identifier followed by '`.`',
+   * * or the empty string (the default name of a library with no library
+   *   name declaration).
+   *
+   * Symbol instances created from the same [name] are equal,
+   * but not necessarily identical, but symbols created as compile-time
+   * constants are canonicalized, as all other constant object creations.
+   *
+   * ```dart
+   * assert(new Symbol("foo") == new Symbol("foo"));
+   * assert(identical(const Symbol("foo"), const Symbol("foo")));
+   * ```
+   *
+   * If [name] is a single identifier that does not start with an underscore,
+   * or it is a qualified identifier,
+   * or it is an operator name different from `unary-`,
+   * then the result of `const Symbol(name)` is the same instance that
+   * the symbol literal created by prefixing `#` to the content of [name]
+   * would evaluate to.
+   *
+   * ```dart
+   * assert(new Symbol("foo") == #foo);
+   * assert(new Symbol("[]=") == #[]=]);
+   * assert(new Symbol("foo.bar") == #foo.bar);
+   * assert(identical(const Symbol("foo"), #foo));
+   * assert(identical(const Symbol("[]="), #[]=]));
+   * assert(identical(const Symbol("foo.bar"), #foo.bar));
+   * ```
+   *
+   * This constructor cannot create a [Symbol] instance that is equal to
+   * a private symbol literal like `#_foo`.
+   * ```dart
+   * const Symbol("_foo") // Invalid
+   * ```
+   *
+   * The created instance overrides [Object.==].
+   *
+   * The following text is non-normative:
+   *
+   * Creating non-const Symbol instances may result in larger output.  If
+   * possible, use `MirrorsUsed` from "dart:mirrors" to specify which names
+   * might be passed to this constructor.
+   */
+  const factory Symbol(String name) = internal.Symbol;
+
+  /**
+   * Returns a hash code compatible with [operator==].
+   *
+   * Equal symbols have the same hash code.
+   */
+  int get hashCode;
+
+  /**
+   * Symbols are equal to other symbols that correspond to the same member name.
+   *
+   * Qualified member names, like `#foo.bar` are equal only if they have the
+   * same identifiers before the same final member name.
+   */
+  bool operator ==(other);
+}
diff --git a/sdk_nnbd/lib/core/type.dart b/sdk_nnbd/lib/core/type.dart
new file mode 100644
index 0000000..d2e107b
--- /dev/null
+++ b/sdk_nnbd/lib/core/type.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 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 dart.core;
+
+/**
+ * Runtime representation of a type.
+ */
+abstract class Type {}
diff --git a/sdk_nnbd/lib/core/uri.dart b/sdk_nnbd/lib/core/uri.dart
new file mode 100644
index 0000000..2ca94a1
--- /dev/null
+++ b/sdk_nnbd/lib/core/uri.dart
@@ -0,0 +1,4784 @@
+// Copyright (c) 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 dart.core;
+
+// Frequently used character codes.
+const int _SPACE = 0x20;
+const int _PERCENT = 0x25;
+const int _AMPERSAND = 0x26;
+const int _PLUS = 0x2B;
+const int _DOT = 0x2E;
+const int _SLASH = 0x2F;
+const int _COLON = 0x3A;
+const int _EQUALS = 0x3d;
+const int _UPPER_CASE_A = 0x41;
+const int _UPPER_CASE_Z = 0x5A;
+const int _LEFT_BRACKET = 0x5B;
+const int _BACKSLASH = 0x5C;
+const int _RIGHT_BRACKET = 0x5D;
+const int _LOWER_CASE_A = 0x61;
+const int _LOWER_CASE_F = 0x66;
+const int _LOWER_CASE_Z = 0x7A;
+
+const String _hexDigits = "0123456789ABCDEF";
+
+/**
+ * A parsed URI, such as a URL.
+ *
+ * **See also:**
+ *
+ * * [URIs][uris] in the [library tour][libtour]
+ * * [RFC-3986](http://tools.ietf.org/html/rfc3986)
+ *
+ * [uris]: https://www.dartlang.org/docs/dart-up-and-running/ch03.html#uris
+ * [libtour]: https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html
+ */
+abstract class Uri {
+  /**
+   * Returns the natural base URI for the current platform.
+   *
+   * When running in a browser this is the current URL of the current page
+   * (from `window.location.href`).
+   *
+   * When not running in a browser this is the file URI referencing
+   * the current working directory.
+   */
+  external static Uri get base;
+
+  /**
+   * Creates a new URI from its components.
+   *
+   * Each component is set through a named argument. Any number of
+   * components can be provided. The [path] and [query] components can be set
+   * using either of two different named arguments.
+   *
+   * The scheme component is set through [scheme]. The scheme is
+   * normalized to all lowercase letters. If the scheme is omitted or empty,
+   * the URI will not have a scheme part.
+   *
+   * The user info part of the authority component is set through
+   * [userInfo]. It defaults to the empty string, which will be omitted
+   * from the string representation of the URI.
+   *
+   * The host part of the authority component is set through
+   * [host]. The host can either be a hostname, an IPv4 address or an
+   * IPv6 address, contained in '[' and ']'. If the host contains a
+   * ':' character, the '[' and ']' are added if not already provided.
+   * The host is normalized to all lowercase letters.
+   *
+   * The port part of the authority component is set through
+   * [port].
+   * If [port] is omitted or `null`, it implies the default port for
+   * the URI's scheme, and is equivalent to passing that port explicitly.
+   * The recognized schemes, and their default ports, are "http" (80) and
+   * "https" (443). All other schemes are considered as having zero as the
+   * default port.
+   *
+   * If any of `userInfo`, `host` or `port` are provided,
+   * the URI has an authority according to [hasAuthority].
+   *
+   * The path component is set through either [path] or
+   * [pathSegments].
+   * When [path] is used, it should be a valid URI path,
+   * but invalid characters, except the general delimiters ':/@[]?#',
+   * will be escaped if necessary.
+   * When [pathSegments] is used, each of the provided segments
+   * is first percent-encoded and then joined using the forward slash
+   * separator.
+   *
+   * The percent-encoding of the path segments encodes all
+   * characters except for the unreserved characters and the following
+   * list of characters: `!$&'()*+,;=:@`. If the other components
+   * necessitate an absolute path, a leading slash `/` is prepended if
+   * not already there.
+   *
+   * The query component is set through either [query] or [queryParameters].
+   * When [query] is used, the provided string should be a valid URI query,
+   * but invalid characters, other than general delimiters,
+   * will be escaped if necessary.
+   * When [queryParameters] is used the query is built from the
+   * provided map. Each key and value in the map is percent-encoded
+   * and joined using equal and ampersand characters.
+   * A value in the map must be either a string, or an [Iterable] of strings,
+   * where the latter corresponds to multiple values for the same key.
+   *
+   * The percent-encoding of the keys and values encodes all characters
+   * except for the unreserved characters, and replaces spaces with `+`.
+   * If `query` is the empty string, it is equivalent to omitting it.
+   * To have an actual empty query part,
+   * use an empty map for `queryParameters`.
+   *
+   * If both `query` and `queryParameters` are omitted or `null`,
+   * the URI has no query part.
+   *
+   * The fragment component is set through [fragment].
+   * It should be a valid URI fragment, but invalid characters other than
+   * general delimiters, are escaped if necessary.
+   * If `fragment` is omitted or `null`, the URI has no fragment part.
+   */
+  factory Uri(
+      {String scheme,
+      String userInfo,
+      String host,
+      int port,
+      String path,
+      Iterable<String> pathSegments,
+      String query,
+      Map<String, dynamic /*String|Iterable<String>*/ > queryParameters,
+      String fragment}) = _Uri;
+
+  /**
+   * Creates a new `http` URI from authority, path and query.
+   *
+   * Examples:
+   *
+   * ```
+   * // http://example.org/path?q=dart.
+   * new Uri.http("example.org", "/path", { "q" : "dart" });
+   *
+   * // http://user:pass@localhost:8080
+   * new Uri.http("user:pass@localhost:8080", "");
+   *
+   * // http://example.org/a%20b
+   * new Uri.http("example.org", "a b");
+   *
+   * // http://example.org/a%252F
+   * new Uri.http("example.org", "/a%2F");
+   * ```
+   *
+   * The `scheme` is always set to `http`.
+   *
+   * The `userInfo`, `host` and `port` components are set from the
+   * [authority] argument. If `authority` is `null` or empty,
+   * the created `Uri` has no authority, and isn't directly usable
+   * as an HTTP URL, which must have a non-empty host.
+   *
+   * 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]) = _Uri.http;
+
+  /**
+   * 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]) = _Uri.https;
+
+  /**
+   * Creates a new file URI from an absolute or relative file path.
+   *
+   * The file path is passed in [path].
+   *
+   * This path is interpreted using either Windows or non-Windows
+   * semantics.
+   *
+   * With non-Windows semantics the slash (`/`) is used to separate
+   * path segments in the input [path].
+   *
+   * With Windows semantics, backslash (`\`) and forward-slash (`/`)
+   * are used to separate path segments in the input [path],
+   * except if the path starts with `\\?\` in which case
+   * only backslash (`\`) separates path segments in [path].
+   *
+   * If the path starts with a path separator, an absolute URI (with the
+   * `file` scheme and an empty authority) is created.
+   * Otherwise a relative URI reference with no scheme or authority is created.
+   * One exception from this rule is that when Windows semantics is used
+   * and the path starts with a drive letter followed by a colon (":") and a
+   * path separator, then an absolute URI is created.
+   *
+   * The default for whether to use Windows or non-Windows semantics
+   * determined from the platform Dart is running on. When running in
+   * the standalone VM, this is detected by the VM based on the
+   * operating system. When running in a browser non-Windows semantics
+   * is always used.
+   *
+   * To override the automatic detection of which semantics to use pass
+   * a value for [windows]. Passing `true` will use Windows
+   * semantics and passing `false` will use non-Windows semantics.
+   *
+   * Examples using non-Windows semantics:
+   *
+   * ```
+   * // xxx/yyy
+   * new Uri.file("xxx/yyy", windows: false);
+   *
+   * // xxx/yyy/
+   * new Uri.file("xxx/yyy/", windows: false);
+   *
+   * // file:///xxx/yyy
+   * new Uri.file("/xxx/yyy", windows: false);
+   *
+   * // file:///xxx/yyy/
+   * new Uri.file("/xxx/yyy/", windows: false);
+   *
+   * // C%3A
+   * new Uri.file("C:", windows: false);
+   * ```
+   *
+   * Examples using Windows semantics:
+   *
+   * ```
+   * // xxx/yyy
+   * new Uri.file(r"xxx\yyy", windows: true);
+   *
+   * // xxx/yyy/
+   * new Uri.file(r"xxx\yyy\", windows: true);
+   *
+   * file:///xxx/yyy
+   * new Uri.file(r"\xxx\yyy", windows: true);
+   *
+   * file:///xxx/yyy/
+   * new Uri.file(r"\xxx\yyy/", windows: true);
+   *
+   * // file:///C:/xxx/yyy
+   * new Uri.file(r"C:\xxx\yyy", windows: true);
+   *
+   * // This throws an error. A path with a drive letter, but no following
+   * // path, is not allowed.
+   * new Uri.file(r"C:", windows: true);
+   *
+   * // This throws an error. A path with a drive letter is not absolute.
+   * new Uri.file(r"C:xxx\yyy", windows: true);
+   *
+   * // file://server/share/file
+   * new Uri.file(r"\\server\share\file", windows: true);
+   * ```
+   *
+   * If the path passed is not a valid file path, an error is thrown.
+   */
+  factory Uri.file(String path, {bool windows}) = _Uri.file;
+
+  /**
+   * Like [Uri.file] except that a non-empty URI path ends in a slash.
+   *
+   * If [path] is not empty, and it doesn't end in a directory separator,
+   * then a slash is added to the returned URI's path.
+   * In all other cases, the result is the same as returned by `Uri.file`.
+   */
+  factory Uri.directory(String path, {bool windows}) = _Uri.directory;
+
+  /**
+   * Creates a `data:` URI containing the [content] string.
+   *
+   * Converts the content to a bytes using [encoding] or the charset specified
+   * in [parameters] (defaulting to US-ASCII if not specified or unrecognized),
+   * then encodes the bytes into the resulting data URI.
+   *
+   * Defaults to encoding using percent-encoding (any non-ASCII or non-URI-valid
+   * bytes is replaced by a percent encoding). If [base64] is true, the bytes
+   * are instead encoded using [base64].
+   *
+   * If [encoding] is not provided and [parameters] has a `charset` entry,
+   * that name is looked up using [Encoding.getByName],
+   * and if the lookup returns an encoding, that encoding is used to convert
+   * [content] to bytes.
+   * If providing both an [encoding] and a charset in [parameters], they should
+   * agree, otherwise decoding won't be able to use the charset parameter
+   * to determine the encoding.
+   *
+   * If [mimeType] and/or [parameters] are supplied, they are added to the
+   * created URI. If any of these contain characters that are not allowed
+   * in the data URI, the character is percent-escaped. If the character is
+   * non-ASCII, it is first UTF-8 encoded and then the bytes are percent
+   * encoded. An omitted [mimeType] in a data URI means `text/plain`, just
+   * as an omitted `charset` parameter defaults to meaning `US-ASCII`.
+   *
+   * To read the content back, use [UriData.contentAsString].
+   */
+  factory Uri.dataFromString(String content,
+      {String mimeType,
+      Encoding encoding,
+      Map<String, String> parameters,
+      bool base64 = false}) {
+    UriData data = UriData.fromString(content,
+        mimeType: mimeType,
+        encoding: encoding,
+        parameters: parameters,
+        base64: base64);
+    return data.uri;
+  }
+
+  /**
+   * Creates a `data:` URI containing an encoding of [bytes].
+   *
+   * Defaults to Base64 encoding the bytes, but if [percentEncoded]
+   * is `true`, the bytes will instead be percent encoded (any non-ASCII
+   * or non-valid-ASCII-character byte is replaced by a percent encoding).
+   *
+   * To read the bytes back, use [UriData.contentAsBytes].
+   *
+   * It defaults to having the mime-type `application/octet-stream`.
+   * The [mimeType] and [parameters] are added to the created URI.
+   * If any of these contain characters that are not allowed
+   * in the data URI, the character is percent-escaped. If the character is
+   * non-ASCII, it is first UTF-8 encoded and then the bytes are percent
+   * encoded.
+   */
+  factory Uri.dataFromBytes(List<int> bytes,
+      {mimeType = "application/octet-stream",
+      Map<String, String> parameters,
+      percentEncoded = false}) {
+    UriData data = UriData.fromBytes(bytes,
+        mimeType: mimeType,
+        parameters: parameters,
+        percentEncoded: percentEncoded);
+    return data.uri;
+  }
+
+  /**
+   * The scheme component of the URI.
+   *
+   * Returns the empty string if there is no scheme component.
+   *
+   * A URI scheme is case insensitive.
+   * The returned scheme is canonicalized to lowercase letters.
+   */
+  String get scheme;
+
+  /**
+   * Returns the authority component.
+   *
+   * The authority is formatted from the [userInfo], [host] and [port]
+   * parts.
+   *
+   * Returns the empty string if there is no authority component.
+   */
+  String get authority;
+
+  /**
+   * Returns the user info part of the authority component.
+   *
+   * Returns the empty string if there is no user info in the
+   * authority component.
+   */
+  String get userInfo;
+
+  /**
+   * Returns the host part of the authority component.
+   *
+   * Returns the empty string if there is no authority component and
+   * hence no host.
+   *
+   * If the host is an IP version 6 address, the surrounding `[` and `]` is
+   * removed.
+   *
+   * The host string is case-insensitive.
+   * The returned host name is canonicalized to lower-case
+   * with upper-case percent-escapes.
+   */
+  String get host;
+
+  /**
+   * Returns the port part of the authority component.
+   *
+   * Returns the default port if there is no port number in the authority
+   * component. That's 80 for http, 443 for https, and 0 for everything else.
+   */
+  int get port;
+
+  /**
+   * Returns the path component.
+   *
+   * The returned path is encoded. To get direct access to the decoded
+   * path use [pathSegments].
+   *
+   * Returns the empty string if there is no path component.
+   */
+  String get path;
+
+  /**
+   * Returns the query component. The returned query is encoded. To get
+   * direct access to the decoded query use [queryParameters].
+   *
+   * Returns the empty string if there is no query component.
+   */
+  String get query;
+
+  /**
+   * Returns the fragment identifier component.
+   *
+   * Returns the empty string if there is no fragment identifier
+   * component.
+   */
+  String get fragment;
+
+  /**
+   * 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 not affect the segments returned.
+   *
+   * The returned list is unmodifiable and will throw [UnsupportedError] on any
+   * calls that would mutate it.
+   */
+  List<String> get pathSegments;
+
+  /**
+   * Returns the URI query split into a map according to the rules
+   * specified for FORM post in the [HTML 4.01 specification section
+   * 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4").
+   * Each key and value in the returned map has been decoded.
+   * If there is no query the empty map is returned.
+   *
+   * Keys in the query string that have no value are mapped to the
+   * empty string.
+   * If a key occurs more than once in the query string, it is mapped to
+   * an arbitrary choice of possible value.
+   * The [queryParametersAll] getter can provide a map
+   * that maps keys to all of their values.
+   *
+   * The returned map is unmodifiable.
+   */
+  Map<String, String> get queryParameters;
+
+  /**
+   * Returns the URI query split into a map according to the rules
+   * specified for FORM post in the [HTML 4.01 specification section
+   * 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4").
+   * Each key and value in the returned map has been decoded. If there is no
+   * query the empty map is returned.
+   *
+   * Keys are mapped to lists of their values. If a key occurs only once,
+   * its value is a singleton list. If a key occurs with no value, the
+   * empty string is used as the value for that occurrence.
+   *
+   * The returned map and the lists it contains are unmodifiable.
+   */
+  Map<String, List<String>> get queryParametersAll;
+
+  /**
+   * Returns whether the URI is absolute.
+   *
+   * A URI is an absolute URI in the sense of RFC 3986 if it has a scheme
+   * and no fragment.
+   */
+  bool get isAbsolute;
+
+  /**
+   * Returns whether the URI has a [scheme] component.
+   */
+  bool get hasScheme => scheme.isNotEmpty;
+
+  /**
+   * Returns whether the URI has an [authority] component.
+   */
+  bool get hasAuthority;
+
+  /**
+   * Returns whether the URI has an explicit port.
+   *
+   * If the port number is the default port number
+   * (zero for unrecognized schemes, with http (80) and https (443) being
+   * recognized),
+   * then the port is made implicit and omitted from the URI.
+   */
+  bool get hasPort;
+
+  /**
+   * Returns whether the URI has a query part.
+   */
+  bool get hasQuery;
+
+  /**
+   * Returns whether the URI has a fragment part.
+   */
+  bool get hasFragment;
+
+  /**
+   * Returns whether the URI has an empty path.
+   */
+  bool get hasEmptyPath;
+
+  /**
+   * Returns whether the URI has an absolute path (starting with '/').
+   */
+  bool get hasAbsolutePath;
+
+  /**
+   * Returns the origin of the URI in the form scheme://host:port for the
+   * schemes http and https.
+   *
+   * It is an error if the scheme is not "http" or "https", or if the host name
+   * is missing or empty.
+   *
+   * See: http://www.w3.org/TR/2011/WD-html5-20110405/origin-0.html#origin
+   */
+  String get origin;
+
+  /// Whether the scheme of this [Uri] is [scheme].
+  ///
+  /// The [scheme] should be the same as the one returned by [Uri.scheme],
+  /// but doesn't have to be case-normalized to lower-case characters.
+  ///
+  /// Example:
+  /// ```dart
+  /// var uri = Uri.parse("http://example.com/");
+  /// print(uri.isScheme("HTTP"));  // Prints true.
+  /// ```
+  ///
+  /// A `null` or empty [scheme] string matches a URI with no scheme
+  /// (one where [hasScheme] returns false).
+  bool isScheme(String scheme);
+
+  /**
+   * Returns the file path from a file URI.
+   *
+   * The returned path has either Windows or non-Windows
+   * semantics.
+   *
+   * For non-Windows semantics the slash ("/") is used to separate
+   * path segments.
+   *
+   * For Windows semantics the backslash ("\\") separator is used to
+   * separate path segments.
+   *
+   * If the URI is absolute the path starts with a path separator
+   * unless Windows semantics is used and the first path segment is a
+   * drive letter. When Windows semantics is used a host component in
+   * the uri in interpreted as a file server and a UNC path is
+   * returned.
+   *
+   * The default for whether to use Windows or non-Windows semantics
+   * determined from the platform Dart is running on. When running in
+   * the standalone VM this is detected by the VM based on the
+   * operating system. When running in a browser non-Windows semantics
+   * is always used.
+   *
+   * To override the automatic detection of which semantics to use pass
+   * a value for [windows]. Passing `true` will use Windows
+   * semantics and passing `false` will use non-Windows semantics.
+   *
+   * If the URI ends with a slash (i.e. the last path component is
+   * empty) the returned file path will also end with a slash.
+   *
+   * With Windows semantics URIs starting with a drive letter cannot
+   * be relative to the current drive on the designated drive. That is
+   * for the URI `file:///c:abc` calling `toFilePath` will throw as a
+   * path segment cannot contain colon on Windows.
+   *
+   * Examples using non-Windows semantics (resulting of calling
+   * toFilePath in comment):
+   *
+   *     Uri.parse("xxx/yyy");  // xxx/yyy
+   *     Uri.parse("xxx/yyy/");  // xxx/yyy/
+   *     Uri.parse("file:///xxx/yyy");  // /xxx/yyy
+   *     Uri.parse("file:///xxx/yyy/");  // /xxx/yyy/
+   *     Uri.parse("file:///C:");  // /C:
+   *     Uri.parse("file:///C:a");  // /C:a
+   *
+   * Examples using Windows semantics (resulting URI in comment):
+   *
+   *     Uri.parse("xxx/yyy");  // xxx\yyy
+   *     Uri.parse("xxx/yyy/");  // xxx\yyy\
+   *     Uri.parse("file:///xxx/yyy");  // \xxx\yyy
+   *     Uri.parse("file:///xxx/yyy/");  // \xxx\yyy\
+   *     Uri.parse("file:///C:/xxx/yyy");  // C:\xxx\yyy
+   *     Uri.parse("file:C:xxx/yyy");  // Throws as a path segment
+   *                                   // cannot contain colon on Windows.
+   *     Uri.parse("file://server/share/file");  // \\server\share\file
+   *
+   * If the URI is not a file URI calling this throws
+   * [UnsupportedError].
+   *
+   * If the URI cannot be converted to a file path calling this throws
+   * [UnsupportedError].
+   */
+  // TODO(lrn): Deprecate and move functionality to File class or similar.
+  // The core libraries should not worry about the platform.
+  String toFilePath({bool windows});
+
+  /**
+   * Access the structure of a `data:` URI.
+   *
+   * Returns a [UriData] object for `data:` URIs and `null` for all other
+   * URIs.
+   * The [UriData] object can be used to access the media type and data
+   * of a `data:` URI.
+   */
+  UriData get data;
+
+  /// Returns a hash code computed as `toString().hashCode`.
+  ///
+  /// This guarantees that URIs with the same normalized
+  int get hashCode;
+
+  /// A URI is equal to another URI with the same normalized representation.
+  bool operator ==(Object other);
+
+  /// Returns the normalized string representation of the URI.
+  String toString();
+
+  /**
+   * Returns a new `Uri` based on this one, but with some parts replaced.
+   *
+   * This method takes the same parameters as the [new Uri] constructor,
+   * and they have the same meaning.
+   *
+   * At most one of [path] and [pathSegments] must be provided.
+   * Likewise, at most one of [query] and [queryParameters] must be provided.
+   *
+   * Each part that is not provided will default to the corresponding
+   * value from this `Uri` instead.
+   *
+   * This method is different from [Uri.resolve] which overrides in a
+   * hierarchical manner,
+   * and can instead replace each part of a `Uri` individually.
+   *
+   * Example:
+   *
+   *     Uri uri1 = Uri.parse("a://b@c:4/d/e?f#g");
+   *     Uri uri2 = uri1.replace(scheme: "A", path: "D/E/E", fragment: "G");
+   *     print(uri2);  // prints "a://b@c:4/D/E/E?f#G"
+   *
+   * This method acts similarly to using the `new Uri` constructor with
+   * some of the arguments taken from this `Uri`. Example:
+   *
+   *     Uri uri3 = new Uri(
+   *         scheme: "A",
+   *         userInfo: uri1.userInfo,
+   *         host: uri1.host,
+   *         port: uri1.port,
+   *         path: "D/E/E",
+   *         query: uri1.query,
+   *         fragment: "G");
+   *     print(uri3);  // prints "a://b@c:4/D/E/E?f#G"
+   *     print(uri2 == uri3);  // prints true.
+   *
+   * Using this method can be seen as a shorthand for the `Uri` constructor
+   * call above, but may also be slightly faster because the parts taken
+   * from this `Uri` need not be checked for validity again.
+   */
+  Uri replace(
+      {String scheme,
+      String userInfo,
+      String host,
+      int port,
+      String path,
+      Iterable<String> pathSegments,
+      String query,
+      Map<String, dynamic /*String|Iterable<String>*/ > queryParameters,
+      String fragment});
+
+  /**
+   * Returns a `Uri` that differs from this only in not having a fragment.
+   *
+   * If this `Uri` does not have a fragment, it is itself returned.
+   */
+  Uri removeFragment();
+
+  /**
+   * Resolve [reference] as an URI relative to `this`.
+   *
+   * First turn [reference] into a URI using [Uri.parse]. Then resolve the
+   * resulting URI relative to `this`.
+   *
+   * Returns the resolved URI.
+   *
+   * See [resolveUri] for details.
+   */
+  Uri resolve(String reference);
+
+  /**
+   * Resolve [reference] as an URI relative to `this`.
+   *
+   * Returns the resolved URI.
+   *
+   * The algorithm "Transform Reference" for resolving a reference is described
+   * in [RFC-3986 Section 5](http://tools.ietf.org/html/rfc3986#section-5 "RFC-1123").
+   *
+   * Updated to handle the case where the base URI is just a relative path -
+   * that is: when it has no scheme and no authority and the path does not start
+   * with a slash.
+   * In that case, the paths are combined without removing leading "..", and
+   * an empty path is not converted to "/".
+   */
+  Uri resolveUri(Uri reference);
+
+  /**
+   * Returns a URI where the path has been normalized.
+   *
+   * A normalized path does not contain `.` segments or non-leading `..`
+   * segments.
+   * Only a relative path with no scheme or authority may contain
+   * leading `..` segments,
+   * a path that starts with `/` will also drop any leading `..` segments.
+   *
+   * This uses the same normalization strategy as `new Uri().resolve(this)`.
+   *
+   * Does not change any part of the URI except the path.
+   *
+   * The default implementation of `Uri` always normalizes paths, so calling
+   * this function has no effect.
+   */
+  Uri normalizePath();
+
+  /**
+   * Creates a new `Uri` object by parsing a URI string.
+   *
+   * If [start] and [end] are provided, they must specify a valid substring
+   * of [uri], and only the substring from `start` to `end` is parsed as a URI.
+   *
+   * The [uri] must not be `null`.
+   * If the [uri] string is not valid as a URI or URI reference,
+   * a [FormatException] is thrown.
+   */
+  static Uri parse(String uri, [int start = 0, int end]) {
+    // This parsing will not validate percent-encoding, IPv6, etc.
+    // When done splitting into parts, it will call, e.g., [_makeFragment]
+    // to do the final parsing.
+    //
+    // Important parts of the RFC 3986 used here:
+    // URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
+    //
+    // hier-part     = "//" authority path-abempty
+    //               / path-absolute
+    //               / path-rootless
+    //               / path-empty
+    //
+    // URI-reference = URI / relative-ref
+    //
+    // absolute-URI  = scheme ":" hier-part [ "?" query ]
+    //
+    // relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
+    //
+    // relative-part = "//" authority path-abempty
+    //               / path-absolute
+    //               / path-noscheme
+    //               / path-empty
+    //
+    // scheme        = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+    //
+    // authority     = [ userinfo "@" ] host [ ":" port ]
+    // userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )
+    // host          = IP-literal / IPv4address / reg-name
+    // IP-literal    = "[" ( IPv6address / IPv6addrz / IPvFuture ) "]"
+    // IPv6addrz     = IPv6address "%25" ZoneID
+    // ZoneID        = 1*( unreserved / pct-encoded )
+    // port          = *DIGIT
+    // reg-name      = *( unreserved / pct-encoded / sub-delims )
+    //
+    // path          = path-abempty    ; begins with "/" or is empty
+    //               / path-absolute   ; begins with "/" but not "//"
+    //               / path-noscheme   ; begins with a non-colon segment
+    //               / path-rootless   ; begins with a segment
+    //               / path-empty      ; zero characters
+    //
+    // path-abempty  = *( "/" segment )
+    // path-absolute = "/" [ segment-nz *( "/" segment ) ]
+    // path-noscheme = segment-nz-nc *( "/" segment )
+    // path-rootless = segment-nz *( "/" segment )
+    // path-empty    = 0<pchar>
+    //
+    // segment       = *pchar
+    // segment-nz    = 1*pchar
+    // segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
+    //               ; non-zero-length segment without any colon ":"
+    //
+    // pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
+    //
+    // query         = *( pchar / "/" / "?" )
+    //
+    // fragment      = *( pchar / "/" / "?" )
+    end ??= uri.length;
+
+    // Special case data:URIs. Ignore case when testing.
+    if (end >= start + 5) {
+      int dataDelta = _startsWithData(uri, start);
+      if (dataDelta == 0) {
+        // The case is right.
+        if (start > 0 || end < uri.length) uri = uri.substring(start, end);
+        return UriData._parse(uri, 5, null).uri;
+      } else if (dataDelta == 0x20) {
+        return UriData._parse(uri.substring(start + 5, end), 0, null).uri;
+      }
+      // Otherwise the URI doesn't start with "data:" or any case variant of it.
+    }
+
+    // The following index-normalization belongs with the scanning, but is
+    // easier to do here because we already have extracted variables from the
+    // indices list.
+    var indices = List<int>(8);
+
+    // Set default values for each position.
+    // The value will either be correct in some cases where it isn't set
+    // by the scanner, or it is clearly recognizable as an unset value.
+    indices
+      ..[0] = 0
+      ..[_schemeEndIndex] = start - 1
+      ..[_hostStartIndex] = start - 1
+      ..[_notSimpleIndex] = start - 1
+      ..[_portStartIndex] = start
+      ..[_pathStartIndex] = start
+      ..[_queryStartIndex] = end
+      ..[_fragmentStartIndex] = end;
+    var state = _scan(uri, start, end, _uriStart, indices);
+    // Some states that should be non-simple, but the URI ended early.
+    // Paths that end at a ".." must be normalized to end in "../".
+    if (state >= _nonSimpleEndStates) {
+      indices[_notSimpleIndex] = end;
+    }
+    int schemeEnd = indices[_schemeEndIndex];
+    if (schemeEnd >= start) {
+      // Rescan the scheme part now that we know it's not a path.
+      state = _scan(uri, start, schemeEnd, _schemeStart, indices);
+      if (state == _schemeStart) {
+        // Empty scheme.
+        indices[_notSimpleIndex] = schemeEnd;
+      }
+    }
+    // The returned positions are limited by the scanners ability to write only
+    // one position per character, and only the current position.
+    // Scanning from left to right, we only know whether something is a scheme
+    // or a path when we see a `:` or `/`, and likewise we only know if the first
+    // `/` is part of the path or is leading an authority component when we see
+    // the next character.
+
+    int hostStart = indices[_hostStartIndex] + 1;
+    int portStart = indices[_portStartIndex];
+    int pathStart = indices[_pathStartIndex];
+    int queryStart = indices[_queryStartIndex];
+    int fragmentStart = indices[_fragmentStartIndex];
+
+    // We may discover scheme while handling special cases.
+    String scheme;
+
+    // Derive some positions that weren't set to normalize the indices.
+    if (fragmentStart < queryStart) queryStart = fragmentStart;
+    // If pathStart isn't set (it's before scheme end or host start), then
+    // the path is empty, or there is no authority part and the path
+    // starts with a non-simple character.
+    if (pathStart < hostStart) {
+      // There is an authority, but no path. The path would start with `/`
+      // if it was there.
+      pathStart = queryStart;
+    } else if (pathStart <= schemeEnd) {
+      // There is a scheme, but no authority.
+      pathStart = schemeEnd + 1;
+    }
+    // If there is an authority with no port, set the port position
+    // to be at the end of the authority (equal to pathStart).
+    // This also handles a ":" in a user-info component incorrectly setting
+    // the port start position.
+    if (portStart < hostStart) portStart = pathStart;
+
+    assert(hostStart == start || schemeEnd <= hostStart);
+    assert(hostStart <= portStart);
+    assert(schemeEnd <= pathStart);
+    assert(portStart <= pathStart);
+    assert(pathStart <= queryStart);
+    assert(queryStart <= fragmentStart);
+
+    bool isSimple = indices[_notSimpleIndex] < start;
+
+    if (isSimple) {
+      // Check/do normalizations that weren't detected by the scanner.
+      // This includes removal of empty port or userInfo,
+      // or scheme specific port and path normalizations.
+      if (hostStart > schemeEnd + 3) {
+        // Always be non-simple if URI contains user-info.
+        // The scanner doesn't set the not-simple position in this case because
+        // it's setting the host-start position instead.
+        isSimple = false;
+      } else if (portStart > start && portStart + 1 == pathStart) {
+        // If the port is empty, it should be omitted.
+        // Pathological case, don't bother correcting it.
+        isSimple = false;
+      } else if (queryStart < end &&
+              (queryStart == pathStart + 2 &&
+                  uri.startsWith("..", pathStart)) ||
+          (queryStart > pathStart + 2 &&
+              uri.startsWith("/..", queryStart - 3))) {
+        // The path ends in a ".." segment. This should be normalized to "../".
+        // We didn't detect this while scanning because a query or fragment was
+        // detected at the same time (which is why we only need to check this
+        // if there is something after the path).
+        isSimple = false;
+      } else {
+        // There are a few scheme-based normalizations that
+        // the scanner couldn't check.
+        // That means that the input is very close to simple, so just do
+        // the normalizations.
+        if (schemeEnd == start + 4) {
+          // Do scheme based normalizations for file, http.
+          if (uri.startsWith("file", start)) {
+            scheme = "file";
+            if (hostStart <= start) {
+              // File URIs should have an authority.
+              // Paths after an authority should be absolute.
+              String schemeAuth = "file://";
+              int delta = 2;
+              if (!uri.startsWith("/", pathStart)) {
+                schemeAuth = "file:///";
+                delta = 3;
+              }
+              uri = schemeAuth + uri.substring(pathStart, end);
+              schemeEnd -= start;
+              hostStart = 7;
+              portStart = 7;
+              pathStart = 7;
+              queryStart += delta - start;
+              fragmentStart += delta - start;
+              start = 0;
+              end = uri.length;
+            } else if (pathStart == queryStart) {
+              // Uri has authority and empty path. Add "/" as path.
+              if (start == 0 && end == uri.length) {
+                uri = uri.replaceRange(pathStart, queryStart, "/");
+                queryStart += 1;
+                fragmentStart += 1;
+                end += 1;
+              } else {
+                uri = "${uri.substring(start, pathStart)}/"
+                    "${uri.substring(queryStart, end)}";
+                schemeEnd -= start;
+                hostStart -= start;
+                portStart -= start;
+                pathStart -= start;
+                queryStart += 1 - start;
+                fragmentStart += 1 - start;
+                start = 0;
+                end = uri.length;
+              }
+            }
+          } else if (uri.startsWith("http", start)) {
+            scheme = "http";
+            // HTTP URIs should not have an explicit port of 80.
+            if (portStart > start &&
+                portStart + 3 == pathStart &&
+                uri.startsWith("80", portStart + 1)) {
+              if (start == 0 && end == uri.length) {
+                uri = uri.replaceRange(portStart, pathStart, "");
+                pathStart -= 3;
+                queryStart -= 3;
+                fragmentStart -= 3;
+                end -= 3;
+              } else {
+                uri = uri.substring(start, portStart) +
+                    uri.substring(pathStart, end);
+                schemeEnd -= start;
+                hostStart -= start;
+                portStart -= start;
+                pathStart -= 3 + start;
+                queryStart -= 3 + start;
+                fragmentStart -= 3 + start;
+                start = 0;
+                end = uri.length;
+              }
+            }
+          }
+        } else if (schemeEnd == start + 5 && uri.startsWith("https", start)) {
+          scheme = "https";
+          // HTTPS URIs should not have an explicit port of 443.
+          if (portStart > start &&
+              portStart + 4 == pathStart &&
+              uri.startsWith("443", portStart + 1)) {
+            if (start == 0 && end == uri.length) {
+              uri = uri.replaceRange(portStart, pathStart, "");
+              pathStart -= 4;
+              queryStart -= 4;
+              fragmentStart -= 4;
+              end -= 3;
+            } else {
+              uri = uri.substring(start, portStart) +
+                  uri.substring(pathStart, end);
+              schemeEnd -= start;
+              hostStart -= start;
+              portStart -= start;
+              pathStart -= 4 + start;
+              queryStart -= 4 + start;
+              fragmentStart -= 4 + start;
+              start = 0;
+              end = uri.length;
+            }
+          }
+        }
+      }
+    }
+
+    if (isSimple) {
+      if (start > 0 || end < uri.length) {
+        uri = uri.substring(start, end);
+        schemeEnd -= start;
+        hostStart -= start;
+        portStart -= start;
+        pathStart -= start;
+        queryStart -= start;
+        fragmentStart -= start;
+      }
+      return _SimpleUri(uri, schemeEnd, hostStart, portStart, pathStart,
+          queryStart, fragmentStart, scheme);
+    }
+
+    return _Uri.notSimple(uri, start, end, schemeEnd, hostStart, portStart,
+        pathStart, queryStart, fragmentStart, scheme);
+  }
+
+  /**
+   * Creates a new `Uri` object by parsing a URI string.
+   *
+   * If [start] and [end] are provided, they must specify a valid substring
+   * of [uri], and only the substring from `start` to `end` is parsed as a URI.
+   * The [uri] must not be `null`.
+   *
+   * Returns `null` if the [uri] string is not valid as a URI or URI reference.
+   */
+  static Uri tryParse(String uri, [int start = 0, int end]) {
+    // TODO: Optimize to avoid throwing-and-recatching.
+    try {
+      return parse(uri, start, end);
+    } on FormatException {
+      return null;
+    }
+  }
+
+  /**
+   * Encode the string [component] using percent-encoding to make it
+   * safe for literal use as a URI component.
+   *
+   * All characters except uppercase and lowercase letters, digits and
+   * the characters `-_.!~*'()` are percent-encoded. This is the
+   * set of characters specified in RFC 2396 and the which is
+   * specified for the encodeUriComponent in ECMA-262 version 5.1.
+   *
+   * When manually encoding path segments or query components remember
+   * to encode each part separately before building the path or query
+   * string.
+   *
+   * For encoding the query part consider using
+   * [encodeQueryComponent].
+   *
+   * To avoid the need for explicitly encoding use the [pathSegments]
+   * and [queryParameters] optional named arguments when constructing
+   * a [Uri].
+   */
+  static String encodeComponent(String component) {
+    return _Uri._uriEncode(_Uri._unreserved2396Table, component, utf8, false);
+  }
+
+  /**
+   * Encode the string [component] according to the HTML 4.01 rules
+   * for encoding the posting of a HTML form as a query string
+   * component.
+   *
+   * Encode the string [component] according to the HTML 4.01 rules
+   * for encoding the posting of a HTML form as a query string
+   * component.
+
+   * The component is first encoded to bytes using [encoding].
+   * The default is to use [utf8] encoding, which preserves all
+   * the characters that don't need encoding.
+
+   * Then the resulting bytes are "percent-encoded". This transforms
+   * spaces (U+0020) to a plus sign ('+') and all bytes that are not
+   * the ASCII decimal digits, letters or one of '-._~' are written as
+   * a percent sign '%' followed by the two-digit hexadecimal
+   * representation of the byte.
+
+   * Note that the set of characters which are percent-encoded is a
+   * superset of what HTML 4.01 requires, since it refers to RFC 1738
+   * for reserved characters.
+   *
+   * When manually encoding query components remember to encode each
+   * part separately before building the query string.
+   *
+   * To avoid the need for explicitly encoding the query use the
+   * [queryParameters] optional named arguments when constructing a
+   * [Uri].
+   *
+   * See http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2 for more
+   * details.
+   */
+  static String encodeQueryComponent(String component,
+      {Encoding encoding = utf8}) {
+    return _Uri._uriEncode(_Uri._unreservedTable, component, encoding, true);
+  }
+
+  /**
+   * Decodes the percent-encoding in [encodedComponent].
+   *
+   * Note that decoding a URI component might change its meaning as
+   * some of the decoded characters could be characters with are
+   * delimiters for a given URI component type. Always split a URI
+   * component using the delimiters for the component before decoding
+   * the individual parts.
+   *
+   * For handling the [path] and [query] components consider using
+   * [pathSegments] and [queryParameters] to get the separated and
+   * decoded component.
+   */
+  static String decodeComponent(String encodedComponent) {
+    return _Uri._uriDecode(
+        encodedComponent, 0, encodedComponent.length, utf8, false);
+  }
+
+  /**
+   * Decodes the percent-encoding in [encodedComponent], converting
+   * pluses to spaces.
+   *
+   * It will create a byte-list of the decoded characters, and then use
+   * [encoding] to decode the byte-list to a String. The default encoding is
+   * UTF-8.
+   */
+  static String decodeQueryComponent(String encodedComponent,
+      {Encoding encoding = utf8}) {
+    return _Uri._uriDecode(
+        encodedComponent, 0, encodedComponent.length, encoding, true);
+  }
+
+  /**
+   * Encode the string [uri] using percent-encoding to make it
+   * safe for literal use as a full URI.
+   *
+   * All characters except uppercase and lowercase letters, digits and
+   * the characters `!#$&'()*+,-./:;=?@_~` are percent-encoded. This
+   * is the set of characters specified in in ECMA-262 version 5.1 for
+   * the encodeURI function .
+   */
+  static String encodeFull(String uri) {
+    return _Uri._uriEncode(_Uri._encodeFullTable, uri, utf8, false);
+  }
+
+  /**
+   * Decodes the percent-encoding in [uri].
+   *
+   * Note that decoding a full URI might change its meaning as some of
+   * the decoded characters could be reserved characters. In most
+   * cases an encoded URI should be parsed into components using
+   * [Uri.parse] before decoding the separate components.
+   */
+  static String decodeFull(String uri) {
+    return _Uri._uriDecode(uri, 0, uri.length, utf8, false);
+  }
+
+  /**
+   * Returns the [query] split into a map according to the rules
+   * specified for FORM post in the [HTML 4.01 specification section
+   * 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4").
+   * Each key and value in the returned map has been decoded. If the [query]
+   * is the empty string an empty map is returned.
+   *
+   * Keys in the query string that have no value are mapped to the
+   * empty string.
+   *
+   * Each query component will be decoded using [encoding]. The default encoding
+   * is UTF-8.
+   */
+  static Map<String, String> splitQueryString(String query,
+      {Encoding encoding = utf8}) {
+    return query.split("&").fold({}, (map, element) {
+      int index = element.indexOf("=");
+      if (index == -1) {
+        if (element != "") {
+          map[decodeQueryComponent(element, encoding: encoding)] = "";
+        }
+      } else if (index != 0) {
+        var key = element.substring(0, index);
+        var value = element.substring(index + 1);
+        map[decodeQueryComponent(key, encoding: encoding)] =
+            decodeQueryComponent(value, encoding: encoding);
+      }
+      return map;
+    });
+  }
+
+  /**
+   * Parse the [host] as an IP version 4 (IPv4) address, returning the address
+   * as a list of 4 bytes in network byte order (big endian).
+   *
+   * Throws a [FormatException] if [host] is not a valid IPv4 address
+   * representation.
+   */
+  static List<int> parseIPv4Address(String host) =>
+      _parseIPv4Address(host, 0, host.length);
+
+  /// Implementation of [parseIPv4Address] that can work on a substring.
+  static List<int> _parseIPv4Address(String host, int start, int end) {
+    void error(String msg, int position) {
+      throw FormatException('Illegal IPv4 address, $msg', host, position);
+    }
+
+    var result = Uint8List(4);
+    int partIndex = 0;
+    int partStart = start;
+    for (int i = start; i < end; i++) {
+      int char = host.codeUnitAt(i);
+      if (char != _DOT) {
+        if (char ^ 0x30 > 9) {
+          // Fail on a non-digit character.
+          error("invalid character", i);
+        }
+      } else {
+        if (partIndex == 3) {
+          error('IPv4 address should contain exactly 4 parts', i);
+        }
+        int part = int.parse(host.substring(partStart, i));
+        if (part > 255) {
+          error("each part must be in the range 0..255", partStart);
+        }
+        result[partIndex++] = part;
+        partStart = i + 1;
+      }
+    }
+
+    if (partIndex != 3) {
+      error('IPv4 address should contain exactly 4 parts', end);
+    }
+
+    int part = int.parse(host.substring(partStart, end));
+    if (part > 255) {
+      error("each part must be in the range 0..255", partStart);
+    }
+    result[partIndex] = part;
+
+    return result;
+  }
+
+  /**
+   * Parse the [host] as an IP version 6 (IPv6) address, returning the address
+   * as a list of 16 bytes in network byte order (big endian).
+   *
+   * Throws a [FormatException] if [host] is not a valid IPv6 address
+   * representation.
+   *
+   * Acts on the substring from [start] to [end]. If [end] is omitted, it
+   * defaults ot the end of the string.
+   *
+   * Some examples of IPv6 addresses:
+   *  * `::1`
+   *  * `FEDC:BA98:7654:3210:FEDC:BA98:7654:3210`
+   *  * `3ffe:2a00:100:7031::1`
+   *  * `::FFFF:129.144.52.38`
+   *  * `2010:836B:4179::836B:4179`
+   */
+  static List<int> parseIPv6Address(String host, [int start = 0, int end]) {
+    end ??= host.length;
+    // An IPv6 address consists of exactly 8 parts of 1-4 hex digits, separated
+    // by `:`'s, with the following exceptions:
+    //
+    //  - One (and only one) wildcard (`::`) may be present, representing a fill
+    //    of 0's. The IPv6 `::` is thus 16 bytes of `0`.
+    //  - The last two parts may be replaced by an IPv4 "dotted-quad" address.
+
+    // Helper function for reporting a badly formatted IPv6 address.
+    void error(String msg, [position]) {
+      throw FormatException('Illegal IPv6 address, $msg', host, position);
+    }
+
+    // Parse a hex block.
+    int parseHex(int start, int end) {
+      if (end - start > 4) {
+        error('an IPv6 part can only contain a maximum of 4 hex digits', start);
+      }
+      int value = int.parse(host.substring(start, end), radix: 16);
+      if (value < 0 || value > 0xFFFF) {
+        error('each part must be in the range of `0x0..0xFFFF`', start);
+      }
+      return value;
+    }
+
+    if (host.length < 2) error('address is too short');
+    List<int> parts = [];
+    bool wildcardSeen = false;
+    // Set if seeing a ".", suggesting that there is an IPv4 address.
+    bool seenDot = false;
+    int partStart = start;
+    // Parse all parts, except a potential last one.
+    for (int i = start; i < end; i++) {
+      int char = host.codeUnitAt(i);
+      if (char == _COLON) {
+        if (i == start) {
+          // If we see a `:` in the beginning, expect wildcard.
+          i++;
+          if (host.codeUnitAt(i) != _COLON) {
+            error('invalid start colon.', i);
+          }
+          partStart = i;
+        }
+        if (i == partStart) {
+          // Wildcard. We only allow one.
+          if (wildcardSeen) {
+            error('only one wildcard `::` is allowed', i);
+          }
+          wildcardSeen = true;
+          parts.add(-1);
+        } else {
+          // Found a single colon. Parse [partStart..i] as a hex entry.
+          parts.add(parseHex(partStart, i));
+        }
+        partStart = i + 1;
+      } else if (char == _DOT) {
+        seenDot = true;
+      }
+    }
+    if (parts.length == 0) error('too few parts');
+    bool atEnd = (partStart == end);
+    bool isLastWildcard = (parts.last == -1);
+    if (atEnd && !isLastWildcard) {
+      error('expected a part after last `:`', end);
+    }
+    if (!atEnd) {
+      if (!seenDot) {
+        parts.add(parseHex(partStart, end));
+      } else {
+        List<int> last = _parseIPv4Address(host, partStart, end);
+        parts.add(last[0] << 8 | last[1]);
+        parts.add(last[2] << 8 | last[3]);
+      }
+    }
+    if (wildcardSeen) {
+      if (parts.length > 7) {
+        error('an address with a wildcard must have less than 7 parts');
+      }
+    } else if (parts.length != 8) {
+      error('an address without a wildcard must contain exactly 8 parts');
+    }
+    List<int> bytes = Uint8List(16);
+    for (int i = 0, index = 0; i < parts.length; i++) {
+      int value = parts[i];
+      if (value == -1) {
+        int wildCardLength = 9 - parts.length;
+        for (int j = 0; j < wildCardLength; j++) {
+          bytes[index] = 0;
+          bytes[index + 1] = 0;
+          index += 2;
+        }
+      } else {
+        bytes[index] = value >> 8;
+        bytes[index + 1] = value & 0xff;
+        index += 2;
+      }
+    }
+    return bytes;
+  }
+}
+
+class _Uri implements Uri {
+  // We represent the missing scheme as an empty string.
+  // A valid scheme cannot be empty.
+  final String scheme;
+
+  /**
+   * The user-info part of the authority.
+   *
+   * Does not distinguish between an empty user-info and an absent one.
+   * The value is always non-null.
+   * Is considered absent if [_host] is `null`.
+   */
+  final String _userInfo;
+
+  /**
+   * The host name of the URI.
+   *
+   * Set to `null` if there is no authority in the URI.
+   * The host name is the only mandatory part of an authority, so we use
+   * it to mark whether an authority part was present or not.
+   */
+  final String _host;
+
+  /**
+   * The port number part of the authority.
+   *
+   * The port. Set to null if there is no port. Normalized to null if
+   * the port is the default port for the scheme.
+   */
+  int _port;
+
+  /**
+   * The path of the URI.
+   *
+   * Always non-null.
+   */
+  final String path;
+
+  // The query content, or null if there is no query.
+  final String _query;
+
+  // The fragment content, or null if there is no fragment.
+  final String _fragment;
+
+  /**
+   * Cache the computed return value of [pathSegments].
+   */
+  List<String> _pathSegments;
+
+  /**
+   * Cache of the full normalized text representation of the URI.
+   */
+  String _text;
+
+  /**
+   * Cache of the hashCode of [_text].
+   *
+   * Is null until computed.
+   */
+  int _hashCodeCache;
+
+  /**
+   * Cache the computed return value of [queryParameters].
+   */
+  Map<String, String> _queryParameters;
+  Map<String, List<String>> _queryParameterLists;
+
+  /// Internal non-verifying constructor. Only call with validated arguments.
+  ///
+  /// The components must be properly normalized.
+  ///
+  /// Use `null` for [_host] if there is no authority. In that case, always
+  /// pass `null` for [_port] and [_userInfo] as well.
+  ///
+  /// Use `null` for [_port], [_userInfo], [_query] and [_fragment] if there is
+  /// component of that type.
+  ///
+  /// The [path] and [scheme] are never empty.
+  _Uri._internal(this.scheme, this._userInfo, this._host, this._port, this.path,
+      this._query, this._fragment);
+
+  /// Create a [_Uri] from parts of [uri].
+  ///
+  /// The parameters specify the start/end of particular components of the URI.
+  /// The [scheme] may contain a string representing a normalized scheme
+  /// component if one has already been discovered.
+  factory _Uri.notSimple(
+      String uri,
+      int start,
+      int end,
+      int schemeEnd,
+      int hostStart,
+      int portStart,
+      int pathStart,
+      int queryStart,
+      int fragmentStart,
+      String scheme) {
+    if (scheme == null) {
+      scheme = "";
+      if (schemeEnd > start) {
+        scheme = _makeScheme(uri, start, schemeEnd);
+      } else if (schemeEnd == start) {
+        _fail(uri, start, "Invalid empty scheme");
+      }
+    }
+    String userInfo = "";
+    String host;
+    int port;
+    if (hostStart > start) {
+      int userInfoStart = schemeEnd + 3;
+      if (userInfoStart < hostStart) {
+        userInfo = _makeUserInfo(uri, userInfoStart, hostStart - 1);
+      }
+      host = _makeHost(uri, hostStart, portStart, false);
+      if (portStart + 1 < pathStart) {
+        // Should throw because invalid.
+        port = int.parse(uri.substring(portStart + 1, pathStart), onError: (_) {
+          throw FormatException("Invalid port", uri, portStart + 1);
+        });
+        port = _makePort(port, scheme);
+      }
+    }
+    String path =
+        _makePath(uri, pathStart, queryStart, null, scheme, host != null);
+    String query;
+    if (queryStart < fragmentStart) {
+      query = _makeQuery(uri, queryStart + 1, fragmentStart, null);
+    }
+    String fragment;
+    if (fragmentStart < end) {
+      fragment = _makeFragment(uri, fragmentStart + 1, end);
+    }
+    return _Uri._internal(scheme, userInfo, host, port, path, query, fragment);
+  }
+
+  /// Implementation of [Uri.Uri].
+  factory _Uri(
+      {String scheme,
+      String userInfo,
+      String host,
+      int port,
+      String path,
+      Iterable<String> pathSegments,
+      String query,
+      Map<String, dynamic /*String|Iterable<String>*/ > queryParameters,
+      String fragment}) {
+    scheme = _makeScheme(scheme, 0, _stringOrNullLength(scheme));
+    userInfo = _makeUserInfo(userInfo, 0, _stringOrNullLength(userInfo));
+    host = _makeHost(host, 0, _stringOrNullLength(host), false);
+    // Special case this constructor for backwards compatibility.
+    if (query == "") query = null;
+    query = _makeQuery(query, 0, _stringOrNullLength(query), queryParameters);
+    fragment = _makeFragment(fragment, 0, _stringOrNullLength(fragment));
+    port = _makePort(port, scheme);
+    bool isFile = (scheme == "file");
+    if (host == null && (userInfo.isNotEmpty || port != null || isFile)) {
+      host = "";
+    }
+    bool hasAuthority = (host != null);
+    path = _makePath(
+        path, 0, _stringOrNullLength(path), pathSegments, scheme, hasAuthority);
+    if (scheme.isEmpty && host == null && !path.startsWith('/')) {
+      bool allowScheme = scheme.isNotEmpty || host != null;
+      path = _normalizeRelativePath(path, allowScheme);
+    } else {
+      path = _removeDotSegments(path);
+    }
+    if (host == null && path.startsWith("//")) {
+      host = "";
+    }
+    return _Uri._internal(scheme, userInfo, host, port, path, query, fragment);
+  }
+
+  /// Implementation of [Uri.http].
+  factory _Uri.http(String authority, String unencodedPath,
+      [Map<String, String> queryParameters]) {
+    return _makeHttpUri("http", authority, unencodedPath, queryParameters);
+  }
+
+  /// Implementation of [Uri.https].
+  factory _Uri.https(String authority, String unencodedPath,
+      [Map<String, String> queryParameters]) {
+    return _makeHttpUri("https", authority, unencodedPath, queryParameters);
+  }
+
+  String get authority {
+    if (!hasAuthority) return "";
+    var sb = StringBuffer();
+    _writeAuthority(sb);
+    return sb.toString();
+  }
+
+  String get userInfo => _userInfo;
+
+  String get host {
+    if (_host == null) return "";
+    if (_host.startsWith('[')) {
+      return _host.substring(1, _host.length - 1);
+    }
+    return _host;
+  }
+
+  int get port {
+    if (_port == null) return _defaultPort(scheme);
+    return _port;
+  }
+
+  // The default port for the scheme of this Uri.
+  static int _defaultPort(String scheme) {
+    if (scheme == "http") return 80;
+    if (scheme == "https") return 443;
+    return 0;
+  }
+
+  String get query => _query ?? "";
+
+  String get fragment => _fragment ?? "";
+
+  bool isScheme(String scheme) {
+    String thisScheme = this.scheme;
+    if (scheme == null) return thisScheme.isEmpty;
+    if (scheme.length != thisScheme.length) return false;
+    return _compareScheme(scheme, thisScheme);
+  }
+
+  /// Compares scheme characters in [scheme] and at the start of [uri].
+  ///
+  /// Returns `true` if [scheme] represents the same scheme as the start of
+  /// [uri]. That means having the same characters, but possibly different case
+  /// for letters.
+  ///
+  /// This function doesn't check that the characters are valid URI scheme
+  /// characters. The [uri] is assumed to be valid, so if [scheme] matches
+  /// it, it has to be valid too.
+  ///
+  /// The length should be tested before calling this function,
+  /// so the scheme part of [uri] is known to have the same length as [scheme].
+  static bool _compareScheme(String scheme, String uri) {
+    for (int i = 0; i < scheme.length; i++) {
+      int schemeChar = scheme.codeUnitAt(i);
+      int uriChar = uri.codeUnitAt(i);
+      int delta = schemeChar ^ uriChar;
+      if (delta != 0) {
+        if (delta == 0x20) {
+          // Might be a case difference.
+          int lowerChar = uriChar | delta;
+          if (0x61 /*a*/ <= lowerChar && lowerChar <= 0x7a /*z*/) {
+            continue;
+          }
+        }
+        return false;
+      }
+    }
+    return true;
+  }
+
+  // Report a parse failure.
+  static void _fail(String uri, int index, String message) {
+    throw FormatException(message, uri, index);
+  }
+
+  static Uri _makeHttpUri(String scheme, String authority, String unencodedPath,
+      Map<String, String> queryParameters) {
+    var userInfo = "";
+    String host;
+    int port;
+
+    if (authority != null && authority.isNotEmpty) {
+      var hostStart = 0;
+      // Split off the user info.
+      bool hasUserInfo = false;
+      for (int i = 0; i < authority.length; i++) {
+        const int atSign = 0x40;
+        if (authority.codeUnitAt(i) == atSign) {
+          hasUserInfo = true;
+          userInfo = authority.substring(0, i);
+          hostStart = i + 1;
+          break;
+        }
+      }
+      var hostEnd = hostStart;
+      if (hostStart < authority.length &&
+          authority.codeUnitAt(hostStart) == _LEFT_BRACKET) {
+        // IPv6 host.
+        int escapeForZoneID = -1;
+        for (; hostEnd < authority.length; hostEnd++) {
+          int char = authority.codeUnitAt(hostEnd);
+          if (char == _PERCENT && escapeForZoneID < 0) {
+            escapeForZoneID = hostEnd;
+            if (authority.startsWith("25", hostEnd + 1)) {
+              hostEnd += 2; // Might as well skip the already checked escape.
+            }
+          } else if (char == _RIGHT_BRACKET) {
+            break;
+          }
+        }
+        if (hostEnd == authority.length) {
+          throw FormatException(
+              "Invalid IPv6 host entry.", authority, hostStart);
+        }
+        Uri.parseIPv6Address(authority, hostStart + 1,
+            (escapeForZoneID < 0) ? hostEnd : escapeForZoneID);
+        hostEnd++; // Skip the closing bracket.
+        if (hostEnd != authority.length &&
+            authority.codeUnitAt(hostEnd) != _COLON) {
+          throw FormatException("Invalid end of authority", authority, hostEnd);
+        }
+      }
+      // Split host and port.
+      bool hasPort = false;
+      for (; hostEnd < authority.length; hostEnd++) {
+        if (authority.codeUnitAt(hostEnd) == _COLON) {
+          var portString = authority.substring(hostEnd + 1);
+          // We allow the empty port - falling back to initial value.
+          if (portString.isNotEmpty) port = int.parse(portString);
+          break;
+        }
+      }
+      host = authority.substring(hostStart, hostEnd);
+    }
+    return Uri(
+        scheme: scheme,
+        userInfo: userInfo,
+        host: host,
+        port: port,
+        pathSegments: unencodedPath.split("/"),
+        queryParameters: queryParameters);
+  }
+
+  /// Implementation of [Uri.file].
+  factory _Uri.file(String path, {bool windows}) {
+    windows = (windows == null) ? _Uri._isWindows : windows;
+    return windows
+        ? _makeWindowsFileUrl(path, false)
+        : _makeFileUri(path, false);
+  }
+
+  /// Implementation of [Uri.directory].
+  factory _Uri.directory(String path, {bool windows}) {
+    windows = (windows == null) ? _Uri._isWindows : windows;
+    return windows ? _makeWindowsFileUrl(path, true) : _makeFileUri(path, true);
+  }
+
+  /// Used internally in path-related constructors.
+  external static bool get _isWindows;
+
+  static _checkNonWindowsPathReservedCharacters(
+      List<String> segments, bool argumentError) {
+    segments.forEach((segment) {
+      if (segment.contains("/")) {
+        if (argumentError) {
+          throw ArgumentError("Illegal path character $segment");
+        } else {
+          throw UnsupportedError("Illegal path character $segment");
+        }
+      }
+    });
+  }
+
+  static _checkWindowsPathReservedCharacters(
+      List<String> segments, bool argumentError,
+      [int firstSegment = 0]) {
+    for (var segment in segments.skip(firstSegment)) {
+      if (segment.contains(RegExp(r'["*/:<>?\\|]'))) {
+        if (argumentError) {
+          throw ArgumentError("Illegal character in path");
+        } else {
+          throw UnsupportedError("Illegal character in path: $segment");
+        }
+      }
+    }
+  }
+
+  static _checkWindowsDriveLetter(int charCode, bool argumentError) {
+    if ((_UPPER_CASE_A <= charCode && charCode <= _UPPER_CASE_Z) ||
+        (_LOWER_CASE_A <= charCode && charCode <= _LOWER_CASE_Z)) {
+      return;
+    }
+    if (argumentError) {
+      throw ArgumentError(
+          "Illegal drive letter " + String.fromCharCode(charCode));
+    } else {
+      throw UnsupportedError(
+          "Illegal drive letter " + String.fromCharCode(charCode));
+    }
+  }
+
+  static _makeFileUri(String path, bool slashTerminated) {
+    const String sep = "/";
+    var segments = path.split(sep);
+    if (slashTerminated && segments.isNotEmpty && segments.last.isNotEmpty) {
+      segments.add(""); // Extra separator at end.
+    }
+    if (path.startsWith(sep)) {
+      // Absolute file:// URI.
+      return Uri(scheme: "file", pathSegments: segments);
+    } else {
+      // Relative URI.
+      return Uri(pathSegments: segments);
+    }
+  }
+
+  static _makeWindowsFileUrl(String path, bool slashTerminated) {
+    if (path.startsWith(r"\\?\")) {
+      if (path.startsWith(r"UNC\", 4)) {
+        path = path.replaceRange(0, 7, r'\');
+      } else {
+        path = path.substring(4);
+        if (path.length < 3 ||
+            path.codeUnitAt(1) != _COLON ||
+            path.codeUnitAt(2) != _BACKSLASH) {
+          throw ArgumentError(
+              r"Windows paths with \\?\ prefix must be absolute");
+        }
+      }
+    } else {
+      path = path.replaceAll("/", r'\');
+    }
+    const String sep = r'\';
+    if (path.length > 1 && path.codeUnitAt(1) == _COLON) {
+      _checkWindowsDriveLetter(path.codeUnitAt(0), true);
+      if (path.length == 2 || path.codeUnitAt(2) != _BACKSLASH) {
+        throw ArgumentError("Windows paths with drive letter must be absolute");
+      }
+      // Absolute file://C:/ URI.
+      var pathSegments = path.split(sep);
+      if (slashTerminated && pathSegments.last.isNotEmpty) {
+        pathSegments.add(""); // Extra separator at end.
+      }
+      _checkWindowsPathReservedCharacters(pathSegments, true, 1);
+      return Uri(scheme: "file", pathSegments: pathSegments);
+    }
+
+    if (path.startsWith(sep)) {
+      if (path.startsWith(sep, 1)) {
+        // Absolute file:// URI with host.
+        int pathStart = path.indexOf(r'\', 2);
+        String hostPart =
+            (pathStart < 0) ? path.substring(2) : path.substring(2, pathStart);
+        String pathPart = (pathStart < 0) ? "" : path.substring(pathStart + 1);
+        var pathSegments = pathPart.split(sep);
+        _checkWindowsPathReservedCharacters(pathSegments, true);
+        if (slashTerminated && pathSegments.last.isNotEmpty) {
+          pathSegments.add(""); // Extra separator at end.
+        }
+        return Uri(scheme: "file", host: hostPart, pathSegments: pathSegments);
+      } else {
+        // Absolute file:// URI.
+        var pathSegments = path.split(sep);
+        if (slashTerminated && pathSegments.last.isNotEmpty) {
+          pathSegments.add(""); // Extra separator at end.
+        }
+        _checkWindowsPathReservedCharacters(pathSegments, true);
+        return Uri(scheme: "file", pathSegments: pathSegments);
+      }
+    } else {
+      // Relative URI.
+      var pathSegments = path.split(sep);
+      _checkWindowsPathReservedCharacters(pathSegments, true);
+      if (slashTerminated &&
+          pathSegments.isNotEmpty &&
+          pathSegments.last.isNotEmpty) {
+        pathSegments.add(""); // Extra separator at end.
+      }
+      return Uri(pathSegments: pathSegments);
+    }
+  }
+
+  Uri replace(
+      {String scheme,
+      String userInfo,
+      String host,
+      int port,
+      String path,
+      Iterable<String> pathSegments,
+      String query,
+      Map<String, dynamic /*String|Iterable<String>*/ > queryParameters,
+      String fragment}) {
+    // Set to true if the scheme has (potentially) changed.
+    // In that case, the default port may also have changed and we need
+    // to check even the existing port.
+    bool schemeChanged = false;
+    if (scheme != null) {
+      scheme = _makeScheme(scheme, 0, scheme.length);
+      schemeChanged = (scheme != this.scheme);
+    } else {
+      scheme = this.scheme;
+    }
+    bool isFile = (scheme == "file");
+    if (userInfo != null) {
+      userInfo = _makeUserInfo(userInfo, 0, userInfo.length);
+    } else {
+      userInfo = this._userInfo;
+    }
+    if (port != null) {
+      port = _makePort(port, scheme);
+    } else {
+      port = this._port;
+      if (schemeChanged) {
+        // The default port might have changed.
+        port = _makePort(port, scheme);
+      }
+    }
+    if (host != null) {
+      host = _makeHost(host, 0, host.length, false);
+    } else if (this.hasAuthority) {
+      host = this._host;
+    } else if (userInfo.isNotEmpty || port != null || isFile) {
+      host = "";
+    }
+
+    bool hasAuthority = host != null;
+    if (path != null || pathSegments != null) {
+      path = _makePath(path, 0, _stringOrNullLength(path), pathSegments, scheme,
+          hasAuthority);
+    } else {
+      path = this.path;
+      if ((isFile || (hasAuthority && !path.isEmpty)) &&
+          !path.startsWith('/')) {
+        path = "/" + path;
+      }
+    }
+
+    if (query != null || queryParameters != null) {
+      query = _makeQuery(query, 0, _stringOrNullLength(query), queryParameters);
+    } else {
+      query = this._query;
+    }
+
+    if (fragment != null) {
+      fragment = _makeFragment(fragment, 0, fragment.length);
+    } else {
+      fragment = this._fragment;
+    }
+
+    return _Uri._internal(scheme, userInfo, host, port, path, query, fragment);
+  }
+
+  Uri removeFragment() {
+    if (!this.hasFragment) return this;
+    return _Uri._internal(scheme, _userInfo, _host, _port, path, _query, null);
+  }
+
+  List<String> get pathSegments {
+    var result = _pathSegments;
+    if (result != null) return result;
+
+    var pathToSplit = path;
+    if (pathToSplit.isNotEmpty && pathToSplit.codeUnitAt(0) == _SLASH) {
+      pathToSplit = pathToSplit.substring(1);
+    }
+    result = (pathToSplit == "")
+        ? const <String>[]
+        : List<String>.unmodifiable(
+            pathToSplit.split("/").map(Uri.decodeComponent));
+    _pathSegments = result;
+    return result;
+  }
+
+  Map<String, String> get queryParameters {
+    _queryParameters ??=
+        UnmodifiableMapView<String, String>(Uri.splitQueryString(query));
+    return _queryParameters;
+  }
+
+  Map<String, List<String>> get queryParametersAll {
+    if (_queryParameterLists == null) {
+      Map queryParameterLists = _splitQueryStringAll(query);
+      for (var key in queryParameterLists.keys) {
+        queryParameterLists[key] =
+            List<String>.unmodifiable(queryParameterLists[key]);
+      }
+      _queryParameterLists =
+          Map<String, List<String>>.unmodifiable(queryParameterLists);
+    }
+    return _queryParameterLists;
+  }
+
+  Uri normalizePath() {
+    String path = _normalizePath(this.path, scheme, hasAuthority);
+    if (identical(path, this.path)) return this;
+    return this.replace(path: path);
+  }
+
+  static int _makePort(int port, String scheme) {
+    // Perform scheme specific normalization.
+    if (port != null && port == _defaultPort(scheme)) return null;
+    return port;
+  }
+
+  /**
+   * Check and normalize a host name.
+   *
+   * If the host name starts and ends with '[' and ']', it is considered an
+   * IPv6 address. If [strictIPv6] is false, the address is also considered
+   * an IPv6 address if it contains any ':' character.
+   *
+   * If it is not an IPv6 address, it is case- and escape-normalized.
+   * This escapes all characters not valid in a reg-name,
+   * and converts all non-escape upper-case letters to lower-case.
+   */
+  static String _makeHost(String host, int start, int end, bool strictIPv6) {
+    // TODO(lrn): Should we normalize IPv6 addresses according to RFC 5952?
+    if (host == null) return null;
+    if (start == end) return "";
+    // Host is an IPv6 address if it starts with '[' or contains a colon.
+    if (host.codeUnitAt(start) == _LEFT_BRACKET) {
+      if (host.codeUnitAt(end - 1) != _RIGHT_BRACKET) {
+        _fail(host, start, 'Missing end `]` to match `[` in host');
+      }
+      String zoneID = "";
+      int index = _checkZoneID(host, start + 1, end - 1);
+      if (index < end - 1) {
+        int zoneIDstart =
+            (host.startsWith("25", index + 1)) ? index + 3 : index + 1;
+        zoneID = _normalizeZoneID(host, zoneIDstart, end - 1, "%25");
+      }
+      Uri.parseIPv6Address(host, start + 1, index);
+      // RFC 5952 requires hex digits to be lower case.
+      return host.substring(start, index).toLowerCase() + zoneID + ']';
+    }
+    if (!strictIPv6) {
+      // TODO(lrn): skip if too short to be a valid IPv6 address?
+      for (int i = start; i < end; i++) {
+        if (host.codeUnitAt(i) == _COLON) {
+          String zoneID = "";
+          int index = _checkZoneID(host, start, end);
+          if (index < end) {
+            int zoneIDstart =
+                (host.startsWith("25", index + 1)) ? index + 3 : index + 1;
+            zoneID = _normalizeZoneID(host, zoneIDstart, end, "%25");
+          }
+          Uri.parseIPv6Address(host, start, index);
+          return '[${host.substring(start, index)}' + zoneID + ']';
+        }
+      }
+    }
+    return _normalizeRegName(host, start, end);
+  }
+
+  // RFC 6874 check for ZoneID
+  // Return the index of first appeared `%`.
+  static int _checkZoneID(String host, int start, int end) {
+    int index = host.indexOf('%', start);
+    index = (index >= start && index < end) ? index : end;
+    return index;
+  }
+
+  static bool _isZoneIDChar(int char) {
+    return char < 127 && (_zoneIDTable[char >> 4] & (1 << (char & 0xf))) != 0;
+  }
+
+  /**
+   * Validates and does case- and percent-encoding normalization.
+   *
+   * The same as [_normalizeOrSubstring]
+   * except this function does not convert characters to lower case.
+   * The [host] must be an RFC6874 "ZoneID".
+   * ZoneID = 1*(unreserved / pct-encoded)
+   */
+  static String _normalizeZoneID(String host, int start, int end,
+      [String prefix = '']) {
+    StringBuffer buffer;
+    if (prefix != '') {
+      buffer = StringBuffer(prefix);
+    }
+    int sectionStart = start;
+    int index = start;
+    // Whether all characters between sectionStart and index are normalized,
+    bool isNormalized = true;
+
+    while (index < end) {
+      int char = host.codeUnitAt(index);
+      if (char == _PERCENT) {
+        String replacement = _normalizeEscape(host, index, true);
+        if (replacement == null && isNormalized) {
+          index += 3;
+          continue;
+        }
+        buffer ??= StringBuffer();
+        String slice = host.substring(sectionStart, index);
+        buffer.write(slice);
+        int sourceLength = 3;
+        if (replacement == null) {
+          replacement = host.substring(index, index + 3);
+        } else if (replacement == "%") {
+          _fail(host, index, "ZoneID should not contain % anymore");
+        }
+        buffer.write(replacement);
+        index += sourceLength;
+        sectionStart = index;
+        isNormalized = true;
+      } else if (_isZoneIDChar(char)) {
+        if (isNormalized && _UPPER_CASE_A <= char && _UPPER_CASE_Z >= char) {
+          // Put initial slice in buffer and continue in non-normalized mode
+          buffer ??= StringBuffer();
+          if (sectionStart < index) {
+            buffer.write(host.substring(sectionStart, index));
+            sectionStart = index;
+          }
+          isNormalized = false;
+        }
+        index++;
+      } else {
+        int sourceLength = 1;
+        if ((char & 0xFC00) == 0xD800 && (index + 1) < end) {
+          int tail = host.codeUnitAt(index + 1);
+          if ((tail & 0xFC00) == 0xDC00) {
+            char = 0x10000 | ((char & 0x3ff) << 10) | (tail & 0x3ff);
+            sourceLength = 2;
+          }
+        }
+        buffer ??= StringBuffer();
+        String slice = host.substring(sectionStart, index);
+        buffer.write(slice);
+        buffer.write(_escapeChar(char));
+        index += sourceLength;
+        sectionStart = index;
+      }
+    }
+    if (buffer == null) return host.substring(start, end);
+    if (sectionStart < end) {
+      String slice = host.substring(sectionStart, end);
+      buffer.write(slice);
+    }
+    return buffer.toString();
+  }
+
+  static bool _isRegNameChar(int char) {
+    return char < 127 && (_regNameTable[char >> 4] & (1 << (char & 0xf))) != 0;
+  }
+
+  /**
+   * Validates and does case- and percent-encoding normalization.
+   *
+   * The [host] must be an RFC3986 "reg-name". It is converted
+   * to lower case, and percent escapes are converted to either
+   * lower case unreserved characters or upper case escapes.
+   */
+  static String _normalizeRegName(String host, int start, int end) {
+    StringBuffer buffer;
+    int sectionStart = start;
+    int index = start;
+    // Whether all characters between sectionStart and index are normalized,
+    bool isNormalized = true;
+
+    while (index < end) {
+      int char = host.codeUnitAt(index);
+      if (char == _PERCENT) {
+        // The _regNameTable contains "%", so we check that first.
+        String replacement = _normalizeEscape(host, index, true);
+        if (replacement == null && isNormalized) {
+          index += 3;
+          continue;
+        }
+        buffer ??= StringBuffer();
+        String slice = host.substring(sectionStart, index);
+        if (!isNormalized) slice = slice.toLowerCase();
+        buffer.write(slice);
+        int sourceLength = 3;
+        if (replacement == null) {
+          replacement = host.substring(index, index + 3);
+        } else if (replacement == "%") {
+          replacement = "%25";
+          sourceLength = 1;
+        }
+        buffer.write(replacement);
+        index += sourceLength;
+        sectionStart = index;
+        isNormalized = true;
+      } else if (_isRegNameChar(char)) {
+        if (isNormalized && _UPPER_CASE_A <= char && _UPPER_CASE_Z >= char) {
+          // Put initial slice in buffer and continue in non-normalized mode
+          buffer ??= StringBuffer();
+          if (sectionStart < index) {
+            buffer.write(host.substring(sectionStart, index));
+            sectionStart = index;
+          }
+          isNormalized = false;
+        }
+        index++;
+      } else if (_isGeneralDelimiter(char)) {
+        _fail(host, index, "Invalid character");
+      } else {
+        int sourceLength = 1;
+        if ((char & 0xFC00) == 0xD800 && (index + 1) < end) {
+          int tail = host.codeUnitAt(index + 1);
+          if ((tail & 0xFC00) == 0xDC00) {
+            char = 0x10000 | ((char & 0x3ff) << 10) | (tail & 0x3ff);
+            sourceLength = 2;
+          }
+        }
+        buffer ??= StringBuffer();
+        String slice = host.substring(sectionStart, index);
+        if (!isNormalized) slice = slice.toLowerCase();
+        buffer.write(slice);
+        buffer.write(_escapeChar(char));
+        index += sourceLength;
+        sectionStart = index;
+      }
+    }
+    if (buffer == null) return host.substring(start, end);
+    if (sectionStart < end) {
+      String slice = host.substring(sectionStart, end);
+      if (!isNormalized) slice = slice.toLowerCase();
+      buffer.write(slice);
+    }
+    return buffer.toString();
+  }
+
+  /**
+   * Validates scheme characters and does case-normalization.
+   *
+   * Schemes are converted to lower case. They cannot contain escapes.
+   */
+  static String _makeScheme(String scheme, int start, int end) {
+    if (start == end) return "";
+    final int firstCodeUnit = scheme.codeUnitAt(start);
+    if (!_isAlphabeticCharacter(firstCodeUnit)) {
+      _fail(scheme, start, "Scheme not starting with alphabetic character");
+    }
+    bool containsUpperCase = false;
+    for (int i = start; i < end; i++) {
+      final int codeUnit = scheme.codeUnitAt(i);
+      if (!_isSchemeCharacter(codeUnit)) {
+        _fail(scheme, i, "Illegal scheme character");
+      }
+      if (_UPPER_CASE_A <= codeUnit && codeUnit <= _UPPER_CASE_Z) {
+        containsUpperCase = true;
+      }
+    }
+    scheme = scheme.substring(start, end);
+    if (containsUpperCase) scheme = scheme.toLowerCase();
+    return _canonicalizeScheme(scheme);
+  }
+
+  // Canonicalize a few often-used scheme strings.
+  //
+  // This improves memory usage and makes comparison faster.
+  static String _canonicalizeScheme(String scheme) {
+    if (scheme == "http") return "http";
+    if (scheme == "file") return "file";
+    if (scheme == "https") return "https";
+    if (scheme == "package") return "package";
+    return scheme;
+  }
+
+  static String _makeUserInfo(String userInfo, int start, int end) {
+    if (userInfo == null) return "";
+    return _normalizeOrSubstring(userInfo, start, end, _userinfoTable);
+  }
+
+  static String _makePath(String path, int start, int end,
+      Iterable<String> pathSegments, String scheme, bool hasAuthority) {
+    bool isFile = (scheme == "file");
+    bool ensureLeadingSlash = isFile || hasAuthority;
+    if (path == null && pathSegments == null) return isFile ? "/" : "";
+    if (path != null && pathSegments != null) {
+      throw ArgumentError('Both path and pathSegments specified');
+    }
+    String result;
+    if (path != null) {
+      result = _normalizeOrSubstring(path, start, end, _pathCharOrSlashTable,
+          escapeDelimiters: true);
+    } else {
+      result = pathSegments
+          .map((s) => _uriEncode(_pathCharTable, s, utf8, false))
+          .join("/");
+    }
+    if (result.isEmpty) {
+      if (isFile) return "/";
+    } else if (ensureLeadingSlash && !result.startsWith('/')) {
+      result = "/" + result;
+    }
+    result = _normalizePath(result, scheme, hasAuthority);
+    return result;
+  }
+
+  /// Performs path normalization (remove dot segments) on a path.
+  ///
+  /// If the URI has neither scheme nor authority, it's considered a
+  /// "pure path" and normalization won't remove leading ".." segments.
+  /// Otherwise it follows the RFC 3986 "remove dot segments" algorithm.
+  static String _normalizePath(String path, String scheme, bool hasAuthority) {
+    if (scheme.isEmpty && !hasAuthority && !path.startsWith('/')) {
+      return _normalizeRelativePath(path, scheme.isNotEmpty || hasAuthority);
+    }
+    return _removeDotSegments(path);
+  }
+
+  static String _makeQuery(String query, int start, int end,
+      Map<String, dynamic /*String|Iterable<String>*/ > queryParameters) {
+    if (query != null) {
+      if (queryParameters != null) {
+        throw ArgumentError('Both query and queryParameters specified');
+      }
+      return _normalizeOrSubstring(query, start, end, _queryCharTable,
+          escapeDelimiters: true);
+    }
+    if (queryParameters == null) return null;
+
+    var result = StringBuffer();
+    var separator = "";
+
+    void writeParameter(String key, String value) {
+      result.write(separator);
+      separator = "&";
+      result.write(Uri.encodeQueryComponent(key));
+      if (value != null && value.isNotEmpty) {
+        result.write("=");
+        result.write(Uri.encodeQueryComponent(value));
+      }
+    }
+
+    queryParameters.forEach((key, value) {
+      if (value == null || value is String) {
+        writeParameter(key, value);
+      } else {
+        Iterable values = value;
+        for (String value in values) {
+          writeParameter(key, value);
+        }
+      }
+    });
+    return result.toString();
+  }
+
+  static String _makeFragment(String fragment, int start, int end) {
+    if (fragment == null) return null;
+    return _normalizeOrSubstring(fragment, start, end, _queryCharTable,
+        escapeDelimiters: true);
+  }
+
+  /**
+   * Performs RFC 3986 Percent-Encoding Normalization.
+   *
+   * Returns a replacement string that should be replace the original escape.
+   * Returns null if no replacement is necessary because the escape is
+   * not for an unreserved character and is already non-lower-case.
+   *
+   * Returns "%" if the escape is invalid (not two valid hex digits following
+   * the percent sign). The calling code should replace the percent
+   * sign with "%25", but leave the following two characters unmodified.
+   *
+   * If [lowerCase] is true, a single character returned is always lower case,
+   */
+  static String _normalizeEscape(String source, int index, bool lowerCase) {
+    assert(source.codeUnitAt(index) == _PERCENT);
+    if (index + 2 >= source.length) {
+      return "%"; // Marks the escape as invalid.
+    }
+    int firstDigit = source.codeUnitAt(index + 1);
+    int secondDigit = source.codeUnitAt(index + 2);
+    int firstDigitValue = hexDigitValue(firstDigit);
+    int secondDigitValue = hexDigitValue(secondDigit);
+    if (firstDigitValue < 0 || secondDigitValue < 0) {
+      return "%"; // Marks the escape as invalid.
+    }
+    int value = firstDigitValue * 16 + secondDigitValue;
+    if (_isUnreservedChar(value)) {
+      if (lowerCase && _UPPER_CASE_A <= value && _UPPER_CASE_Z >= value) {
+        value |= 0x20;
+      }
+      return String.fromCharCode(value);
+    }
+    if (firstDigit >= _LOWER_CASE_A || secondDigit >= _LOWER_CASE_A) {
+      // Either digit is lower case.
+      return source.substring(index, index + 3).toUpperCase();
+    }
+    // Escape is retained, and is already non-lower case, so return null to
+    // represent "no replacement necessary".
+    return null;
+  }
+
+  static String _escapeChar(int char) {
+    assert(char <= 0x10ffff); // It's a valid unicode code point.
+    List<int> codeUnits;
+    if (char < 0x80) {
+      // ASCII, a single percent encoded sequence.
+      codeUnits = List(3);
+      codeUnits[0] = _PERCENT;
+      codeUnits[1] = _hexDigits.codeUnitAt(char >> 4);
+      codeUnits[2] = _hexDigits.codeUnitAt(char & 0xf);
+    } else {
+      // Do UTF-8 encoding of character, then percent encode bytes.
+      int flag = 0xc0; // The high-bit markers on the first byte of UTF-8.
+      int encodedBytes = 2;
+      if (char > 0x7ff) {
+        flag = 0xe0;
+        encodedBytes = 3;
+        if (char > 0xffff) {
+          encodedBytes = 4;
+          flag = 0xf0;
+        }
+      }
+      codeUnits = List(3 * encodedBytes);
+      int index = 0;
+      while (--encodedBytes >= 0) {
+        int byte = ((char >> (6 * encodedBytes)) & 0x3f) | flag;
+        codeUnits[index] = _PERCENT;
+        codeUnits[index + 1] = _hexDigits.codeUnitAt(byte >> 4);
+        codeUnits[index + 2] = _hexDigits.codeUnitAt(byte & 0xf);
+        index += 3;
+        flag = 0x80; // Following bytes have only high bit set.
+      }
+    }
+    return String.fromCharCodes(codeUnits);
+  }
+
+  /**
+   * Normalizes using [_normalize] or returns substring of original.
+   *
+   * If [_normalize] returns `null` (original content is already normalized),
+   * this methods returns the substring if [component] from [start] to [end].
+   */
+  static String _normalizeOrSubstring(
+      String component, int start, int end, List<int> charTable,
+      {bool escapeDelimiters = false}) {
+    return _normalize(component, start, end, charTable,
+            escapeDelimiters: escapeDelimiters) ??
+        component.substring(start, end);
+  }
+
+  /**
+   * Runs through component checking that each character is valid and
+   * normalize percent escapes.
+   *
+   * Uses [charTable] to check if a non-`%` character is allowed.
+   * Each `%` character must be followed by two hex digits.
+   * If the hex-digits are lower case letters, they are converted to
+   * upper case.
+   *
+   * Returns `null` if the original content was already normalized.
+   */
+  static String _normalize(
+      String component, int start, int end, List<int> charTable,
+      {bool escapeDelimiters = false}) {
+    StringBuffer buffer;
+    int sectionStart = start;
+    int index = start;
+    // Loop while characters are valid and escapes correct and upper-case.
+    while (index < end) {
+      int char = component.codeUnitAt(index);
+      if (char < 127 && (charTable[char >> 4] & (1 << (char & 0x0f))) != 0) {
+        index++;
+      } else {
+        String replacement;
+        int sourceLength;
+        if (char == _PERCENT) {
+          replacement = _normalizeEscape(component, index, false);
+          // Returns null if we should keep the existing escape.
+          if (replacement == null) {
+            index += 3;
+            continue;
+          }
+          // Returns "%" if we should escape the existing percent.
+          if ("%" == replacement) {
+            replacement = "%25";
+            sourceLength = 1;
+          } else {
+            sourceLength = 3;
+          }
+        } else if (!escapeDelimiters && _isGeneralDelimiter(char)) {
+          _fail(component, index, "Invalid character");
+        } else {
+          sourceLength = 1;
+          if ((char & 0xFC00) == 0xD800) {
+            // Possible lead surrogate.
+            if (index + 1 < end) {
+              int tail = component.codeUnitAt(index + 1);
+              if ((tail & 0xFC00) == 0xDC00) {
+                // Tail surrogate.
+                sourceLength = 2;
+                char = 0x10000 | ((char & 0x3ff) << 10) | (tail & 0x3ff);
+              }
+            }
+          }
+          replacement = _escapeChar(char);
+        }
+        buffer ??= StringBuffer();
+        buffer.write(component.substring(sectionStart, index));
+        buffer.write(replacement);
+        index += sourceLength;
+        sectionStart = index;
+      }
+    }
+    if (buffer == null) {
+      return null;
+    }
+    if (sectionStart < end) {
+      buffer.write(component.substring(sectionStart, end));
+    }
+    return buffer.toString();
+  }
+
+  static bool _isSchemeCharacter(int ch) {
+    return ch < 128 && ((_schemeTable[ch >> 4] & (1 << (ch & 0x0f))) != 0);
+  }
+
+  static bool _isGeneralDelimiter(int ch) {
+    return ch <= _RIGHT_BRACKET &&
+        ((_genDelimitersTable[ch >> 4] & (1 << (ch & 0x0f))) != 0);
+  }
+
+  /**
+   * Returns whether the URI is absolute.
+   */
+  bool get isAbsolute => scheme != "" && fragment == "";
+
+  String _mergePaths(String base, String reference) {
+    // Optimize for the case: absolute base, reference beginning with "../".
+    int backCount = 0;
+    int refStart = 0;
+    // Count number of "../" at beginning of reference.
+    while (reference.startsWith("../", refStart)) {
+      refStart += 3;
+      backCount++;
+    }
+
+    // Drop last segment - everything after last '/' of base.
+    int baseEnd = base.lastIndexOf('/');
+    // Drop extra segments for each leading "../" of reference.
+    while (baseEnd > 0 && backCount > 0) {
+      int newEnd = base.lastIndexOf('/', baseEnd - 1);
+      if (newEnd < 0) {
+        break;
+      }
+      int delta = baseEnd - newEnd;
+      // If we see a "." or ".." segment in base, stop here and let
+      // _removeDotSegments handle it.
+      if ((delta == 2 || delta == 3) &&
+          base.codeUnitAt(newEnd + 1) == _DOT &&
+          (delta == 2 || base.codeUnitAt(newEnd + 2) == _DOT)) {
+        break;
+      }
+      baseEnd = newEnd;
+      backCount--;
+    }
+    return base.replaceRange(
+        baseEnd + 1, null, reference.substring(refStart - 3 * backCount));
+  }
+
+  /// Make a guess at whether a path contains a `..` or `.` segment.
+  ///
+  /// This is a primitive test that can cause false positives.
+  /// It's only used to avoid a more expensive operation in the case where
+  /// it's not necessary.
+  static bool _mayContainDotSegments(String path) {
+    if (path.startsWith('.')) return true;
+    int index = path.indexOf("/.");
+    return index != -1;
+  }
+
+  /// Removes '.' and '..' segments from a path.
+  ///
+  /// Follows the RFC 2986 "remove dot segments" algorithm.
+  /// This algorithm is only used on paths of URIs with a scheme,
+  /// and it treats the path as if it is absolute (leading '..' are removed).
+  static String _removeDotSegments(String path) {
+    if (!_mayContainDotSegments(path)) return path;
+    assert(path.isNotEmpty); // An empty path would not have dot segments.
+    List<String> output = [];
+    bool appendSlash = false;
+    for (String segment in path.split("/")) {
+      appendSlash = false;
+      if (segment == "..") {
+        if (output.isNotEmpty) {
+          output.removeLast();
+          if (output.isEmpty) {
+            output.add("");
+          }
+        }
+        appendSlash = true;
+      } else if ("." == segment) {
+        appendSlash = true;
+      } else {
+        output.add(segment);
+      }
+    }
+    if (appendSlash) output.add("");
+    return output.join("/");
+  }
+
+  /// Removes all `.` segments and any non-leading `..` segments.
+  ///
+  /// If the path starts with something that looks like a scheme,
+  /// and [allowScheme] is false, the colon is escaped.
+  ///
+  /// Removing the ".." from a "bar/foo/.." sequence results in "bar/"
+  /// (trailing "/"). If the entire path is removed (because it contains as
+  /// many ".." segments as real segments), the result is "./".
+  /// This is different from an empty string, which represents "no path",
+  /// when you resolve it against a base URI with a path with a non-empty
+  /// final segment.
+  static String _normalizeRelativePath(String path, bool allowScheme) {
+    assert(!path.startsWith('/')); // Only get called for relative paths.
+    if (!_mayContainDotSegments(path)) {
+      if (!allowScheme) path = _escapeScheme(path);
+      return path;
+    }
+    assert(path.isNotEmpty); // An empty path would not have dot segments.
+    List<String> output = [];
+    bool appendSlash = false;
+    for (String segment in path.split("/")) {
+      appendSlash = false;
+      if (".." == segment) {
+        if (!output.isEmpty && output.last != "..") {
+          output.removeLast();
+          appendSlash = true;
+        } else {
+          output.add("..");
+        }
+      } else if ("." == segment) {
+        appendSlash = true;
+      } else {
+        output.add(segment);
+      }
+    }
+    if (output.isEmpty || (output.length == 1 && output[0].isEmpty)) {
+      return "./";
+    }
+    if (appendSlash || output.last == '..') output.add("");
+    if (!allowScheme) output[0] = _escapeScheme(output[0]);
+    return output.join("/");
+  }
+
+  /// If [path] starts with a valid scheme, escape the percent.
+  static String _escapeScheme(String path) {
+    if (path.length >= 2 && _isAlphabeticCharacter(path.codeUnitAt(0))) {
+      for (int i = 1; i < path.length; i++) {
+        int char = path.codeUnitAt(i);
+        if (char == _COLON) {
+          return "${path.substring(0, i)}%3A${path.substring(i + 1)}";
+        }
+        if (char > 127 ||
+            ((_schemeTable[char >> 4] & (1 << (char & 0x0f))) == 0)) {
+          break;
+        }
+      }
+    }
+    return path;
+  }
+
+  Uri resolve(String reference) {
+    return resolveUri(Uri.parse(reference));
+  }
+
+  Uri resolveUri(Uri reference) {
+    // From RFC 3986.
+    String targetScheme;
+    String targetUserInfo = "";
+    String targetHost;
+    int targetPort;
+    String targetPath;
+    String targetQuery;
+    if (reference.scheme.isNotEmpty) {
+      targetScheme = reference.scheme;
+      if (reference.hasAuthority) {
+        targetUserInfo = reference.userInfo;
+        targetHost = reference.host;
+        targetPort = reference.hasPort ? reference.port : null;
+      }
+      targetPath = _removeDotSegments(reference.path);
+      if (reference.hasQuery) {
+        targetQuery = reference.query;
+      }
+    } else {
+      targetScheme = this.scheme;
+      if (reference.hasAuthority) {
+        targetUserInfo = reference.userInfo;
+        targetHost = reference.host;
+        targetPort =
+            _makePort(reference.hasPort ? reference.port : null, targetScheme);
+        targetPath = _removeDotSegments(reference.path);
+        if (reference.hasQuery) targetQuery = reference.query;
+      } else {
+        targetUserInfo = this._userInfo;
+        targetHost = this._host;
+        targetPort = this._port;
+        if (reference.path == "") {
+          targetPath = this.path;
+          if (reference.hasQuery) {
+            targetQuery = reference.query;
+          } else {
+            targetQuery = this._query;
+          }
+        } else {
+          if (reference.hasAbsolutePath) {
+            targetPath = _removeDotSegments(reference.path);
+          } else {
+            // This is the RFC 3986 behavior for merging.
+            if (this.hasEmptyPath) {
+              if (!this.hasAuthority) {
+                if (!this.hasScheme) {
+                  // Keep the path relative if no scheme or authority.
+                  targetPath = reference.path;
+                } else {
+                  // Remove leading dot-segments if the path is put
+                  // beneath a scheme.
+                  targetPath = _removeDotSegments(reference.path);
+                }
+              } else {
+                // RFC algorithm for base with authority and empty path.
+                targetPath = _removeDotSegments("/" + reference.path);
+              }
+            } else {
+              var mergedPath = _mergePaths(this.path, reference.path);
+              if (this.hasScheme || this.hasAuthority || this.hasAbsolutePath) {
+                targetPath = _removeDotSegments(mergedPath);
+              } else {
+                // Non-RFC 3986 behavior.
+                // If both base and reference are relative paths,
+                // allow the merged path to start with "..".
+                // The RFC only specifies the case where the base has a scheme.
+                targetPath = _normalizeRelativePath(
+                    mergedPath, this.hasScheme || this.hasAuthority);
+              }
+            }
+          }
+          if (reference.hasQuery) targetQuery = reference.query;
+        }
+      }
+    }
+    String fragment = reference.hasFragment ? reference.fragment : null;
+    return _Uri._internal(targetScheme, targetUserInfo, targetHost, targetPort,
+        targetPath, targetQuery, fragment);
+  }
+
+  bool get hasScheme => scheme.isNotEmpty;
+
+  bool get hasAuthority => _host != null;
+
+  bool get hasPort => _port != null;
+
+  bool get hasQuery => _query != null;
+
+  bool get hasFragment => _fragment != null;
+
+  bool get hasEmptyPath => path.isEmpty;
+
+  bool get hasAbsolutePath => path.startsWith('/');
+
+  String get origin {
+    if (scheme == "") {
+      throw StateError("Cannot use origin without a scheme: $this");
+    }
+    if (scheme != "http" && scheme != "https") {
+      throw StateError(
+          "Origin is only applicable schemes http and https: $this");
+    }
+    if (_host == null || _host == "") {
+      throw StateError(
+          "A $scheme: URI should have a non-empty host name: $this");
+    }
+    if (_port == null) return "$scheme://$_host";
+    return "$scheme://$_host:$_port";
+  }
+
+  String toFilePath({bool windows}) {
+    if (scheme != "" && scheme != "file") {
+      throw UnsupportedError("Cannot extract a file path from a $scheme URI");
+    }
+    if (query != "") {
+      throw UnsupportedError(
+          "Cannot extract a file path from a URI with a query component");
+    }
+    if (fragment != "") {
+      throw UnsupportedError(
+          "Cannot extract a file path from a URI with a fragment component");
+    }
+    windows ??= _isWindows;
+    return windows ? _toWindowsFilePath(this) : _toFilePath();
+  }
+
+  String _toFilePath() {
+    if (hasAuthority && host != "") {
+      throw UnsupportedError(
+          "Cannot extract a non-Windows file path from a file URI "
+          "with an authority");
+    }
+    // Use path segments to have any escapes unescaped.
+    var pathSegments = this.pathSegments;
+    _checkNonWindowsPathReservedCharacters(pathSegments, false);
+    var result = StringBuffer();
+    if (hasAbsolutePath) result.write("/");
+    result.writeAll(pathSegments, "/");
+    return result.toString();
+  }
+
+  static String _toWindowsFilePath(Uri uri) {
+    bool hasDriveLetter = false;
+    var segments = uri.pathSegments;
+    if (segments.length > 0 &&
+        segments[0].length == 2 &&
+        segments[0].codeUnitAt(1) == _COLON) {
+      _checkWindowsDriveLetter(segments[0].codeUnitAt(0), false);
+      _checkWindowsPathReservedCharacters(segments, false, 1);
+      hasDriveLetter = true;
+    } else {
+      _checkWindowsPathReservedCharacters(segments, false, 0);
+    }
+    var result = StringBuffer();
+    if (uri.hasAbsolutePath && !hasDriveLetter) result.write(r"\");
+    if (uri.hasAuthority) {
+      var host = uri.host;
+      if (host.isNotEmpty) {
+        result.write(r"\");
+        result.write(host);
+        result.write(r"\");
+      }
+    }
+    result.writeAll(segments, r"\");
+    if (hasDriveLetter && segments.length == 1) result.write(r"\");
+    return result.toString();
+  }
+
+  bool get _isPathAbsolute {
+    return path != null && path.startsWith('/');
+  }
+
+  void _writeAuthority(StringSink ss) {
+    if (_userInfo.isNotEmpty) {
+      ss.write(_userInfo);
+      ss.write("@");
+    }
+    if (_host != null) ss.write(_host);
+    if (_port != null) {
+      ss.write(":");
+      ss.write(_port);
+    }
+  }
+
+  /**
+   * Access the structure of a `data:` URI.
+   *
+   * Returns a [UriData] object for `data:` URIs and `null` for all other
+   * URIs.
+   * The [UriData] object can be used to access the media type and data
+   * of a `data:` URI.
+   */
+  UriData get data => (scheme == "data") ? UriData.fromUri(this) : null;
+
+  String toString() {
+    return _text ??= _initializeText();
+  }
+
+  String _initializeText() {
+    assert(_text == null);
+    StringBuffer sb = StringBuffer();
+    if (scheme.isNotEmpty) sb..write(scheme)..write(":");
+    if (hasAuthority || (scheme == "file")) {
+      // File URIS always have the authority, even if it is empty.
+      // The empty URI means "localhost".
+      sb.write("//");
+      _writeAuthority(sb);
+    }
+    sb.write(path);
+    if (_query != null) sb..write("?")..write(_query);
+    if (_fragment != null) sb..write("#")..write(_fragment);
+    return sb.toString();
+  }
+
+  bool operator ==(Object other) {
+    if (identical(this, other)) return true;
+    return other is Uri &&
+        scheme == other.scheme &&
+        hasAuthority == other.hasAuthority &&
+        userInfo == other.userInfo &&
+        host == other.host &&
+        port == other.port &&
+        path == other.path &&
+        hasQuery == other.hasQuery &&
+        query == other.query &&
+        hasFragment == other.hasFragment &&
+        fragment == other.fragment;
+  }
+
+  int get hashCode {
+    return _hashCodeCache ??= toString().hashCode;
+  }
+
+  static List<String> _createList() => <String>[];
+
+  static Map<String, List<String>> _splitQueryStringAll(String query,
+      {Encoding encoding = utf8}) {
+    var result = <String, List<String>>{};
+    int i = 0;
+    int start = 0;
+    int equalsIndex = -1;
+
+    void parsePair(int start, int equalsIndex, int end) {
+      String key;
+      String value;
+      if (start == end) return;
+      if (equalsIndex < 0) {
+        key = _uriDecode(query, start, end, encoding, true);
+        value = "";
+      } else {
+        key = _uriDecode(query, start, equalsIndex, encoding, true);
+        value = _uriDecode(query, equalsIndex + 1, end, encoding, true);
+      }
+      result.putIfAbsent(key, _createList).add(value);
+    }
+
+    while (i < query.length) {
+      int char = query.codeUnitAt(i);
+      if (char == _EQUALS) {
+        if (equalsIndex < 0) equalsIndex = i;
+      } else if (char == _AMPERSAND) {
+        parsePair(start, equalsIndex, i);
+        start = i + 1;
+        equalsIndex = -1;
+      }
+      i++;
+    }
+    parsePair(start, equalsIndex, i);
+    return result;
+  }
+
+  external static String _uriEncode(List<int> canonicalTable, String text,
+      Encoding encoding, bool spaceToPlus);
+
+  /**
+   * Convert a byte (2 character hex sequence) in string [s] starting
+   * at position [pos] to its ordinal value
+   */
+  static int _hexCharPairToByte(String s, int pos) {
+    int byte = 0;
+    for (int i = 0; i < 2; i++) {
+      var charCode = s.codeUnitAt(pos + i);
+      if (0x30 <= charCode && charCode <= 0x39) {
+        byte = byte * 16 + charCode - 0x30;
+      } else {
+        // Check ranges A-F (0x41-0x46) and a-f (0x61-0x66).
+        charCode |= 0x20;
+        if (0x61 <= charCode && charCode <= 0x66) {
+          byte = byte * 16 + charCode - 0x57;
+        } else {
+          throw ArgumentError("Invalid URL encoding");
+        }
+      }
+    }
+    return byte;
+  }
+
+  /**
+   * Uri-decode a percent-encoded string.
+   *
+   * It unescapes the string [text] and returns the unescaped string.
+   *
+   * This function is similar to the JavaScript-function `decodeURI`.
+   *
+   * If [plusToSpace] is `true`, plus characters will be converted to spaces.
+   *
+   * The decoder will create a byte-list of the percent-encoded parts, and then
+   * decode the byte-list using [encoding]. The default encodings UTF-8.
+   */
+  static String _uriDecode(
+      String text, int start, int end, Encoding encoding, bool plusToSpace) {
+    assert(0 <= start);
+    assert(start <= end);
+    assert(end <= text.length);
+    assert(encoding != null);
+    // First check whether there is any characters which need special handling.
+    bool simple = true;
+    for (int i = start; i < end; i++) {
+      var codeUnit = text.codeUnitAt(i);
+      if (codeUnit > 127 ||
+          codeUnit == _PERCENT ||
+          (plusToSpace && codeUnit == _PLUS)) {
+        simple = false;
+        break;
+      }
+    }
+    List<int> bytes;
+    if (simple) {
+      if (utf8 == encoding || latin1 == encoding || ascii == encoding) {
+        return text.substring(start, end);
+      } else {
+        bytes = text.substring(start, end).codeUnits;
+      }
+    } else {
+      bytes = List();
+      for (int i = start; i < end; i++) {
+        var codeUnit = text.codeUnitAt(i);
+        if (codeUnit > 127) {
+          throw ArgumentError("Illegal percent encoding in URI");
+        }
+        if (codeUnit == _PERCENT) {
+          if (i + 3 > text.length) {
+            throw ArgumentError('Truncated URI');
+          }
+          bytes.add(_hexCharPairToByte(text, i + 1));
+          i += 2;
+        } else if (plusToSpace && codeUnit == _PLUS) {
+          bytes.add(_SPACE);
+        } else {
+          bytes.add(codeUnit);
+        }
+      }
+    }
+    return encoding.decode(bytes);
+  }
+
+  static bool _isAlphabeticCharacter(int codeUnit) {
+    var lowerCase = codeUnit | 0x20;
+    return (_LOWER_CASE_A <= lowerCase && lowerCase <= _LOWER_CASE_Z);
+  }
+
+  static bool _isUnreservedChar(int char) {
+    return char < 127 &&
+        ((_unreservedTable[char >> 4] & (1 << (char & 0x0f))) != 0);
+  }
+
+  // Tables of char-codes organized as a bit vector of 128 bits where
+  // each bit indicate whether a character code on the 0-127 needs to
+  // be escaped or not.
+
+  // The unreserved characters of RFC 3986.
+  static const _unreservedTable = <int>[
+    //                     LSB            MSB
+    //                      |              |
+    0x0000, // 0x00 - 0x0f  0000000000000000
+    0x0000, // 0x10 - 0x1f  0000000000000000
+    //                                   -.
+    0x6000, // 0x20 - 0x2f  0000000000000110
+    //                      0123456789
+    0x03ff, // 0x30 - 0x3f  1111111111000000
+    //                       ABCDEFGHIJKLMNO
+    0xfffe, // 0x40 - 0x4f  0111111111111111
+    //                      PQRSTUVWXYZ    _
+    0x87ff, // 0x50 - 0x5f  1111111111100001
+    //                       abcdefghijklmno
+    0xfffe, // 0x60 - 0x6f  0111111111111111
+    //                      pqrstuvwxyz   ~
+    0x47ff, // 0x70 - 0x7f  1111111111100010
+  ];
+
+  // The unreserved characters of RFC 2396.
+  static const _unreserved2396Table = <int>[
+    //                     LSB            MSB
+    //                      |              |
+    0x0000, // 0x00 - 0x0f  0000000000000000
+    0x0000, // 0x10 - 0x1f  0000000000000000
+    //                       !     '()*  -.
+    0x6782, // 0x20 - 0x2f  0100000111100110
+    //                      0123456789
+    0x03ff, // 0x30 - 0x3f  1111111111000000
+    //                       ABCDEFGHIJKLMNO
+    0xfffe, // 0x40 - 0x4f  0111111111111111
+    //                      PQRSTUVWXYZ    _
+    0x87ff, // 0x50 - 0x5f  1111111111100001
+    //                       abcdefghijklmno
+    0xfffe, // 0x60 - 0x6f  0111111111111111
+    //                      pqrstuvwxyz   ~
+    0x47ff, // 0x70 - 0x7f  1111111111100010
+  ];
+
+  // Table of reserved characters specified by ECMAScript 5.
+  static const _encodeFullTable = <int>[
+    //                     LSB            MSB
+    //                      |              |
+    0x0000, // 0x00 - 0x0f  0000000000000000
+    0x0000, // 0x10 - 0x1f  0000000000000000
+    //                       ! #$ &'()*+,-./
+    0xffda, // 0x20 - 0x2f  0101101111111111
+    //                      0123456789:; = ?
+    0xafff, // 0x30 - 0x3f  1111111111110101
+    //                      @ABCDEFGHIJKLMNO
+    0xffff, // 0x40 - 0x4f  1111111111111111
+    //                      PQRSTUVWXYZ    _
+    0x87ff, // 0x50 - 0x5f  1111111111100001
+    //                       abcdefghijklmno
+    0xfffe, // 0x60 - 0x6f  0111111111111111
+    //                      pqrstuvwxyz   ~
+    0x47ff, // 0x70 - 0x7f  1111111111100010
+  ];
+
+  // Characters allowed in the scheme.
+  static const _schemeTable = <int>[
+    //                     LSB            MSB
+    //                      |              |
+    0x0000, // 0x00 - 0x0f  0000000000000000
+    0x0000, // 0x10 - 0x1f  0000000000000000
+    //                                 + -.
+    0x6800, // 0x20 - 0x2f  0000000000010110
+    //                      0123456789
+    0x03ff, // 0x30 - 0x3f  1111111111000000
+    //                       ABCDEFGHIJKLMNO
+    0xfffe, // 0x40 - 0x4f  0111111111111111
+    //                      PQRSTUVWXYZ
+    0x07ff, // 0x50 - 0x5f  1111111111100001
+    //                       abcdefghijklmno
+    0xfffe, // 0x60 - 0x6f  0111111111111111
+    //                      pqrstuvwxyz
+    0x07ff, // 0x70 - 0x7f  1111111111100010
+  ];
+
+  // Characters allowed in scheme except for upper case letters.
+  static const _schemeLowerTable = <int>[
+    //                     LSB            MSB
+    //                      |              |
+    0x0000, // 0x00 - 0x0f  0000000000000000
+    0x0000, // 0x10 - 0x1f  0000000000000000
+    //                                 + -.
+    0x6800, // 0x20 - 0x2f  0000000000010110
+    //                      0123456789
+    0x03ff, // 0x30 - 0x3f  1111111111000000
+    //
+    0x0000, // 0x40 - 0x4f  0111111111111111
+    //
+    0x0000, // 0x50 - 0x5f  1111111111100001
+    //                       abcdefghijklmno
+    0xfffe, // 0x60 - 0x6f  0111111111111111
+    //                      pqrstuvwxyz
+    0x07ff, // 0x70 - 0x7f  1111111111100010
+  ];
+
+  // Sub delimiter characters combined with unreserved as of 3986.
+  // sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
+  //         / "*" / "+" / "," / ";" / "="
+  // RFC 3986 section 2.3.
+  // unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
+  static const _subDelimitersTable = <int>[
+    //                     LSB            MSB
+    //                      |              |
+    0x0000, // 0x00 - 0x0f  0000000000000000
+    0x0000, // 0x10 - 0x1f  0000000000000000
+    //                       !  $ &'()*+,-.
+    0x7fd2, // 0x20 - 0x2f  0100101111111110
+    //                      0123456789 ; =
+    0x2bff, // 0x30 - 0x3f  1111111111010100
+    //                       ABCDEFGHIJKLMNO
+    0xfffe, // 0x40 - 0x4f  0111111111111111
+    //                      PQRSTUVWXYZ    _
+    0x87ff, // 0x50 - 0x5f  1111111111100001
+    //                       abcdefghijklmno
+    0xfffe, // 0x60 - 0x6f  0111111111111111
+    //                      pqrstuvwxyz   ~
+    0x47ff, // 0x70 - 0x7f  1111111111100010
+  ];
+
+  // General delimiter characters, RFC 3986 section 2.2.
+  // gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"
+  //
+  static const _genDelimitersTable = <int>[
+    //                     LSB            MSB
+    //                      |              |
+    0x0000, // 0x00 - 0x0f  0000000000000000
+    0x0000, // 0x10 - 0x1f  0000000000000000
+    //                         #           /
+    0x8008, // 0x20 - 0x2f  0001000000000001
+    //                                :    ?
+    0x8400, // 0x30 - 0x3f  0000000000100001
+    //                      @
+    0x0001, // 0x40 - 0x4f  1000000000000000
+    //                                 [ ]
+    0x2800, // 0x50 - 0x5f  0000000000010100
+    //
+    0x0000, // 0x60 - 0x6f  0000000000000000
+    //
+    0x0000, // 0x70 - 0x7f  0000000000000000
+  ];
+
+  // Characters allowed in the userinfo as of RFC 3986.
+  // RFC 3986 Appendix A
+  // userinfo = *( unreserved / pct-encoded / sub-delims / ':')
+  static const _userinfoTable = <int>[
+    //                     LSB            MSB
+    //                      |              |
+    0x0000, // 0x00 - 0x0f  0000000000000000
+    0x0000, // 0x10 - 0x1f  0000000000000000
+    //                       !  $ &'()*+,-.
+    0x7fd2, // 0x20 - 0x2f  0100101111111110
+    //                      0123456789:; =
+    0x2fff, // 0x30 - 0x3f  1111111111110100
+    //                       ABCDEFGHIJKLMNO
+    0xfffe, // 0x40 - 0x4f  0111111111111111
+    //                      PQRSTUVWXYZ    _
+    0x87ff, // 0x50 - 0x5f  1111111111100001
+    //                       abcdefghijklmno
+    0xfffe, // 0x60 - 0x6f  0111111111111111
+    //                      pqrstuvwxyz   ~
+    0x47ff, // 0x70 - 0x7f  1111111111100010
+  ];
+
+  // Characters allowed in the reg-name as of RFC 3986.
+  // RFC 3986 Appendix A
+  // reg-name = *( unreserved / pct-encoded / sub-delims )
+  static const _regNameTable = <int>[
+    //                     LSB            MSB
+    //                      |              |
+    0x0000, // 0x00 - 0x0f  0000000000000000
+    0x0000, // 0x10 - 0x1f  0000000000000000
+    //                       !  $%&'()*+,-.
+    0x7ff2, // 0x20 - 0x2f  0100111111111110
+    //                      0123456789 ; =
+    0x2bff, // 0x30 - 0x3f  1111111111010100
+    //                       ABCDEFGHIJKLMNO
+    0xfffe, // 0x40 - 0x4f  0111111111111111
+    //                      PQRSTUVWXYZ    _
+    0x87ff, // 0x50 - 0x5f  1111111111100001
+    //                       abcdefghijklmno
+    0xfffe, // 0x60 - 0x6f  0111111111111111
+    //                      pqrstuvwxyz   ~
+    0x47ff, // 0x70 - 0x7f  1111111111100010
+  ];
+
+  // Characters allowed in the path as of RFC 3986.
+  // RFC 3986 section 3.3.
+  // pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
+  static const _pathCharTable = <int>[
+    //                     LSB            MSB
+    //                      |              |
+    0x0000, // 0x00 - 0x0f  0000000000000000
+    0x0000, // 0x10 - 0x1f  0000000000000000
+    //                       !  $ &'()*+,-.
+    0x7fd2, // 0x20 - 0x2f  0100101111111110
+    //                      0123456789:; =
+    0x2fff, // 0x30 - 0x3f  1111111111110100
+    //                      @ABCDEFGHIJKLMNO
+    0xffff, // 0x40 - 0x4f  1111111111111111
+    //                      PQRSTUVWXYZ    _
+    0x87ff, // 0x50 - 0x5f  1111111111100001
+    //                       abcdefghijklmno
+    0xfffe, // 0x60 - 0x6f  0111111111111111
+    //                      pqrstuvwxyz   ~
+    0x47ff, // 0x70 - 0x7f  1111111111100010
+  ];
+
+  // Characters allowed in the path as of RFC 3986.
+  // RFC 3986 section 3.3 *and* slash.
+  static const _pathCharOrSlashTable = [
+    //                     LSB            MSB
+    //                      |              |
+    0x0000, // 0x00 - 0x0f  0000000000000000
+    0x0000, // 0x10 - 0x1f  0000000000000000
+    //                       !  $ &'()*+,-./
+    0xffd2, // 0x20 - 0x2f  0100101111111111
+    //                      0123456789:; =
+    0x2fff, // 0x30 - 0x3f  1111111111110100
+    //                      @ABCDEFGHIJKLMNO
+    0xffff, // 0x40 - 0x4f  1111111111111111
+
+    //                      PQRSTUVWXYZ    _
+    0x87ff, // 0x50 - 0x5f  1111111111100001
+    //                       abcdefghijklmno
+    0xfffe, // 0x60 - 0x6f  0111111111111111
+    //                      pqrstuvwxyz   ~
+    0x47ff, // 0x70 - 0x7f  1111111111100010
+  ];
+
+  // Characters allowed in the query as of RFC 3986.
+  // RFC 3986 section 3.4.
+  // query = *( pchar / "/" / "?" )
+  static const _queryCharTable = [
+    //                     LSB            MSB
+    //                      |              |
+    0x0000, // 0x00 - 0x0f  0000000000000000
+    0x0000, // 0x10 - 0x1f  0000000000000000
+    //                       !  $ &'()*+,-./
+    0xffd2, // 0x20 - 0x2f  0100101111111111
+    //                      0123456789:; = ?
+    0xafff, // 0x30 - 0x3f  1111111111110101
+    //                      @ABCDEFGHIJKLMNO
+    0xffff, // 0x40 - 0x4f  1111111111111111
+    //                      PQRSTUVWXYZ    _
+    0x87ff, // 0x50 - 0x5f  1111111111100001
+    //                       abcdefghijklmno
+    0xfffe, // 0x60 - 0x6f  0111111111111111
+    //                      pqrstuvwxyz   ~
+    0x47ff, // 0x70 - 0x7f  1111111111100010
+  ];
+
+  // Characters allowed in the ZoneID as of RFC 6874.
+  // ZoneID = 1*( unreserved / pct-encoded )
+  static const _zoneIDTable = <int>[
+    //                     LSB            MSB
+    //                      |              |
+    0x0000, // 0x00 - 0x0f  0000000000000000
+    0x0000, // 0x10 - 0x1f  0000000000000000
+    //                       !  $%&'()*+,-.
+    0x6000, // 0x20 - 0x2f  0000000000000110
+    //                      0123456789 ; =
+    0x03ff, // 0x30 - 0x3f  1111111111000000
+    //                       ABCDEFGHIJKLMNO
+    0xfffe, // 0x40 - 0x4f  0111111111111111
+    //                      PQRSTUVWXYZ    _
+    0x87ff, // 0x50 - 0x5f  1111111111100001
+    //                       abcdefghijklmno
+    0xfffe, // 0x60 - 0x6f  0111111111111111
+    //                      pqrstuvwxyz   ~
+    0x47ff, // 0x70 - 0x7f  1111111111100010
+  ];
+}
+
+// --------------------------------------------------------------------
+// Data URI
+// --------------------------------------------------------------------
+
+/**
+ * A way to access the structure of a `data:` URI.
+ *
+ * Data URIs are non-hierarchical URIs that can contain any binary data.
+ * They are defined by [RFC 2397](https://tools.ietf.org/html/rfc2397).
+ *
+ * This class allows parsing the URI text and extracting individual parts of the
+ * URI, as well as building the URI text from structured parts.
+ */
+class UriData {
+  static const int _noScheme = -1;
+  /**
+   * Contains the text content of a `data:` URI, with or without a
+   * leading `data:`.
+   *
+   * If [_separatorIndices] starts with `4` (the index of the `:`), then
+   * there is a leading `data:`, otherwise [_separatorIndices] starts with
+   * `-1`.
+   */
+  final String _text;
+
+  /**
+   * List of the separators (';', '=' and ',') in the text.
+   *
+   * Starts with the index of the `:` in `data:` of the mimeType.
+   * That is always either -1 or 4, depending on whether `_text` includes the
+   * `data:` scheme or not.
+   *
+   * The first speparator ends the mime type. We don't bother with finding
+   * the '/' inside the mime type.
+   *
+   * Each two separators after that marks a parameter key and value.
+   *
+   * If there is a single separator left, it ends the "base64" marker.
+   *
+   * So the following separators are found for a text:
+   * ```
+   * data:text/plain;foo=bar;base64,ARGLEBARGLE=
+   *     ^          ^   ^   ^      ^
+   * ```
+   */
+  final List<int> _separatorIndices;
+
+  /**
+   * Cache of the result returned by [uri].
+   */
+  Uri _uriCache;
+
+  UriData._(this._text, this._separatorIndices, this._uriCache);
+
+  // Avoid shadowing by argument.
+  static const Base64Codec _base64 = base64;
+
+  /**
+   * Creates a `data:` URI containing the [content] string.
+   *
+   * Equivalent to `new Uri.dataFromString(...).data`, but may
+   * be more efficient if the [uri] itself isn't used.
+   */
+  factory UriData.fromString(String content,
+      {String mimeType,
+      Encoding encoding,
+      Map<String, String> parameters,
+      bool base64 = false}) {
+    StringBuffer buffer = StringBuffer();
+    List<int> indices = [_noScheme];
+    String charsetName;
+    String encodingName;
+    if (parameters != null) charsetName = parameters["charset"];
+    if (encoding == null) {
+      if (charsetName != null) {
+        encoding = Encoding.getByName(charsetName);
+      }
+    } else if (charsetName == null) {
+      // Non-null only if parameters does not contain "charset".
+      encodingName = encoding.name;
+    }
+    encoding ??= ascii;
+    _writeUri(mimeType, encodingName, parameters, buffer, indices);
+    indices.add(buffer.length);
+    if (base64) {
+      buffer.write(';base64,');
+      indices.add(buffer.length - 1);
+      buffer.write(encoding.fuse(_base64).encode(content));
+    } else {
+      buffer.write(',');
+      _uriEncodeBytes(_uricTable, encoding.encode(content), buffer);
+    }
+    return UriData._(buffer.toString(), indices, null);
+  }
+
+  /**
+   * Creates a `data:` URI containing an encoding of [bytes].
+   *
+   * Equivalent to `new Uri.dataFromBytes(...).data`, but may
+   * be more efficient if the [uri] itself isn't used.
+   */
+  factory UriData.fromBytes(List<int> bytes,
+      {mimeType = "application/octet-stream",
+      Map<String, String> parameters,
+      percentEncoded = false}) {
+    StringBuffer buffer = StringBuffer();
+    List<int> indices = [_noScheme];
+    _writeUri(mimeType, null, parameters, buffer, indices);
+    indices.add(buffer.length);
+    if (percentEncoded) {
+      buffer.write(',');
+      _uriEncodeBytes(_uricTable, bytes, buffer);
+    } else {
+      buffer.write(';base64,');
+      indices.add(buffer.length - 1);
+      _base64.encoder
+          .startChunkedConversion(StringConversionSink.fromStringSink(buffer))
+          .addSlice(bytes, 0, bytes.length, true);
+    }
+
+    return UriData._(buffer.toString(), indices, null);
+  }
+
+  /**
+   * Creates a `DataUri` from a [Uri] which must have `data` as [Uri.scheme].
+   *
+   * The [uri] must have scheme `data` and no authority or fragment,
+   * and the path (concatenated with the query, if there is one) must be valid
+   * as data URI content with the same rules as [parse].
+   */
+  factory UriData.fromUri(Uri uri) {
+    if (uri.scheme != "data") {
+      throw ArgumentError.value(uri, "uri", "Scheme must be 'data'");
+    }
+    if (uri.hasAuthority) {
+      throw ArgumentError.value(uri, "uri", "Data uri must not have authority");
+    }
+    if (uri.hasFragment) {
+      throw ArgumentError.value(
+          uri, "uri", "Data uri must not have a fragment part");
+    }
+    if (!uri.hasQuery) {
+      return _parse(uri.path, 0, uri);
+    }
+    // Includes path and query (and leading "data:").
+    return _parse("$uri", 5, uri);
+  }
+
+  /**
+   * Writes the initial part of a `data:` uri, from after the "data:"
+   * until just before the ',' before the data, or before a `;base64,`
+   * marker.
+   *
+   * Of an [indices] list is passed, separator indices are stored in that
+   * list.
+   */
+  static void _writeUri(String mimeType, String charsetName,
+      Map<String, String> parameters, StringBuffer buffer, List indices) {
+    if (mimeType == null || mimeType == "text/plain") {
+      mimeType = "";
+    }
+    if (mimeType.isEmpty || identical(mimeType, "application/octet-stream")) {
+      buffer.write(mimeType); // Common cases need no escaping.
+    } else {
+      int slashIndex = _validateMimeType(mimeType);
+      if (slashIndex < 0) {
+        throw ArgumentError.value(mimeType, "mimeType", "Invalid MIME type");
+      }
+      buffer.write(_Uri._uriEncode(
+          _tokenCharTable, mimeType.substring(0, slashIndex), utf8, false));
+      buffer.write("/");
+      buffer.write(_Uri._uriEncode(
+          _tokenCharTable, mimeType.substring(slashIndex + 1), utf8, false));
+    }
+    if (charsetName != null) {
+      if (indices != null) {
+        indices..add(buffer.length)..add(buffer.length + 8);
+      }
+      buffer.write(";charset=");
+      buffer.write(_Uri._uriEncode(_tokenCharTable, charsetName, utf8, false));
+    }
+    parameters?.forEach((key, value) {
+      if (key.isEmpty) {
+        throw ArgumentError.value("", "Parameter names must not be empty");
+      }
+      if (value.isEmpty) {
+        throw ArgumentError.value(
+            "", "Parameter values must not be empty", 'parameters["$key"]');
+      }
+      if (indices != null) indices.add(buffer.length);
+      buffer.write(';');
+      // Encode any non-RFC2045-token character and both '%' and '#'.
+      buffer.write(_Uri._uriEncode(_tokenCharTable, key, utf8, false));
+      if (indices != null) indices.add(buffer.length);
+      buffer.write('=');
+      buffer.write(_Uri._uriEncode(_tokenCharTable, value, utf8, false));
+    });
+  }
+
+  /**
+   * Checks mimeType is valid-ish (`token '/' token`).
+   *
+   * Returns the index of the slash, or -1 if the mime type is not
+   * considered valid.
+   *
+   * Currently only looks for slashes, all other characters will be
+   * percent-encoded as UTF-8 if necessary.
+   */
+  static int _validateMimeType(String mimeType) {
+    int slashIndex = -1;
+    for (int i = 0; i < mimeType.length; i++) {
+      var char = mimeType.codeUnitAt(i);
+      if (char != _SLASH) continue;
+      if (slashIndex < 0) {
+        slashIndex = i;
+        continue;
+      }
+      return -1;
+    }
+    return slashIndex;
+  }
+
+  /**
+   * Parses a string as a `data` URI.
+   *
+   * The string must have the format:
+   *
+   * ```
+   * 'data:' (type '/' subtype)? (';' attribute '=' value)* (';base64')? ',' data
+   * ````
+   *
+   * where `type`, `subtype`, `attribute` and `value` are specified in RFC-2045,
+   * and `data` is a sequence of URI-characters (RFC-2396 `uric`).
+   *
+   * This means that all the characters must be ASCII, but the URI may contain
+   * percent-escapes for non-ASCII byte values that need an interpretation
+   * to be converted to the corresponding string.
+   *
+   * Parsing checks that Base64 encoded data is valid, and it normalizes it
+   * to use the default Base64 alphabet and to use padding.
+   * Non-Base64 data is escaped using percent-escapes as necessary to make
+   * it valid, and existing escapes are case normalized.
+   *
+   * Accessing the individual parts may fail later if they turn out to have
+   * content that can't be decoded successfully as a string, for example if
+   * existing percent escapes represent bytes that cannot be decoded
+   * by the chosen [Encoding] (see [contentAsString]).
+   *
+   * A [FormatException] is thrown if [uri] is not a valid data URI.
+   */
+  static UriData parse(String uri) {
+    if (uri.length >= 5) {
+      int dataDelta = _startsWithData(uri, 0);
+      if (dataDelta == 0) {
+        // Exact match on "data:".
+        return _parse(uri, 5, null);
+      }
+      if (dataDelta == 0x20) {
+        // Starts with a non-normalized "data" scheme containing upper-case
+        // letters. Parse anyway, but throw away the scheme.
+        return _parse(uri.substring(5), 0, null);
+      }
+    }
+    throw FormatException("Does not start with 'data:'", uri, 0);
+  }
+
+  /**
+   * The [Uri] that this `UriData` is giving access to.
+   *
+   * Returns a `Uri` with scheme `data` and the remainder of the data URI
+   * as path.
+   */
+  Uri get uri {
+    if (_uriCache != null) return _uriCache;
+    String path = _text;
+    String query;
+    int colonIndex = _separatorIndices[0];
+    int queryIndex = _text.indexOf('?', colonIndex + 1);
+    int end = _text.length;
+    if (queryIndex >= 0) {
+      query = _Uri._normalizeOrSubstring(
+          _text, queryIndex + 1, end, _Uri._queryCharTable);
+      end = queryIndex;
+    }
+    path = _Uri._normalizeOrSubstring(
+        _text, colonIndex + 1, end, _Uri._pathCharOrSlashTable);
+    _uriCache = _DataUri(this, path, query);
+    return _uriCache;
+  }
+
+  /**
+   * The MIME type of the data URI.
+   *
+   * A data URI consists of a "media type" followed by data.
+   * The media type starts with a MIME type and can be followed by
+   * extra parameters.
+   * If the MIME type representation in the URI text contains URI escapes,
+   * they are unescaped in the returned string.
+   * If the value contain non-ASCII percent escapes, they are decoded as UTF-8.
+   *
+   * Example:
+   *
+   *     data:text/plain;charset=utf-8,Hello%20World!
+   *
+   * This data URI has the media type `text/plain;charset=utf-8`, which is the
+   * MIME type `text/plain` with the parameter `charset` with value `utf-8`.
+   * See [RFC 2045](https://tools.ietf.org/html/rfc2045) for more detail.
+   *
+   * If the first part of the data URI is empty, it defaults to `text/plain`.
+   */
+  String get mimeType {
+    int start = _separatorIndices[0] + 1;
+    int end = _separatorIndices[1];
+    if (start == end) return "text/plain";
+    return _Uri._uriDecode(_text, start, end, utf8, false);
+  }
+
+  /**
+   * The charset parameter of the media type.
+   *
+   * If the parameters of the media type contains a `charset` parameter
+   * then this returns its value, otherwise it returns `US-ASCII`,
+   * which is the default charset for data URIs.
+   * If the value contain non-ASCII percent escapes, they are decoded as UTF-8.
+   *
+   * If the MIME type representation in the URI text contains URI escapes,
+   * they are unescaped in the returned string.
+   */
+  String get charset {
+    int parameterStart = 1;
+    int parameterEnd = _separatorIndices.length - 1; // The ',' before data.
+    if (isBase64) {
+      // There is a ";base64" separator, so subtract one for that as well.
+      parameterEnd -= 1;
+    }
+    for (int i = parameterStart; i < parameterEnd; i += 2) {
+      var keyStart = _separatorIndices[i] + 1;
+      var keyEnd = _separatorIndices[i + 1];
+      if (keyEnd == keyStart + 7 && _text.startsWith("charset", keyStart)) {
+        return _Uri._uriDecode(
+            _text, keyEnd + 1, _separatorIndices[i + 2], utf8, false);
+      }
+    }
+    return "US-ASCII";
+  }
+
+  /**
+   * Whether the data is Base64 encoded or not.
+   */
+  bool get isBase64 => _separatorIndices.length.isOdd;
+
+  /**
+   * The content part of the data URI, as its actual representation.
+   *
+   * This string may contain percent escapes.
+   */
+  String get contentText => _text.substring(_separatorIndices.last + 1);
+
+  /**
+   * The content part of the data URI as bytes.
+   *
+   * If the data is Base64 encoded, it will be decoded to bytes.
+   *
+   * If the data is not Base64 encoded, it will be decoded by unescaping
+   * percent-escaped characters and returning byte values of each unescaped
+   * character. The bytes will not be, e.g., UTF-8 decoded.
+   */
+  Uint8List contentAsBytes() {
+    String text = _text;
+    int start = _separatorIndices.last + 1;
+    if (isBase64) {
+      return base64.decoder.convert(text, start);
+    }
+
+    // Not base64, do percent-decoding and return the remaining bytes.
+    // Compute result size.
+    const int percent = 0x25;
+    int length = text.length - start;
+    for (int i = start; i < text.length; i++) {
+      var codeUnit = text.codeUnitAt(i);
+      if (codeUnit == percent) {
+        i += 2;
+        length -= 2;
+      }
+    }
+    // Fill result array.
+    Uint8List result = Uint8List(length);
+    if (length == text.length) {
+      result.setRange(0, length, text.codeUnits, start);
+      return result;
+    }
+    int index = 0;
+    for (int i = start; i < text.length; i++) {
+      var codeUnit = text.codeUnitAt(i);
+      if (codeUnit != percent) {
+        result[index++] = codeUnit;
+      } else {
+        if (i + 2 < text.length) {
+          int byte = parseHexByte(text, i + 1);
+          if (byte >= 0) {
+            result[index++] = byte;
+            i += 2;
+            continue;
+          }
+        }
+        throw FormatException("Invalid percent escape", text, i);
+      }
+    }
+    assert(index == result.length);
+    return result;
+  }
+
+  /**
+   * Returns a string created from the content of the data URI.
+   *
+   * If the content is Base64 encoded, it will be decoded to bytes and then
+   * decoded to a string using [encoding].
+   * If encoding is omitted, the value of a `charset` parameter is used
+   * if it is recognized by [Encoding.getByName], otherwise it defaults to
+   * the [ascii] encoding, which is the default encoding for data URIs
+   * that do not specify an encoding.
+   *
+   * If the content is not Base64 encoded, it will first have percent-escapes
+   * converted to bytes and then the character codes and byte values are
+   * decoded using [encoding].
+   */
+  String contentAsString({Encoding encoding}) {
+    if (encoding == null) {
+      var charset = this.charset; // Returns "US-ASCII" if not present.
+      encoding = Encoding.getByName(charset);
+      if (encoding == null) {
+        throw UnsupportedError("Unknown charset: $charset");
+      }
+    }
+    String text = _text;
+    int start = _separatorIndices.last + 1;
+    if (isBase64) {
+      var converter = base64.decoder.fuse(encoding.decoder);
+      return converter.convert(text.substring(start));
+    }
+    return _Uri._uriDecode(text, start, text.length, encoding, false);
+  }
+
+  /**
+   * A map representing the parameters of the media type.
+   *
+   * A data URI may contain parameters between the MIME type and the
+   * data. This converts these parameters to a map from parameter name
+   * to parameter value.
+   * The map only contains parameters that actually occur in the URI.
+   * The `charset` parameter has a default value even if it doesn't occur
+   * in the URI, which is reflected by the [charset] getter. This means that
+   * [charset] may return a value even if `parameters["charset"]` is `null`.
+   *
+   * If the values contain non-ASCII values or percent escapes,
+   * they are decoded as UTF-8.
+   */
+  Map<String, String> get parameters {
+    var result = <String, String>{};
+    for (int i = 3; i < _separatorIndices.length; i += 2) {
+      var start = _separatorIndices[i - 2] + 1;
+      var equals = _separatorIndices[i - 1];
+      var end = _separatorIndices[i];
+      String key = _Uri._uriDecode(_text, start, equals, utf8, false);
+      String value = _Uri._uriDecode(_text, equals + 1, end, utf8, false);
+      result[key] = value;
+    }
+    return result;
+  }
+
+  static UriData _parse(String text, int start, Uri sourceUri) {
+    assert(start == 0 || start == 5);
+    assert((start == 5) == text.startsWith("data:"));
+
+    /// Character codes.
+    const int comma = 0x2c;
+    const int slash = 0x2f;
+    const int semicolon = 0x3b;
+    const int equals = 0x3d;
+    List<int> indices = [start - 1];
+    int slashIndex = -1;
+    var char;
+    int i = start;
+    for (; i < text.length; i++) {
+      char = text.codeUnitAt(i);
+      if (char == comma || char == semicolon) break;
+      if (char == slash) {
+        if (slashIndex < 0) {
+          slashIndex = i;
+          continue;
+        }
+        throw FormatException("Invalid MIME type", text, i);
+      }
+    }
+    if (slashIndex < 0 && i > start) {
+      // An empty MIME type is allowed, but if non-empty it must contain
+      // exactly one slash.
+      throw FormatException("Invalid MIME type", text, i);
+    }
+    while (char != comma) {
+      // Parse parameters and/or "base64".
+      indices.add(i);
+      i++;
+      int equalsIndex = -1;
+      for (; i < text.length; i++) {
+        char = text.codeUnitAt(i);
+        if (char == equals) {
+          if (equalsIndex < 0) equalsIndex = i;
+        } else if (char == semicolon || char == comma) {
+          break;
+        }
+      }
+      if (equalsIndex >= 0) {
+        indices.add(equalsIndex);
+      } else {
+        // Have to be final "base64".
+        var lastSeparator = indices.last;
+        if (char != comma ||
+            i != lastSeparator + 7 /* "base64,".length */ ||
+            !text.startsWith("base64", lastSeparator + 1)) {
+          throw FormatException("Expecting '='", text, i);
+        }
+        break;
+      }
+    }
+    indices.add(i);
+    bool isBase64 = indices.length.isOdd;
+    if (isBase64) {
+      text = base64.normalize(text, i + 1, text.length);
+    } else {
+      // Validate "data" part, must only contain RFC 2396 'uric' characters
+      // (reserved, unreserved, or escape sequences).
+      // Normalize to this (throws on a fragment separator).
+      var data = _Uri._normalize(text, i + 1, text.length, _uricTable,
+          escapeDelimiters: true);
+      if (data != null) {
+        text = text.replaceRange(i + 1, text.length, data);
+      }
+    }
+    return UriData._(text, indices, sourceUri);
+  }
+
+  /**
+   * Like [Uri._uriEncode] but takes the input as bytes, not a string.
+   *
+   * Encodes into [buffer] instead of creating its own buffer.
+   */
+  static void _uriEncodeBytes(
+      List<int> canonicalTable, List<int> bytes, StringSink buffer) {
+    // Encode the string into bytes then generate an ASCII only string
+    // by percent encoding selected bytes.
+    int byteOr = 0;
+    for (int i = 0; i < bytes.length; i++) {
+      int byte = bytes[i];
+      byteOr |= byte;
+      if (byte < 128 &&
+          ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) {
+        buffer.writeCharCode(byte);
+      } else {
+        buffer.writeCharCode(_PERCENT);
+        buffer.writeCharCode(_hexDigits.codeUnitAt(byte >> 4));
+        buffer.writeCharCode(_hexDigits.codeUnitAt(byte & 0x0f));
+      }
+    }
+    if ((byteOr & ~0xFF) != 0) {
+      for (int i = 0; i < bytes.length; i++) {
+        var byte = bytes[i];
+        if (byte < 0 || byte > 255) {
+          throw ArgumentError.value(byte, "non-byte value");
+        }
+      }
+    }
+  }
+
+  String toString() =>
+      (_separatorIndices[0] == _noScheme) ? "data:$_text" : _text;
+
+  // Table of the `token` characters of RFC 2045 in a URI.
+  //
+  // A token is any US-ASCII character except SPACE, control characters and
+  // `tspecial` characters. The `tspecial` category is:
+  // '(', ')', '<', '>', '@', ',', ';', ':', '\', '"', '/', '[, ']', '?', '='.
+  //
+  // In a data URI, we also need to escape '%' and '#' characters.
+  static const _tokenCharTable = [
+    //                     LSB             MSB
+    //                      |               |
+    0x0000, // 0x00 - 0x0f  00000000 00000000
+    0x0000, // 0x10 - 0x1f  00000000 00000000
+    //                       !  $ &'   *+ -.
+    0x6cd2, // 0x20 - 0x2f  01001011 00110110
+    //                      01234567 89
+    0x03ff, // 0x30 - 0x3f  11111111 11000000
+    //                       ABCDEFG HIJKLMNO
+    0xfffe, // 0x40 - 0x4f  01111111 11111111
+    //                      PQRSTUVW XYZ   ^_
+    0xc7ff, // 0x50 - 0x5f  11111111 11100011
+    //                      `abcdefg hijklmno
+    0xffff, // 0x60 - 0x6f  11111111 11111111
+    //                      pqrstuvw xyz{|}~
+    0x7fff, // 0x70 - 0x7f  11111111 11111110
+  ];
+
+  // All non-escape RFC-2396 uric characters.
+  //
+  //  uric        =  reserved | unreserved | escaped
+  //  reserved    =  ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
+  //  unreserved  =  alphanum | mark
+  //  mark        =  "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
+  //
+  // This is the same characters as in a URI query (which is URI pchar plus '?')
+  static const _uricTable = _Uri._queryCharTable;
+
+  // Characters allowed in base-64 encoding (alphanumeric, '/', '+' and '=').
+  static const _base64Table = [
+    //                     LSB             MSB
+    //                      |               |
+    0x0000, // 0x00 - 0x0f  00000000 00000000
+    0x0000, // 0x10 - 0x1f  00000000 00000000
+    //                                  +   /
+    0x8800, // 0x20 - 0x2f  00000000 00010001
+    //                      01234567 89
+    0x03ff, // 0x30 - 0x3f  11111111 11000000
+    //                       ABCDEFG HIJKLMNO
+    0xfffe, // 0x40 - 0x4f  01111111 11111111
+    //                      PQRSTUVW XYZ
+    0x07ff, // 0x50 - 0x5f  11111111 11100000
+    //                       abcdefg hijklmno
+    0xfffe, // 0x60 - 0x6f  01111111 11111111
+    //                      pqrstuvw xyz
+    0x07ff, // 0x70 - 0x7f  11111111 11100000
+  ];
+}
+
+// --------------------------------------------------------------------
+// Constants used to read the scanner result.
+// The indices points into the table filled by [_scan] which contains
+// recognized positions in the scanned URI.
+// The `0` index is only used internally.
+
+/// Index of the position of that `:` after a scheme.
+const int _schemeEndIndex = 1;
+
+/// Index of the position of the character just before the host name.
+const int _hostStartIndex = 2;
+
+/// Index of the position of the `:` before a port value.
+const int _portStartIndex = 3;
+
+/// Index of the position of the first character of a path.
+const int _pathStartIndex = 4;
+
+/// Index of the position of the `?` before a query.
+const int _queryStartIndex = 5;
+
+/// Index of the position of the `#` before a fragment.
+const int _fragmentStartIndex = 6;
+
+/// Index of a position where the URI was determined to be "non-simple".
+const int _notSimpleIndex = 7;
+
+// Initial state for scanner.
+const int _uriStart = 00;
+
+// If scanning of a URI terminates in this state or above,
+// consider the URI non-simple
+const int _nonSimpleEndStates = 14;
+
+// Initial state for scheme validation.
+const int _schemeStart = 20;
+
+/// Transition tables used to scan a URI to determine its structure.
+///
+/// The tables represent a state machine with output.
+///
+/// To scan the URI, start in the [_uriStart] state, then read each character
+/// of the URI in order, from start to end, and for each character perform a
+/// transition to a new state while writing the current position into the output
+/// buffer at a designated index.
+///
+/// Each state, represented by an integer which is an index into
+/// [_scannerTables], has a set of transitions, one for each character.
+/// The transitions are encoded as a 5-bit integer representing the next state
+/// and a 3-bit index into the output table.
+///
+/// For URI scanning, only characters in the range U+0020 through U+007E are
+/// interesting, all characters outside that range are treated the same.
+/// The tables only contain 96 entries, representing that characters in the
+/// interesting range, plus one more to represent all values outside the range.
+/// The character entries are stored in one `Uint8List` per state, with the
+/// transition for a character at position `character ^ 0x60`,
+/// which maps the range U+0020 .. U+007F into positions 0 .. 95.
+/// All remaining characters are mapped to position 31 (`0x7f ^ 0x60`) which
+/// represents the transition for all remaining characters.
+final List<Uint8List> _scannerTables = _createTables();
+
+// ----------------------------------------------------------------------
+// Code to create the URI scanner table.
+
+/// Creates the tables for [_scannerTables] used by [Uri.parse].
+///
+/// See [_scannerTables] for the generated format.
+///
+/// The concrete tables are chosen as a trade-off between the number of states
+/// needed and the precision of the result.
+/// This allows definitely recognizing the general structure of the URI
+/// (presence and location of scheme, user-info, host, port, path, query and
+/// fragment) while at the same time detecting that some components are not
+/// in canonical form (anything containing a `%`, a host-name containing a
+/// capital letter). Since the scanner doesn't know whether something is a
+/// scheme or a path until it sees `:`, or user-info or host until it sees
+/// a `@`, a second pass is needed to validate the scheme and any user-info
+/// is considered non-canonical by default.
+///
+/// The states (starting from [_uriStart]) write positions while scanning
+/// a string from `start` to `end` as follows:
+///
+/// - [_schemeEndIndex]: Should be initialized to `start-1`.
+///   If the URI has a scheme, it is set to the position of the `:` after
+///   the scheme.
+/// - [_hostStartIndex]: Should be initialized to `start - 1`.
+///   If the URI has an authority, it is set to the character before the
+///   host name - either the second `/` in the `//` leading the authority,
+///   or the `@` after a user-info. Comparing this value to the scheme end
+///   position can be used to detect that there is a user-info component.
+/// - [_portStartIndex]: Should be initialized to `start`.
+///   Set to the position of the last `:` in an authority, and unchanged
+///   if there is no authority or no `:` in an authority.
+///   If this position is after the host start, there is a port, otherwise it
+///   is just marking a colon in the user-info component.
+/// - [_pathStartIndex]: Should be initialized to `start`.
+///   Is set to the first path character unless the path is empty.
+///   If the path is empty, the position is either unchanged (`start`) or
+///   the first slash of an authority. So, if the path start is before a
+///   host start or scheme end, the path is empty.
+/// - [_queryStartIndex]: Should be initialized to `end`.
+///   The position of the `?` leading a query if the URI contains a query.
+/// - [_fragmentStartIndex]: Should be initialized to `end`.
+///   The position of the `#` leading a fragment if the URI contains a fragment.
+/// - [_notSimpleIndex]: Should be initialized to `start - 1`.
+///   Set to another value if the URI is considered "not simple".
+///   This is elaborated below.
+///
+/// # Simple URIs
+/// A URI is considered "simple" if it is in a normalized form containing no
+/// escapes. This allows us to skip normalization and checking whether escapes
+/// are valid, and to extract components without worrying about unescaping.
+///
+/// The scanner computes a conservative approximation of being "simple".
+/// It rejects any URI with an escape, with a user-info component (mainly
+/// because they are rare and would increase the number of states in the
+/// scanner significantly), with an IPV6 host or with a capital letter in
+/// the scheme or host name (the scheme is handled in a second scan using
+/// a separate two-state table).
+/// Further, paths containing `..` or `.` path segments are considered
+/// non-simple except for pure relative paths (no scheme or authority) starting
+/// with a sequence of "../" segments.
+///
+/// The transition tables cannot detect a trailing ".." in the path,
+/// followed by a query or fragment, because the segment is not known to be
+/// complete until we are past it, and we then need to store the query/fragment
+/// start instead. This cast is checked manually post-scanning (such a path
+/// needs to be normalized to end in "../", so the URI shouldn't be considered
+/// simple).
+List<Uint8List> _createTables() {
+  // TODO(lrn): Use a precomputed table.
+
+  // Total number of states for the scanner.
+  const int stateCount = 22;
+
+  // States used to scan a URI from scratch.
+  const int schemeOrPath = 01;
+  const int authOrPath = 02;
+  const int authOrPathSlash = 03;
+  const int uinfoOrHost0 = 04;
+  const int uinfoOrHost = 05;
+  const int uinfoOrPort0 = 06;
+  const int uinfoOrPort = 07;
+  const int ipv6Host = 08;
+  const int relPathSeg = 09;
+  const int pathSeg = 10;
+  const int path = 11;
+  const int query = 12;
+  const int fragment = 13;
+  const int schemeOrPathDot = 14;
+  const int schemeOrPathDot2 = 15;
+  const int relPathSegDot = 16;
+  const int relPathSegDot2 = 17;
+  const int pathSegDot = 18;
+  const int pathSegDot2 = 19;
+
+  // States used to validate a scheme after its end position has been found.
+  const int scheme0 = _schemeStart;
+  const int scheme = 21;
+
+  // Constants encoding the write-index for the state transition into the top 5
+  // bits of a byte.
+  const int schemeEnd = _schemeEndIndex << 5;
+  const int hostStart = _hostStartIndex << 5;
+  const int portStart = _portStartIndex << 5;
+  const int pathStart = _pathStartIndex << 5;
+  const int queryStart = _queryStartIndex << 5;
+  const int fragmentStart = _fragmentStartIndex << 5;
+  const int notSimple = _notSimpleIndex << 5;
+
+  /// The `unreserved` characters of RFC 3986.
+  const unreserved =
+      "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-._~";
+
+  /// The `sub-delim` characters of RFC 3986.
+  const subDelims = r"!$&'()*+,;=";
+  // The `pchar` characters of RFC 3986: characters that may occur in a path,
+  // excluding escapes.
+  const pchar = "$unreserved$subDelims";
+
+  var tables = List<Uint8List>.generate(stateCount, (_) => Uint8List(96));
+
+  // Helper function which initialize the table for [state] with a default
+  // transition and returns the table.
+  Uint8List build(state, defaultTransition) =>
+      tables[state]..fillRange(0, 96, defaultTransition);
+
+  // Helper function which sets the transition for each character in [chars]
+  // to [transition] in the [target] table.
+  // The [chars] string must contain only characters in the U+0020 .. U+007E
+  // range.
+  void setChars(Uint8List target, String chars, int transition) {
+    for (int i = 0; i < chars.length; i++) {
+      var char = chars.codeUnitAt(i);
+      target[char ^ 0x60] = transition;
+    }
+  }
+
+  /// Helper function which sets the transition for all characters in the
+  /// range from `range[0]` to `range[1]` to [transition] in the [target] table.
+  ///
+  /// The [range] must be a two-character string where both characters are in
+  /// the U+0020 .. U+007E range and the former character must have a lower
+  /// code point than the latter.
+  void setRange(Uint8List target, String range, int transition) {
+    for (int i = range.codeUnitAt(0), n = range.codeUnitAt(1); i <= n; i++) {
+      target[i ^ 0x60] = transition;
+    }
+  }
+
+  // Create the transitions for each state.
+  var b;
+
+  // Validate as path, if it is a scheme, we handle it later.
+  b = build(_uriStart, schemeOrPath | notSimple);
+  setChars(b, pchar, schemeOrPath);
+  setChars(b, ".", schemeOrPathDot);
+  setChars(b, ":", authOrPath | schemeEnd); // Handle later.
+  setChars(b, "/", authOrPathSlash);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(schemeOrPathDot, schemeOrPath | notSimple);
+  setChars(b, pchar, schemeOrPath);
+  setChars(b, ".", schemeOrPathDot2);
+  setChars(b, ':', authOrPath | schemeEnd);
+  setChars(b, "/", pathSeg | notSimple);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(schemeOrPathDot2, schemeOrPath | notSimple);
+  setChars(b, pchar, schemeOrPath);
+  setChars(b, "%", schemeOrPath | notSimple);
+  setChars(b, ':', authOrPath | schemeEnd);
+  setChars(b, "/", relPathSeg);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(schemeOrPath, schemeOrPath | notSimple);
+  setChars(b, pchar, schemeOrPath);
+  setChars(b, ':', authOrPath | schemeEnd);
+  setChars(b, "/", pathSeg);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(authOrPath, path | notSimple);
+  setChars(b, pchar, path | pathStart);
+  setChars(b, "/", authOrPathSlash | pathStart);
+  setChars(b, ".", pathSegDot | pathStart);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(authOrPathSlash, path | notSimple);
+  setChars(b, pchar, path);
+  setChars(b, "/", uinfoOrHost0 | hostStart);
+  setChars(b, ".", pathSegDot);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(uinfoOrHost0, uinfoOrHost | notSimple);
+  setChars(b, pchar, uinfoOrHost);
+  setRange(b, "AZ", uinfoOrHost | notSimple);
+  setChars(b, ":", uinfoOrPort0 | portStart);
+  setChars(b, "@", uinfoOrHost0 | hostStart);
+  setChars(b, "[", ipv6Host | notSimple);
+  setChars(b, "/", pathSeg | pathStart);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(uinfoOrHost, uinfoOrHost | notSimple);
+  setChars(b, pchar, uinfoOrHost);
+  setRange(b, "AZ", uinfoOrHost | notSimple);
+  setChars(b, ":", uinfoOrPort0 | portStart);
+  setChars(b, "@", uinfoOrHost0 | hostStart);
+  setChars(b, "/", pathSeg | pathStart);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(uinfoOrPort0, uinfoOrPort | notSimple);
+  setRange(b, "19", uinfoOrPort);
+  setChars(b, "@", uinfoOrHost0 | hostStart);
+  setChars(b, "/", pathSeg | pathStart);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(uinfoOrPort, uinfoOrPort | notSimple);
+  setRange(b, "09", uinfoOrPort);
+  setChars(b, "@", uinfoOrHost0 | hostStart);
+  setChars(b, "/", pathSeg | pathStart);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(ipv6Host, ipv6Host);
+  setChars(b, "]", uinfoOrHost);
+
+  b = build(relPathSeg, path | notSimple);
+  setChars(b, pchar, path);
+  setChars(b, ".", relPathSegDot);
+  setChars(b, "/", pathSeg | notSimple);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(relPathSegDot, path | notSimple);
+  setChars(b, pchar, path);
+  setChars(b, ".", relPathSegDot2);
+  setChars(b, "/", pathSeg | notSimple);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(relPathSegDot2, path | notSimple);
+  setChars(b, pchar, path);
+  setChars(b, "/", relPathSeg);
+  setChars(b, "?", query | queryStart); // This should be non-simple.
+  setChars(b, "#", fragment | fragmentStart); // This should be non-simple.
+
+  b = build(pathSeg, path | notSimple);
+  setChars(b, pchar, path);
+  setChars(b, ".", pathSegDot);
+  setChars(b, "/", pathSeg | notSimple);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(pathSegDot, path | notSimple);
+  setChars(b, pchar, path);
+  setChars(b, ".", pathSegDot2);
+  setChars(b, "/", pathSeg | notSimple);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(pathSegDot2, path | notSimple);
+  setChars(b, pchar, path);
+  setChars(b, "/", pathSeg | notSimple);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(path, path | notSimple);
+  setChars(b, pchar, path);
+  setChars(b, "/", pathSeg);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(query, query | notSimple);
+  setChars(b, pchar, query);
+  setChars(b, "?", query);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(fragment, fragment | notSimple);
+  setChars(b, pchar, fragment);
+  setChars(b, "?", fragment);
+
+  // A separate two-state validator for lower-case scheme names.
+  // Any non-scheme character or upper-case letter is marked as non-simple.
+  b = build(scheme0, scheme | notSimple);
+  setRange(b, "az", scheme);
+
+  b = build(scheme, scheme | notSimple);
+  setRange(b, "az", scheme);
+  setRange(b, "09", scheme);
+  setChars(b, "+-.", scheme);
+
+  return tables;
+}
+
+// --------------------------------------------------------------------
+// Code that uses the URI scanner table.
+
+/// Scan a string using the [_scannerTables] state machine.
+///
+/// Scans [uri] from [start] to [end], starting in state [state] and
+/// writing output into [indices].
+///
+/// Returns the final state.
+int _scan(String uri, int start, int end, int state, List<int> indices) {
+  var tables = _scannerTables;
+  assert(end <= uri.length);
+  for (int i = start; i < end; i++) {
+    var table = tables[state];
+    // Xor with 0x60 to move range 0x20-0x7f into 0x00-0x5f
+    int char = uri.codeUnitAt(i) ^ 0x60;
+    // Use 0x1f (nee 0x7f) to represent all unhandled characters.
+    if (char > 0x5f) char = 0x1f;
+    int transition = table[char];
+    state = transition & 0x1f;
+    indices[transition >> 5] = i;
+  }
+  return state;
+}
+
+class _SimpleUri implements Uri {
+  final String _uri;
+  final int _schemeEnd;
+  final int _hostStart;
+  final int _portStart;
+  final int _pathStart;
+  final int _queryStart;
+  final int _fragmentStart;
+
+  /// The scheme is often used to distinguish URIs.
+  /// To make comparisons more efficient, we cache the value, and
+  /// canonicalize a few known types.
+  String _schemeCache;
+  int _hashCodeCache;
+
+  _SimpleUri(
+      this._uri,
+      this._schemeEnd,
+      this._hostStart,
+      this._portStart,
+      this._pathStart,
+      this._queryStart,
+      this._fragmentStart,
+      this._schemeCache);
+
+  bool get hasScheme => _schemeEnd > 0;
+  bool get hasAuthority => _hostStart > 0;
+  bool get hasUserInfo => _hostStart > _schemeEnd + 4;
+  bool get hasPort => _hostStart > 0 && _portStart + 1 < _pathStart;
+  bool get hasQuery => _queryStart < _fragmentStart;
+  bool get hasFragment => _fragmentStart < _uri.length;
+
+  bool get _isFile => _schemeEnd == 4 && _uri.startsWith("file");
+  bool get _isHttp => _schemeEnd == 4 && _uri.startsWith("http");
+  bool get _isHttps => _schemeEnd == 5 && _uri.startsWith("https");
+  bool get _isPackage => _schemeEnd == 7 && _uri.startsWith("package");
+
+  /// Like [isScheme] but expects argument to be case normalized.
+  bool _isScheme(String scheme) =>
+      _schemeEnd == scheme.length && _uri.startsWith(scheme);
+
+  bool get hasAbsolutePath => _uri.startsWith("/", _pathStart);
+  bool get hasEmptyPath => _pathStart == _queryStart;
+
+  bool get isAbsolute => hasScheme && !hasFragment;
+
+  bool isScheme(String scheme) {
+    if (scheme == null || scheme.isEmpty) return _schemeEnd < 0;
+    if (scheme.length != _schemeEnd) return false;
+    return _Uri._compareScheme(scheme, _uri);
+  }
+
+  String get scheme {
+    if (_schemeEnd <= 0) return "";
+    if (_schemeCache != null) return _schemeCache;
+    if (_isHttp) {
+      _schemeCache = "http";
+    } else if (_isHttps) {
+      _schemeCache = "https";
+    } else if (_isFile) {
+      _schemeCache = "file";
+    } else if (_isPackage) {
+      _schemeCache = "package";
+    } else {
+      _schemeCache = _uri.substring(0, _schemeEnd);
+    }
+    return _schemeCache;
+  }
+
+  String get authority =>
+      _hostStart > 0 ? _uri.substring(_schemeEnd + 3, _pathStart) : "";
+  String get userInfo => (_hostStart > _schemeEnd + 3)
+      ? _uri.substring(_schemeEnd + 3, _hostStart - 1)
+      : "";
+  String get host =>
+      _hostStart > 0 ? _uri.substring(_hostStart, _portStart) : "";
+  int get port {
+    if (hasPort) return int.parse(_uri.substring(_portStart + 1, _pathStart));
+    if (_isHttp) return 80;
+    if (_isHttps) return 443;
+    return 0;
+  }
+
+  String get path => _uri.substring(_pathStart, _queryStart);
+  String get query => (_queryStart < _fragmentStart)
+      ? _uri.substring(_queryStart + 1, _fragmentStart)
+      : "";
+  String get fragment =>
+      (_fragmentStart < _uri.length) ? _uri.substring(_fragmentStart + 1) : "";
+
+  String get origin {
+    // Check original behavior - W3C spec is wonky!
+    bool isHttp = _isHttp;
+    if (_schemeEnd < 0) {
+      throw StateError("Cannot use origin without a scheme: $this");
+    }
+    if (!isHttp && !_isHttps) {
+      throw StateError(
+          "Origin is only applicable to schemes http and https: $this");
+    }
+    if (_hostStart == _portStart) {
+      throw StateError(
+          "A $scheme: URI should have a non-empty host name: $this");
+    }
+    if (_hostStart == _schemeEnd + 3) {
+      return _uri.substring(0, _pathStart);
+    }
+    // Need to drop anon-empty userInfo.
+    return _uri.substring(0, _schemeEnd + 3) +
+        _uri.substring(_hostStart, _pathStart);
+  }
+
+  List<String> get pathSegments {
+    int start = _pathStart;
+    int end = _queryStart;
+    if (_uri.startsWith("/", start)) start++;
+    if (start == end) return const <String>[];
+    List<String> parts = [];
+    for (int i = start; i < end; i++) {
+      var char = _uri.codeUnitAt(i);
+      if (char == _SLASH) {
+        parts.add(_uri.substring(start, i));
+        start = i + 1;
+      }
+    }
+    parts.add(_uri.substring(start, end));
+    return List<String>.unmodifiable(parts);
+  }
+
+  Map<String, String> get queryParameters {
+    if (!hasQuery) return const <String, String>{};
+    return UnmodifiableMapView<String, String>(Uri.splitQueryString(query));
+  }
+
+  Map<String, List<String>> get queryParametersAll {
+    if (!hasQuery) return const <String, List<String>>{};
+    Map queryParameterLists = _Uri._splitQueryStringAll(query);
+    for (var key in queryParameterLists.keys) {
+      queryParameterLists[key] =
+          List<String>.unmodifiable(queryParameterLists[key]);
+    }
+    return Map<String, List<String>>.unmodifiable(queryParameterLists);
+  }
+
+  bool _isPort(String port) {
+    int portDigitStart = _portStart + 1;
+    return portDigitStart + port.length == _pathStart &&
+        _uri.startsWith(port, portDigitStart);
+  }
+
+  Uri normalizePath() => this;
+
+  Uri removeFragment() {
+    if (!hasFragment) return this;
+    return _SimpleUri(_uri.substring(0, _fragmentStart), _schemeEnd, _hostStart,
+        _portStart, _pathStart, _queryStart, _fragmentStart, _schemeCache);
+  }
+
+  Uri replace(
+      {String scheme,
+      String userInfo,
+      String host,
+      int port,
+      String path,
+      Iterable<String> pathSegments,
+      String query,
+      Map<String, dynamic /*String|Iterable<String>*/ > queryParameters,
+      String fragment}) {
+    bool schemeChanged = false;
+    if (scheme != null) {
+      scheme = _Uri._makeScheme(scheme, 0, scheme.length);
+      schemeChanged = !_isScheme(scheme);
+    } else {
+      scheme = this.scheme;
+    }
+    bool isFile = (scheme == "file");
+    if (userInfo != null) {
+      userInfo = _Uri._makeUserInfo(userInfo, 0, userInfo.length);
+    } else if (_hostStart > 0) {
+      userInfo = _uri.substring(_schemeEnd + 3, _hostStart);
+    } else {
+      userInfo = "";
+    }
+    if (port != null) {
+      port = _Uri._makePort(port, scheme);
+    } else {
+      port = this.hasPort ? this.port : null;
+      if (schemeChanged) {
+        // The default port might have changed.
+        port = _Uri._makePort(port, scheme);
+      }
+    }
+    if (host != null) {
+      host = _Uri._makeHost(host, 0, host.length, false);
+    } else if (_hostStart > 0) {
+      host = _uri.substring(_hostStart, _portStart);
+    } else if (userInfo.isNotEmpty || port != null || isFile) {
+      host = "";
+    }
+
+    bool hasAuthority = host != null;
+    if (path != null || pathSegments != null) {
+      path = _Uri._makePath(path, 0, _stringOrNullLength(path), pathSegments,
+          scheme, hasAuthority);
+    } else {
+      path = _uri.substring(_pathStart, _queryStart);
+      if ((isFile || (hasAuthority && !path.isEmpty)) &&
+          !path.startsWith('/')) {
+        path = "/" + path;
+      }
+    }
+
+    if (query != null || queryParameters != null) {
+      query = _Uri._makeQuery(
+          query, 0, _stringOrNullLength(query), queryParameters);
+    } else if (_queryStart < _fragmentStart) {
+      query = _uri.substring(_queryStart + 1, _fragmentStart);
+    }
+
+    if (fragment != null) {
+      fragment = _Uri._makeFragment(fragment, 0, fragment.length);
+    } else if (_fragmentStart < _uri.length) {
+      fragment = _uri.substring(_fragmentStart + 1);
+    }
+
+    return _Uri._internal(scheme, userInfo, host, port, path, query, fragment);
+  }
+
+  Uri resolve(String reference) {
+    return resolveUri(Uri.parse(reference));
+  }
+
+  Uri resolveUri(Uri reference) {
+    if (reference is _SimpleUri) {
+      return _simpleMerge(this, reference);
+    }
+    return _toNonSimple().resolveUri(reference);
+  }
+
+  // Merge two simple URIs. This should always result in a prefix of
+  // one concatenated with a suffix of the other, possibly with a `/` in
+  // the middle of two merged paths, which is again simple.
+  // In a few cases, there might be a need for extra normalization, when
+  // resolving on top of a known scheme.
+  Uri _simpleMerge(_SimpleUri base, _SimpleUri ref) {
+    if (ref.hasScheme) return ref;
+    if (ref.hasAuthority) {
+      if (!base.hasScheme) return ref;
+      bool isSimple = true;
+      if (base._isFile) {
+        isSimple = !ref.hasEmptyPath;
+      } else if (base._isHttp) {
+        isSimple = !ref._isPort("80");
+      } else if (base._isHttps) {
+        isSimple = !ref._isPort("443");
+      }
+      if (isSimple) {
+        var delta = base._schemeEnd + 1;
+        var newUri = base._uri.substring(0, base._schemeEnd + 1) +
+            ref._uri.substring(ref._schemeEnd + 1);
+        return _SimpleUri(
+            newUri,
+            base._schemeEnd,
+            ref._hostStart + delta,
+            ref._portStart + delta,
+            ref._pathStart + delta,
+            ref._queryStart + delta,
+            ref._fragmentStart + delta,
+            base._schemeCache);
+      } else {
+        // This will require normalization, so use the _Uri implementation.
+        return _toNonSimple().resolveUri(ref);
+      }
+    }
+    if (ref.hasEmptyPath) {
+      if (ref.hasQuery) {
+        int delta = base._queryStart - ref._queryStart;
+        var newUri = base._uri.substring(0, base._queryStart) +
+            ref._uri.substring(ref._queryStart);
+        return _SimpleUri(
+            newUri,
+            base._schemeEnd,
+            base._hostStart,
+            base._portStart,
+            base._pathStart,
+            ref._queryStart + delta,
+            ref._fragmentStart + delta,
+            base._schemeCache);
+      }
+      if (ref.hasFragment) {
+        int delta = base._fragmentStart - ref._fragmentStart;
+        var newUri = base._uri.substring(0, base._fragmentStart) +
+            ref._uri.substring(ref._fragmentStart);
+        return _SimpleUri(
+            newUri,
+            base._schemeEnd,
+            base._hostStart,
+            base._portStart,
+            base._pathStart,
+            base._queryStart,
+            ref._fragmentStart + delta,
+            base._schemeCache);
+      }
+      return base.removeFragment();
+    }
+    if (ref.hasAbsolutePath) {
+      var delta = base._pathStart - ref._pathStart;
+      var newUri = base._uri.substring(0, base._pathStart) +
+          ref._uri.substring(ref._pathStart);
+      return _SimpleUri(
+          newUri,
+          base._schemeEnd,
+          base._hostStart,
+          base._portStart,
+          base._pathStart,
+          ref._queryStart + delta,
+          ref._fragmentStart + delta,
+          base._schemeCache);
+    }
+    if (base.hasEmptyPath && base.hasAuthority) {
+      // ref has relative non-empty path.
+      // Add a "/" in front, then leading "/../" segments are folded to "/".
+      int refStart = ref._pathStart;
+      while (ref._uri.startsWith("../", refStart)) {
+        refStart += 3;
+      }
+      var delta = base._pathStart - refStart + 1;
+      var newUri = "${base._uri.substring(0, base._pathStart)}/"
+          "${ref._uri.substring(refStart)}";
+      return _SimpleUri(
+          newUri,
+          base._schemeEnd,
+          base._hostStart,
+          base._portStart,
+          base._pathStart,
+          ref._queryStart + delta,
+          ref._fragmentStart + delta,
+          base._schemeCache);
+    }
+    // Merge paths.
+
+    // The RFC 3986 algorithm merges the base path without its final segment
+    // (anything after the final "/", or everything if the base path doesn't
+    // contain any "/"), and the reference path.
+    // Then it removes "." and ".." segments using the remove-dot-segment
+    // algorithm.
+    // This code combines the two steps. It is simplified by knowing that
+    // the base path contains no "." or ".." segments, and the reference
+    // path can only contain leading ".." segments.
+
+    String baseUri = base._uri;
+    String refUri = ref._uri;
+    int baseStart = base._pathStart;
+    int baseEnd = base._queryStart;
+    while (baseUri.startsWith("../", baseStart)) baseStart += 3;
+    int refStart = ref._pathStart;
+    int refEnd = ref._queryStart;
+
+    /// Count of leading ".." segments in reference path.
+    /// The count is decremented when the segment is matched with a
+    /// segment of the base path, and both are then omitted from the result.
+    int backCount = 0;
+
+    /// Count "../" segments and advance `refStart` to after the segments.
+    while (refStart + 3 <= refEnd && refUri.startsWith("../", refStart)) {
+      refStart += 3;
+      backCount += 1;
+    }
+
+    // Extra slash inserted between base and reference path parts if
+    // the base path contains any slashes, or empty string if none.
+    // (We could use a slash from the base path in most cases, but not if
+    // we remove the entire base path).
+    String insert = "";
+
+    /// Remove segments from the base path.
+    /// Start with the segment trailing the last slash,
+    /// then remove segments for each leading "../" segment
+    /// from the reference path, or as many of them as are available.
+    while (baseEnd > baseStart) {
+      baseEnd--;
+      int char = baseUri.codeUnitAt(baseEnd);
+      if (char == _SLASH) {
+        insert = "/";
+        if (backCount == 0) break;
+        backCount--;
+      }
+    }
+
+    if (baseEnd == baseStart && !base.hasScheme && !base.hasAbsolutePath) {
+      // If the base is *just* a relative path (no scheme or authority),
+      // then merging with another relative path doesn't follow the
+      // RFC-3986 behavior.
+      // Don't need to check `base.hasAuthority` since the base path is
+      // non-empty - if there is an authority, a non-empty path is absolute.
+
+      // We reached the start of the base path, and want to stay relative,
+      // so don't insert a slash.
+      insert = "";
+      // If we reached the start of the base path with more "../" left over
+      // in the reference path, include those segments in the result.
+      refStart -= backCount * 3;
+    }
+
+    var delta = baseEnd - refStart + insert.length;
+    var newUri = "${base._uri.substring(0, baseEnd)}$insert"
+        "${ref._uri.substring(refStart)}";
+
+    return _SimpleUri(
+        newUri,
+        base._schemeEnd,
+        base._hostStart,
+        base._portStart,
+        base._pathStart,
+        ref._queryStart + delta,
+        ref._fragmentStart + delta,
+        base._schemeCache);
+  }
+
+  String toFilePath({bool windows}) {
+    if (_schemeEnd >= 0 && !_isFile) {
+      throw UnsupportedError("Cannot extract a file path from a $scheme URI");
+    }
+    if (_queryStart < _uri.length) {
+      if (_queryStart < _fragmentStart) {
+        throw UnsupportedError(
+            "Cannot extract a file path from a URI with a query component");
+      }
+      throw UnsupportedError(
+          "Cannot extract a file path from a URI with a fragment component");
+    }
+    windows ??= _Uri._isWindows;
+    return windows ? _Uri._toWindowsFilePath(this) : _toFilePath();
+  }
+
+  String _toFilePath() {
+    if (_hostStart < _portStart) {
+      // Has authority and non-empty host.
+      throw UnsupportedError(
+          "Cannot extract a non-Windows file path from a file URI "
+          "with an authority");
+    }
+    return this.path;
+  }
+
+  UriData get data {
+    assert(scheme != "data");
+    return null;
+  }
+
+  int get hashCode => _hashCodeCache ??= _uri.hashCode;
+
+  bool operator ==(Object other) {
+    if (identical(this, other)) return true;
+    return other is Uri && _uri == other.toString();
+  }
+
+  Uri _toNonSimple() {
+    return _Uri._internal(
+        this.scheme,
+        this.userInfo,
+        this.hasAuthority ? this.host : null,
+        this.hasPort ? this.port : null,
+        this.path,
+        this.hasQuery ? this.query : null,
+        this.hasFragment ? this.fragment : null);
+  }
+
+  String toString() => _uri;
+}
+
+/// Special [_Uri] created from an existing [UriData].
+class _DataUri extends _Uri {
+  final UriData _data;
+
+  _DataUri(this._data, String path, String query)
+      : super._internal("data", null, null, null, path, query, null);
+
+  UriData get data => _data;
+}
+
+/// Checks whether [text] starts with "data:" at position [start].
+///
+/// The text must be long enough to allow reading five characters
+/// from the [start] position.
+///
+/// Returns an integer value which is zero if text starts with all-lowercase
+/// "data:" and 0x20 if the text starts with "data:" that isn't all lower-case.
+/// All other values means the text starts with some other character.
+int _startsWithData(String text, int start) {
+  // Multiply by 3 to avoid a non-colon character making delta be 0x20.
+  int delta = (text.codeUnitAt(start + 4) ^ _COLON) * 3;
+  delta |= text.codeUnitAt(start) ^ 0x64 /*d*/;
+  delta |= text.codeUnitAt(start + 1) ^ 0x61 /*a*/;
+  delta |= text.codeUnitAt(start + 2) ^ 0x74 /*t*/;
+  delta |= text.codeUnitAt(start + 3) ^ 0x61 /*a*/;
+  return delta;
+}
+
+/// Helper function returning the length of a string, or `0` for `null`.
+int _stringOrNullLength(String s) => (s == null) ? 0 : s.length;
diff --git a/sdk_nnbd/lib/developer/developer.dart b/sdk_nnbd/lib/developer/developer.dart
new file mode 100644
index 0000000..c446fdf
--- /dev/null
+++ b/sdk_nnbd/lib/developer/developer.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Interact with developer tools such as the debugger and inspector.
+///
+/// This library is platform dependent and has separate implementations for
+/// both web and the Dart VM. A specific platform may not support all
+/// operations.
+///
+/// To use this library in your code:
+///
+///     import 'dart:developer';
+///
+/// {@category Core}
+library dart.developer;
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:isolate' show Isolate, RawReceivePort, SendPort;
+
+part 'extension.dart';
+part 'profiler.dart';
+part 'service.dart';
+part 'timeline.dart';
+
+/// If [when] is true, stop the program as if a breakpoint were hit at the
+/// following statement.
+///
+/// Returns the value of [when]. Some debuggers may display [message].
+///
+/// NOTE: When invoked, the isolate will not return until a debugger
+/// continues execution. When running in the Dart VM, the behaviour is the same
+/// regardless of whether or not a debugger is connected. When compiled to
+/// JavaScript, this uses the "debugger" statement, and behaves exactly as
+/// that does.
+external bool debugger({bool when: true, String message});
+
+/// Send a reference to [object] to any attached debuggers.
+///
+/// Debuggers may open an inspector on the object. Returns the argument.
+external Object inspect(Object object);
+
+/// Emit a log event.
+///
+/// This function was designed to map closely to the logging information
+/// collected by `package:logging`.
+///
+/// - [message] is the log message
+/// - [time] (optional) is the timestamp
+/// - [sequenceNumber] (optional) is a monotonically increasing sequence number
+/// - [level] (optional) is the severity level (a value between 0 and 2000); see
+///   the `package:logging` `Level` class for an overview of the possible values
+/// - [name] (optional) is the name of the source of the log message
+/// - [zone] (optional) the zone where the log was emitted
+/// - [error] (optional) an error object associated with this log event
+/// - [stackTrace] (optional) a stack trace associated with this log event
+external void log(
+  String message, {
+  DateTime time,
+  int sequenceNumber,
+  int level: 0,
+  String name: '',
+  Zone zone,
+  Object error,
+  StackTrace stackTrace,
+});
diff --git a/sdk_nnbd/lib/developer/developer_sources.gni b/sdk_nnbd/lib/developer/developer_sources.gni
new file mode 100644
index 0000000..df0dbc2
--- /dev/null
+++ b/sdk_nnbd/lib/developer/developer_sources.gni
@@ -0,0 +1,13 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+developer_sdk_sources = [
+  "developer.dart",
+
+  # The above file needs to be first if additional parts are added to the lib.
+  "extension.dart",
+  "profiler.dart",
+  "service.dart",
+  "timeline.dart",
+]
diff --git a/sdk_nnbd/lib/developer/extension.dart b/sdk_nnbd/lib/developer/extension.dart
new file mode 100644
index 0000000..3cc4ede
--- /dev/null
+++ b/sdk_nnbd/lib/developer/extension.dart
@@ -0,0 +1,161 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.developer;
+
+/// A response to a service protocol extension RPC.
+///
+/// If the RPC was successful, use [ServiceExtensionResponse.result], otherwise
+/// use [ServiceExtensionResponse.error].
+class ServiceExtensionResponse {
+  /// The result of a successful service protocol extension RPC.
+  final String result;
+
+  /// The error code associated with a failed service protocol extension RPC.
+  final int errorCode;
+
+  /// The details of a failed service protocol extension RPC.
+  final String errorDetail;
+
+  /// Creates a successful response to a service protocol extension RPC.
+  ///
+  /// Requires [result] to be a JSON object encoded as a string. When forming
+  /// the JSON-RPC message [result] will be inlined directly.
+  ServiceExtensionResponse.result(String result)
+      : result = result,
+        errorCode = null,
+        errorDetail = null {
+    ArgumentError.checkNotNull(result, "result");
+  }
+
+  /// Creates an error response to a service protocol extension RPC.
+  ///
+  /// Requires [errorCode] to be [invalidParams] or between [extensionErrorMin]
+  /// and [extensionErrorMax]. Requires [errorDetail] to be a JSON object
+  /// encoded as a string. When forming the JSON-RPC message [errorDetail] will
+  /// be inlined directly.
+  ServiceExtensionResponse.error(int errorCode, String errorDetail)
+      : result = null,
+        errorCode = errorCode,
+        errorDetail = errorDetail {
+    _validateErrorCode(errorCode);
+    ArgumentError.checkNotNull(errorDetail, "errorDetail");
+  }
+
+  /// Invalid method parameter(s) error code.
+  @deprecated
+  static const kInvalidParams = invalidParams;
+
+  /// Generic extension error code.
+  @deprecated
+  static const kExtensionError = extensionError;
+
+  /// Maximum extension provided error code.
+  @deprecated
+  static const kExtensionErrorMax = extensionErrorMax;
+
+  /// Minimum extension provided error code.
+  @deprecated
+  static const kExtensionErrorMin = extensionErrorMin;
+
+  /// Invalid method parameter(s) error code.
+  static const invalidParams = -32602;
+
+  /// Generic extension error code.
+  static const extensionError = -32000;
+
+  /// Maximum extension provided error code.
+  static const extensionErrorMax = -32000;
+
+  /// Minimum extension provided error code.
+  static const extensionErrorMin = -32016;
+
+  static String _errorCodeMessage(int errorCode) {
+    _validateErrorCode(errorCode);
+    if (errorCode == invalidParams) {
+      return "Invalid params";
+    }
+    return "Server error";
+  }
+
+  static _validateErrorCode(int errorCode) {
+    ArgumentError.checkNotNull(errorCode, "errorCode");
+    if (errorCode == invalidParams) return;
+    if ((errorCode >= extensionErrorMin) && (errorCode <= extensionErrorMax)) {
+      return;
+    }
+    throw new ArgumentError.value(errorCode, "errorCode", "Out of range");
+  }
+
+  /// Determines if this response represents an error.
+  bool isError() => (errorCode != null) && (errorDetail != null);
+
+  // ignore: unused_element, called from runtime/lib/developer.dart
+  String _toString() {
+    if (result != null) {
+      return result;
+    } else {
+      assert(errorCode != null);
+      assert(errorDetail != null);
+      return json.encode({
+        'code': errorCode,
+        'message': _errorCodeMessage(errorCode),
+        'data': {'details': errorDetail}
+      });
+    }
+  }
+}
+
+/// A service protocol extension handler. Registered with [registerExtension].
+///
+/// Must complete to a [ServiceExtensionResponse]. [method] is the method name
+/// of the service protocol request, and [parameters] is a map holding the
+/// parameters to the service protocol request.
+///
+/// *NOTE*: all parameter names and values are encoded as strings.
+typedef Future<ServiceExtensionResponse> ServiceExtensionHandler(
+    String method, Map<String, String> parameters);
+
+/// Register a [ServiceExtensionHandler] that will be invoked in this isolate
+/// for [method]. *NOTE*: Service protocol extensions must be registered
+/// in each isolate.
+///
+/// *NOTE*: [method] must begin with 'ext.' and you should use the following
+/// structure to avoid conflicts with other packages: 'ext.package.command'.
+/// That is, immediately following the 'ext.' prefix, should be the registering
+/// package name followed by another period ('.') and then the command name.
+/// For example: 'ext.dart.io.getOpenFiles'.
+///
+/// Because service extensions are isolate specific, clients using extensions
+/// must always include an 'isolateId' parameter with each RPC.
+void registerExtension(String method, ServiceExtensionHandler handler) {
+  ArgumentError.checkNotNull(method, 'method');
+  if (!method.startsWith('ext.')) {
+    throw new ArgumentError.value(method, 'method', 'Must begin with ext.');
+  }
+  if (_lookupExtension(method) != null) {
+    throw new ArgumentError('Extension already registered: $method');
+  }
+  ArgumentError.checkNotNull(handler, 'handler');
+  _registerExtension(method, handler);
+}
+
+/// Post an event of [eventKind] with payload of [eventData] to the `Extension`
+/// event stream.
+void postEvent(String eventKind, Map eventData) {
+  ArgumentError.checkNotNull(eventKind, 'eventKind');
+  ArgumentError.checkNotNull(eventData, 'eventData');
+  String eventDataAsString = json.encode(eventData);
+  _postEvent(eventKind, eventDataAsString);
+}
+
+external void _postEvent(String eventKind, String eventData);
+
+// Both of these functions are written inside C++ to avoid updating the data
+// structures in Dart, getting an OOB, and observing stale state. Do not move
+// these into Dart code unless you can ensure that the operations will can be
+// done atomically. Native code lives in vm/isolate.cc-
+// LookupServiceExtensionHandler and RegisterServiceExtensionHandler.
+external ServiceExtensionHandler _lookupExtension(String method);
+external _registerExtension(String method, ServiceExtensionHandler handler);
diff --git a/sdk_nnbd/lib/developer/profiler.dart b/sdk_nnbd/lib/developer/profiler.dart
new file mode 100644
index 0000000..05a9211
--- /dev/null
+++ b/sdk_nnbd/lib/developer/profiler.dart
@@ -0,0 +1,149 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.developer;
+
+/// A UserTag can be used to group samples in the Observatory profiler.
+abstract class UserTag {
+  /// The maximum number of UserTag instances that can be created by a program.
+  static const MAX_USER_TAGS = 64;
+
+  external factory UserTag(String label);
+
+  /// Label of [this].
+  String get label;
+
+  /// Make [this] the current tag for the isolate. Returns the current tag
+  /// before setting.
+  UserTag makeCurrent();
+
+  /// The default [UserTag] with label 'Default'.
+  external static UserTag get defaultTag;
+}
+
+/// Returns the current [UserTag] for the isolate.
+external UserTag getCurrentTag();
+
+/// Abstract [Metric] class. Metric names must be unique, are hierarchical,
+/// and use periods as separators. For example, 'a.b.c'. Uniqueness is only
+/// enforced when a Metric is registered. The name of a metric cannot contain
+/// the slash ('/') character.
+abstract class Metric {
+  /// [name] of this metric.
+  final String name;
+
+  /// [description] of this metric.
+  final String description;
+
+  Metric(this.name, this.description) {
+    if ((name == 'vm') || name.contains('/')) {
+      throw new ArgumentError('Invalid Metric name.');
+    }
+  }
+
+  Map _toJSON();
+}
+
+/// A measured value with a min and max. Initial value is min. Value will
+/// be clamped to the interval [min, max].
+class Gauge extends Metric {
+  final double min;
+  final double max;
+
+  double _value;
+  double get value => _value;
+  set value(double v) {
+    if (v < min) {
+      v = min;
+    } else if (v > max) {
+      v = max;
+    }
+    _value = v;
+  }
+
+  Gauge(String name, String description, this.min, this.max)
+      : super(name, description) {
+    ArgumentError.checkNotNull(min, 'min');
+    ArgumentError.checkNotNull(max, 'max');
+    if (!(min < max)) throw new ArgumentError('min must be less than max');
+    _value = min;
+  }
+
+  Map _toJSON() {
+    var map = {
+      'type': 'Gauge',
+      'id': 'metrics/$name',
+      'name': name,
+      'description': description,
+      'value': value,
+      'min': min,
+      'max': max,
+    };
+    return map;
+  }
+}
+
+/// A changing value. Initial value is 0.0.
+class Counter extends Metric {
+  Counter(String name, String description) : super(name, description);
+
+  double _value = 0.0;
+  double get value => _value;
+  set value(double v) {
+    _value = v;
+  }
+
+  Map _toJSON() {
+    var map = {
+      'type': 'Counter',
+      'id': 'metrics/$name',
+      'name': name,
+      'description': description,
+      'value': value,
+    };
+    return map;
+  }
+}
+
+class Metrics {
+  static final Map<String, Metric> _metrics = new Map<String, Metric>();
+
+  /// Register [Metric]s to make them visible to Observatory.
+  static void register(Metric metric) {
+    ArgumentError.checkNotNull(metric, 'metric');
+    if (_metrics[metric.name] != null) {
+      throw new ArgumentError('Registered metrics have unique names');
+    }
+    _metrics[metric.name] = metric;
+  }
+
+  /// Deregister [Metric]s to make them not visible to Observatory.
+  static void deregister(Metric metric) {
+    ArgumentError.checkNotNull(metric, 'metric');
+    _metrics.remove(metric.name);
+  }
+
+  // ignore: unused_element, called from native code
+  static String _printMetric(String id) {
+    var metric = _metrics[id];
+    if (metric == null) {
+      return null;
+    }
+    return json.encode(metric._toJSON());
+  }
+
+  // ignore: unused_element, called from native code
+  @pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product"))
+  static String _printMetrics() {
+    var metrics = [];
+    for (var metric in _metrics.values) {
+      metrics.add(metric._toJSON());
+    }
+    var map = {
+      'type': 'MetricList',
+      'metrics': metrics,
+    };
+    return json.encode(map);
+  }
+}
diff --git a/sdk_nnbd/lib/developer/service.dart b/sdk_nnbd/lib/developer/service.dart
new file mode 100644
index 0000000..a4d92b9
--- /dev/null
+++ b/sdk_nnbd/lib/developer/service.dart
@@ -0,0 +1,98 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.developer;
+
+/// Service protocol is the protocol that a client like the Observatory
+/// could use to access the services provided by the Dart VM for
+/// debugging and inspecting Dart programs. This class encapsulates the
+/// version number and Uri for accessing this service.
+class ServiceProtocolInfo {
+  /// The major version of the protocol. If the running Dart environment does
+  /// not support the service protocol, this is 0.
+  final int majorVersion = _getServiceMajorVersion();
+
+  /// The minor version of the protocol. If the running Dart environment does
+  /// not support the service protocol, this is 0.
+  final int minorVersion = _getServiceMinorVersion();
+
+  /// The Uri to access the service. If the web server is not running, this
+  /// will be null.
+  final Uri serverUri;
+
+  ServiceProtocolInfo(this.serverUri);
+
+  String toString() {
+    if (serverUri != null) {
+      return 'Dart VM Service Protocol v$majorVersion.$minorVersion '
+          'listening on $serverUri';
+    } else {
+      return 'Dart VM Service Protocol v$majorVersion.$minorVersion';
+    }
+  }
+}
+
+/// Access information about the service protocol and control the web server
+/// that provides access to the services provided by the Dart VM for
+/// debugging and inspecting Dart programs.
+class Service {
+  /// Get information about the service protocol (version number and
+  /// Uri to access the service).
+  static Future<ServiceProtocolInfo> getInfo() async {
+    // Port to receive response from service isolate.
+    final RawReceivePort receivePort = new RawReceivePort();
+    final Completer<Uri> uriCompleter = new Completer<Uri>();
+    receivePort.handler = (Uri uri) => uriCompleter.complete(uri);
+    // Request the information from the service isolate.
+    _getServerInfo(receivePort.sendPort);
+    // Await the response from the service isolate.
+    Uri uri = await uriCompleter.future;
+    // Close the port.
+    receivePort.close();
+    return new ServiceProtocolInfo(uri);
+  }
+
+  /// Control the web server that the service protocol is accessed through.
+  /// The [enable] argument must be a boolean and is used as a toggle to
+  /// enable (true) or disable (false) the web server servicing requests.
+  static Future<ServiceProtocolInfo> controlWebServer(
+      {bool enable: false}) async {
+    ArgumentError.checkNotNull(enable, 'enable');
+    // Port to receive response from service isolate.
+    final RawReceivePort receivePort = new RawReceivePort();
+    final Completer<Uri> uriCompleter = new Completer<Uri>();
+    receivePort.handler = (Uri uri) => uriCompleter.complete(uri);
+    // Request the information from the service isolate.
+    _webServerControl(receivePort.sendPort, enable);
+    // Await the response from the service isolate.
+    Uri uri = await uriCompleter.future;
+    // Close the port.
+    receivePort.close();
+    return new ServiceProtocolInfo(uri);
+  }
+
+  /// Returns a [String] token representing the ID of [isolate].
+  ///
+  /// Returns null if the running Dart environment does not support the service
+  /// protocol.
+  static String getIsolateID(Isolate isolate) {
+    ArgumentError.checkNotNull(isolate, 'isolate');
+    return _getIsolateIDFromSendPort(isolate.controlPort);
+  }
+}
+
+/// [sendPort] will receive a Uri or null.
+external void _getServerInfo(SendPort sendPort);
+
+/// [sendPort] will receive a Uri or null.
+external void _webServerControl(SendPort sendPort, bool enable);
+
+/// Returns the major version of the service protocol.
+external int _getServiceMajorVersion();
+
+/// Returns the minor version of the service protocol.
+external int _getServiceMinorVersion();
+
+/// Returns the service id for the isolate that owns [sendPort].
+external String _getIsolateIDFromSendPort(SendPort sendPort);
diff --git a/sdk_nnbd/lib/developer/timeline.dart b/sdk_nnbd/lib/developer/timeline.dart
new file mode 100644
index 0000000..02f9c98
--- /dev/null
+++ b/sdk_nnbd/lib/developer/timeline.dart
@@ -0,0 +1,344 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.developer;
+
+const bool _hasTimeline =
+    const bool.fromEnvironment("dart.developer.timeline", defaultValue: true);
+
+/// A typedef for the function argument to [Timeline.timeSync].
+typedef TimelineSyncFunction<T> = T Function();
+
+// TODO: This typedef is not used.
+typedef Future TimelineAsyncFunction();
+
+/// A class to represent Flow events.
+///
+/// [Flow] objects are used to thread flow events between timeline slices,
+/// for example, those created with the [Timeline] class below. Adding
+/// [Flow] objects cause arrows to be drawn between slices in Chrome's trace
+/// viewer. The arrows start at e.g [Timeline] events that are passed a
+/// [Flow.begin] object, go through [Timeline] events that are passed a
+/// [Flow.step] object, and end at [Timeline] events that are passed a
+/// [Flow.end] object, all having the same [Flow.id]. For example:
+///
+/// ```dart
+/// var flow = Flow.begin();
+/// Timeline.timeSync('flow_test', () {
+///   doSomething();
+/// }, flow: flow);
+///
+/// Timeline.timeSync('flow_test', () {
+///   doSomething();
+/// }, flow: Flow.step(flow.id));
+///
+/// Timeline.timeSync('flow_test', () {
+///   doSomething();
+/// }, flow: Flow.end(flow.id));
+/// ```
+class Flow {
+  // These values must be kept in sync with the enum "EventType" in
+  // runtime/vm/timeline.h.
+  static const int _begin = 9;
+  static const int _step = 10;
+  static const int _end = 11;
+
+  final int _type;
+
+  /// The flow id of the flow event.
+  final int id;
+
+  Flow._(this._type, this.id);
+
+  /// A "begin" Flow event.
+  ///
+  /// When passed to a [Timeline] method, generates a "begin" Flow event.
+  /// If [id] is not provided, an id that conflicts with no other Dart-generated
+  /// flow id's will be generated.
+  static Flow begin({int id}) {
+    return new Flow._(_begin, id ?? _getNextAsyncId());
+  }
+
+  /// A "step" Flow event.
+  ///
+  /// When passed to a [Timeline] method, generates a "step" Flow event.
+  /// The [id] argument is required. It can come either from another [Flow]
+  /// event, or some id that comes from the environment.
+  static Flow step(int id) => new Flow._(_step, id);
+
+  /// An "end" Flow event.
+  ///
+  /// When passed to a [Timeline] method, generates a "end" Flow event.
+  /// The [id] argument is required. It can come either from another [Flow]
+  /// event, or some id that comes from the environment.
+  static Flow end(int id) => new Flow._(_end, id);
+}
+
+/// Add to the timeline.
+///
+/// [Timeline]'s methods add synchronous events to the timeline. When
+/// generating a timeline in Chrome's tracing format, using [Timeline] generates
+/// "Complete" events. [Timeline]'s [startSync] and [finishSync] can be used
+/// explicitly, or implicitly by wrapping a closure in [timeSync]. For example:
+///
+/// ```dart
+/// Timeline.startSync("Doing Something");
+/// doSomething();
+/// Timeline.finishSync();
+/// ```
+///
+/// Or:
+///
+/// ```dart
+/// Timeline.timeSync("Doing Something", () {
+///   doSomething();
+/// });
+/// ```
+class Timeline {
+  /// Start a synchronous operation labeled [name]. Optionally takes
+  /// a [Map] of [arguments]. This slice may also optionally be associated with
+  /// a [Flow] event. This operation must be finished before
+  /// returning to the event queue.
+  static void startSync(String name, {Map arguments, Flow flow}) {
+    if (!_hasTimeline) return;
+    ArgumentError.checkNotNull(name, 'name');
+    if (!_isDartStreamEnabled()) {
+      // Push a null onto the stack and return.
+      _stack.add(null);
+      return;
+    }
+    var block = new _SyncBlock._(name, _getTraceClock(), _getThreadCpuClock());
+    if (arguments != null) {
+      block._arguments = arguments;
+    }
+    if (flow != null) {
+      block.flow = flow;
+    }
+    _stack.add(block);
+  }
+
+  /// Finish the last synchronous operation that was started.
+  static void finishSync() {
+    if (!_hasTimeline) {
+      return;
+    }
+    if (_stack.length == 0) {
+      throw new StateError('Uneven calls to startSync and finishSync');
+    }
+    // Pop top item off of stack.
+    var block = _stack.removeLast();
+    if (block == null) {
+      // Dart stream was disabled when startSync was called.
+      return;
+    }
+    // Finish it.
+    block.finish();
+  }
+
+  /// Emit an instant event.
+  static void instantSync(String name, {Map arguments}) {
+    if (!_hasTimeline) return;
+    ArgumentError.checkNotNull(name, 'name');
+    if (!_isDartStreamEnabled()) {
+      // Stream is disabled.
+      return;
+    }
+    Map instantArguments;
+    if (arguments != null) {
+      instantArguments = new Map.from(arguments);
+    }
+    _reportInstantEvent(
+        _getTraceClock(), 'Dart', name, _argumentsAsJson(instantArguments));
+  }
+
+  /// A utility method to time a synchronous [function]. Internally calls
+  /// [function] bracketed by calls to [startSync] and [finishSync].
+  static T timeSync<T>(String name, TimelineSyncFunction<T> function,
+      {Map arguments, Flow flow}) {
+    startSync(name, arguments: arguments, flow: flow);
+    try {
+      return function();
+    } finally {
+      finishSync();
+    }
+  }
+
+  /// The current time stamp from the clock used by the timeline. Units are
+  /// microseconds.
+  ///
+  /// When run on the Dart VM, uses the same monotonic clock as the embedding
+  /// API's `Dart_TimelineGetMicros`.
+  static int get now => _getTraceClock();
+  static final List<_SyncBlock> _stack = new List<_SyncBlock>();
+}
+
+/// An asynchronous task on the timeline. An asynchronous task can have many
+/// (nested) synchronous operations. Synchronous operations can live longer than
+/// the current isolate event. To pass a [TimelineTask] to another isolate,
+/// you must first call [pass] to get the task id and then construct a new
+/// [TimelineTask] in the other isolate.
+class TimelineTask {
+  /// Create a task. The task ID will be set by the system.
+  TimelineTask() : _taskId = _getNextAsyncId() {}
+
+  /// Create a task with an explicit [taskId]. This is useful if you are
+  /// passing a task from one isolate to another.
+  TimelineTask.withTaskId(int taskId) : _taskId = taskId {
+    ArgumentError.checkNotNull(taskId, 'taskId');
+  }
+
+  /// Start a synchronous operation within this task named [name].
+  /// Optionally takes a [Map] of [arguments].
+  void start(String name, {Map arguments}) {
+    if (!_hasTimeline) return;
+    ArgumentError.checkNotNull(name, 'name');
+    var block = new _AsyncBlock._(name, _taskId);
+    _stack.add(block);
+    block._start(arguments);
+  }
+
+  /// Emit an instant event for this task.
+  /// Optionally takes a [Map] of [arguments].
+  void instant(String name, {Map arguments}) {
+    if (!_hasTimeline) return;
+    ArgumentError.checkNotNull(name, 'name');
+    Map instantArguments;
+    if (arguments != null) {
+      instantArguments = new Map.from(arguments);
+    }
+    _reportTaskEvent(_getTraceClock(), _taskId, 'n', 'Dart', name,
+        _argumentsAsJson(instantArguments));
+  }
+
+  /// Finish the last synchronous operation that was started.
+  /// Optionally takes a [Map] of [arguments].
+  void finish({Map arguments}) {
+    if (!_hasTimeline) {
+      return;
+    }
+    if (_stack.length == 0) {
+      throw new StateError('Uneven calls to start and finish');
+    }
+    // Pop top item off of stack.
+    var block = _stack.removeLast();
+    block._finish(arguments);
+  }
+
+  /// Retrieve the [TimelineTask]'s task id. Will throw an exception if the
+  /// stack is not empty.
+  int pass() {
+    if (_stack.length > 0) {
+      throw new StateError(
+          'You cannot pass a TimelineTask without finishing all started '
+          'operations');
+    }
+    int r = _taskId;
+    return r;
+  }
+
+  final int _taskId;
+  final List<_AsyncBlock> _stack = [];
+}
+
+/// An asynchronous block of time on the timeline. This block can be kept
+/// open across isolate messages.
+class _AsyncBlock {
+  /// The category this block belongs to.
+  final String category = 'Dart';
+
+  /// The name of this block.
+  final String name;
+
+  /// The asynchronous task id.
+  final int _taskId;
+
+  _AsyncBlock._(this.name, this._taskId);
+
+  // Emit the start event.
+  void _start(Map arguments) {
+    _reportTaskEvent(_getTraceClock(), _taskId, 'b', category, name,
+        _argumentsAsJson(arguments));
+  }
+
+  // Emit the finish event.
+  void _finish(Map arguments) {
+    _reportTaskEvent(_getTraceClock(), _taskId, 'e', category, name,
+        _argumentsAsJson(arguments));
+  }
+}
+
+/// A synchronous block of time on the timeline. This block should not be
+/// kept open across isolate messages.
+class _SyncBlock {
+  /// The category this block belongs to.
+  final String category = 'Dart';
+
+  /// The name of this block.
+  final String name;
+
+  /// An (optional) set of arguments which will be serialized to JSON and
+  /// associated with this block.
+  Map _arguments;
+  // The start time stamp.
+  final int _start;
+  // The start time stamp of the thread cpu clock.
+  final int _startCpu;
+
+  /// An (optional) flow event associated with this block.
+  Flow _flow;
+
+  _SyncBlock._(this.name, this._start, this._startCpu);
+
+  /// Finish this block of time. At this point, this block can no longer be
+  /// used.
+  void finish() {
+    // Report event to runtime.
+    _reportCompleteEvent(
+        _start, _startCpu, category, name, _argumentsAsJson(_arguments));
+    if (_flow != null) {
+      _reportFlowEvent(_start, _startCpu, category, "${_flow.id}", _flow._type,
+          _flow.id, _argumentsAsJson(null));
+    }
+  }
+
+  void set flow(Flow f) {
+    _flow = f;
+  }
+}
+
+String _argumentsAsJson(Map arguments) {
+  if ((arguments == null) || (arguments.length == 0)) {
+    // Fast path no arguments. Avoid calling jsonEncode.
+    return '{}';
+  }
+  return json.encode(arguments);
+}
+
+/// Returns true if the Dart Timeline stream is enabled.
+external bool _isDartStreamEnabled();
+
+/// Returns the next async task id.
+external int _getNextAsyncId();
+
+/// Returns the current value from the trace clock.
+external int _getTraceClock();
+
+/// Returns the current value from the thread CPU usage clock.
+external int _getThreadCpuClock();
+
+/// Reports an event for a task.
+external void _reportTaskEvent(int start, int taskId, String phase,
+    String category, String name, String argumentsAsJson);
+
+/// Reports a complete synchronous event.
+external void _reportCompleteEvent(int start, int startCpu, String category,
+    String name, String argumentsAsJson);
+
+/// Reports a flow event.
+external void _reportFlowEvent(int start, int startCpu, String category,
+    String name, int type, int id, String argumentsAsJson);
+
+/// Reports an instant event.
+external void _reportInstantEvent(
+    int start, String category, String name, String argumentsAsJson);
diff --git a/sdk_nnbd/lib/ffi/annotations.dart b/sdk_nnbd/lib/ffi/annotations.dart
new file mode 100644
index 0000000..d246b56
--- /dev/null
+++ b/sdk_nnbd/lib/ffi/annotations.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.ffi;
+
+class DartRepresentationOf {
+  /// Represents the Dart type corresponding to a [NativeType].
+  ///
+  /// [Int8]                               -> [int]
+  /// [Int16]                              -> [int]
+  /// [Int32]                              -> [int]
+  /// [Int64]                              -> [int]
+  /// [Uint8]                              -> [int]
+  /// [Uint16]                             -> [int]
+  /// [Uint32]                             -> [int]
+  /// [Uint64]                             -> [int]
+  /// [IntPtr]                             -> [int]
+  /// [Double]                             -> [double]
+  /// [Float]                              -> [double]
+  /// [Pointer]<T>                         -> [Pointer]<T>
+  /// [NativeFunction]<T1 Function(T2, T3) -> S1 Function(S2, S3)
+  ///    where DartRepresentationOf(Tn) -> Sn
+  /// T extends Struct<T>                  -> T
+  const DartRepresentationOf(String nativeType);
+}
+
+class Unsized {
+  const Unsized();
+}
+
+/// This [NativeType] does not have predefined size.
+///
+/// Unsized NativeTypes do not support [sizeOf] because their size is unknown.
+/// Consequently, [allocate], [Pointer.load], [Pointer.store], and
+/// [Pointer.elementAt] are not available.
+const unsized = const Unsized();
diff --git a/sdk_nnbd/lib/ffi/dynamic_library.dart b/sdk_nnbd/lib/ffi/dynamic_library.dart
new file mode 100644
index 0000000..ec68eeb
--- /dev/null
+++ b/sdk_nnbd/lib/ffi/dynamic_library.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.ffi;
+
+/// Represents a dynamically loaded C library.
+class DynamicLibrary {
+  /// Creates a dynamic library holding all global symbols.
+  ///
+  /// Any symbol in a library currently loaded with global visibility (including
+  /// the executable itself) may be resolved in this library.
+  ///
+  /// This feature is not available on Windows, instead an exception is thrown.
+  external factory DynamicLibrary.process();
+
+  /// Creates a dynamic library representing the running executable.
+  external factory DynamicLibrary.executable();
+
+  /// Loads a dynamic library file with local visibility.
+  ///
+  /// Throws an [ArgumentError] if loading the dynamic library fails.
+  external factory DynamicLibrary.open(String name);
+
+  /// Looks up a symbol in the [DynamicLibrary] and returns its address in
+  /// memory. Equivalent of dlsym.
+  ///
+  /// Throws an [ArgumentError] if it fails to lookup the symbol.
+  external Pointer<T> lookup<T extends NativeType>(String symbolName);
+
+  /// Helper that combines lookup and cast to a Dart function.
+  external F lookupFunction<T extends Function, F extends Function>(
+      String symbolName);
+
+  /// Dynamic libraries are equal if they load the same library.
+  external bool operator ==(other);
+
+  /// The hash code for a DynamicLibrary only depends on the loaded library
+  external int get hashCode;
+
+  /// The handle to the dynamic library.
+  external Pointer<Void> get handle;
+}
diff --git a/sdk_nnbd/lib/ffi/ffi.dart b/sdk_nnbd/lib/ffi/ffi.dart
new file mode 100644
index 0000000..a975a13
--- /dev/null
+++ b/sdk_nnbd/lib/ffi/ffi.dart
@@ -0,0 +1,144 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+/**
+ * Foreign Function Interface for interoperability with the C programming language.
+ *
+ * **NOTE**: Dart:FFI is in technical preview. The overall feature is incomplete,
+ * may contain issues, and breaking API changes are still expected.
+ *
+ * For further details, please see: https://dart.dev/server/c-interop
+ *
+ * {@category VM}
+ */
+library dart.ffi;
+
+import 'dart:typed_data' show TypedData;
+
+part "native_type.dart";
+part "annotations.dart";
+part "dynamic_library.dart";
+part "struct.dart";
+
+/// Number of bytes used by native type T.
+///
+/// Includes padding and alignment of structs.
+external int sizeOf<T extends NativeType>();
+
+/// Represents a pointer into the native C memory.
+final Pointer<Void> nullptr = Pointer.fromAddress(0);
+
+/// Represents a pointer into the native C memory. Cannot be extended.
+@pragma("vm:entry-point")
+class Pointer<T extends NativeType> extends NativeType {
+  /// Allocate [count] elements of type [T] on the native heap via malloc() and
+  /// return a pointer to the newly allocated memory.
+  ///
+  /// Note that the memory is uninitialized.
+  external factory Pointer.allocate({int count: 1});
+
+  /// Construction from raw integer.
+  external factory Pointer.fromAddress(int ptr);
+
+  /// Convert Dart function to a C function pointer, automatically marshalling
+  /// the arguments and return value
+  ///
+  /// If an exception is thrown while calling `f()`, the native function will
+  /// return `exceptionalReturn`, which must be assignable to return type of `f`.
+  ///
+  /// The returned function address can only be invoked on the mutator (main)
+  /// thread of the current isolate. It will abort the process if invoked on any
+  /// other thread.
+  ///
+  /// The pointer returned will remain alive for the duration of the current
+  /// isolate's lifetime. After the isolate it was created in is terminated,
+  /// invoking it from native code will cause undefined behavior.
+  ///
+  /// Does not accept dynamic invocations -- where the type of the receiver is
+  /// [dynamic].
+  external static Pointer<NativeFunction<T>> fromFunction<T extends Function>(
+      @DartRepresentationOf("T") Function f,
+      [Object exceptionalReturn]);
+
+  /// Store a Dart value into this location.
+  ///
+  /// The [value] is automatically marshalled into its native representation.
+  /// Note that ints which do not fit in [T] are truncated and sign extended,
+  /// and doubles stored into Pointer<[Float]> lose precision.
+  external void store(@DartRepresentationOf("T") Object value);
+
+  /// Load a Dart value from this location.
+  ///
+  /// The value is automatically unmarshalled from its native representation.
+  /// Loading a [Struct] reference returns a reference backed by native memory
+  /// (the same pointer as it's loaded from).
+  external R load<@DartRepresentationOf("T") R>();
+
+  /// Access to the raw pointer value.
+  /// On 32-bit systems, the upper 32-bits of the result are 0.
+  external int get address;
+
+  /// Pointer arithmetic (takes element size into account).
+  external Pointer<T> elementAt(int index);
+
+  /// Pointer arithmetic (byte offset).
+  // TODO(dacoharkes): remove this?
+  // https://github.com/dart-lang/sdk/issues/35883
+  external Pointer<T> offsetBy(int offsetInBytes);
+
+  /// Cast Pointer<T> to a Pointer<V>.
+  external Pointer<U> cast<U extends NativeType>();
+
+  /// Convert to Dart function, automatically marshalling the arguments
+  /// and return value.
+  ///
+  /// Can only be called on [Pointer]<[NativeFunction]>. Does not accept dynamic
+  /// invocations -- where the type of the receiver is [dynamic].
+  external R asFunction<@DartRepresentationOf("T") R extends Function>();
+
+  /// Free memory on the C heap pointed to by this pointer with free().
+  ///
+  /// Note that this zeros out the address.
+  external void free();
+
+  /// Creates an *external* typed data array backed by this pointer.
+  ///
+  /// The typed data array returned is only valid for as long as the backing
+  /// [Pointer]. Accessing any element of the type data array after this
+  /// [Pointer] has been [Pointer.free()]d will cause undefined behavior.
+  ///
+  /// Since [Pointer]s do not know their length, the size of the typed data is
+  /// controlled by `count`, in units of the size of the native type for this
+  /// [Pointer] (similarly to [Pointer.allocate]).
+  ///
+  /// The kind of TypedData produced depends on the native type:
+  ///
+  ///   Pointer<Int8> -> Int8List
+  ///   Pointer<Uint8> -> Uint8List
+  ///   etc. up to Int64/Uint64
+  ///   Pointer<IntPtr> -> Int32List/Int64List depending on platform word size
+  ///   Pointer<Float> -> Float32List
+  ///   Pointer<Double> -> Float64List
+  ///
+  /// Creation of a [Uint8ClampedList] is not supported. Creation of a typed
+  /// data from a [Pointer] to any other native type is not supported.
+  ///
+  /// The pointer must be aligned to a multiple of the native type's size.
+  //
+  // TODO(37773): Use extension methods to articulate more precise return types.
+  // We should still keep this member though as a generic way to access a
+  // Pointer of unknown type.
+  external TypedData asExternalTypedData({int count: 1});
+
+  /// Equality for Pointers only depends on their address.
+  bool operator ==(other) {
+    if (other == null) return false;
+    return address == other.address;
+  }
+
+  /// The hash code for a Pointer only depends on its address.
+  int get hashCode {
+    return address.hashCode;
+  }
+}
diff --git a/sdk_nnbd/lib/ffi/ffi_sources.gni b/sdk_nnbd/lib/ffi/ffi_sources.gni
new file mode 100644
index 0000000..d2bb279
--- /dev/null
+++ b/sdk_nnbd/lib/ffi/ffi_sources.gni
@@ -0,0 +1,13 @@
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+ffi_sdk_sources = [
+  "ffi.dart",
+
+  # The above file needs to be first as it lists the parts below.
+  "annotations.dart",
+  "dynamic_library.dart",
+  "native_type.dart",
+  "struct.dart"
+]
diff --git a/sdk_nnbd/lib/ffi/native_type.dart b/sdk_nnbd/lib/ffi/native_type.dart
new file mode 100644
index 0000000..aa30e63
--- /dev/null
+++ b/sdk_nnbd/lib/ffi/native_type.dart
@@ -0,0 +1,131 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.ffi;
+
+/// [NativeType]'s subtypes represent a native type in C.
+///
+/// [NativeType]'s subtypes are not constructible in the Dart code and serve
+/// purely as markers in type signatures.
+abstract class NativeType {
+  const NativeType();
+}
+
+/// [_NativeInteger]'s subtypes represent a native integer in C.
+///
+/// [_NativeInteger]'s subtypes are not constructible in the Dart code and serve
+/// purely as markers in type signatures.
+class _NativeInteger extends NativeType {
+  const _NativeInteger();
+}
+
+/// [_NativeDouble]'s subtypes represent a native float or double in C.
+///
+/// [_NativeDouble]'s subtypes are not constructible in the Dart code and serve
+/// purely as markers in type signatures.
+class _NativeDouble extends NativeType {
+  const _NativeDouble();
+}
+
+/// Represents a native signed 8 bit integer in C.
+///
+/// [Int8] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+class Int8 extends _NativeInteger {
+  const Int8();
+}
+
+/// Represents a native signed 16 bit integer in C.
+///
+/// [Int16] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+class Int16 extends _NativeInteger {
+  const Int16();
+}
+
+/// Represents a native signed 32 bit integer in C.
+///
+/// [Int32] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+class Int32 extends _NativeInteger {
+  const Int32();
+}
+
+/// Represents a native signed 64 bit integer in C.
+///
+/// [Int64] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+class Int64 extends _NativeInteger {
+  const Int64();
+}
+
+/// Represents a native unsigned 8 bit integer in C.
+///
+/// [Uint8] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+class Uint8 extends _NativeInteger {
+  const Uint8();
+}
+
+/// Represents a native unsigned 16 bit integer in C.
+///
+/// [Uint16] is not constructible in the Dart code and serves purely as marker
+/// in type signatures.
+class Uint16 extends _NativeInteger {
+  const Uint16();
+}
+
+/// Represents a native unsigned 32 bit integer in C.
+///
+/// [Uint32] is not constructible in the Dart code and serves purely as marker
+/// in type signatures.
+class Uint32 extends _NativeInteger {
+  const Uint32();
+}
+
+/// Represents a native unsigned 64 bit integer in C.
+///
+/// [Uint64] is not constructible in the Dart code and serves purely as marker
+/// in type signatures.
+class Uint64 extends _NativeInteger {
+  const Uint64();
+}
+
+/// Represents a native pointer-sized integer in C.
+///
+/// [IntPtr] is not constructible in the Dart code and serves purely as marker
+/// in type signatures.
+class IntPtr extends _NativeInteger {
+  const IntPtr();
+}
+
+/// Represents a native 32 bit float in C.
+///
+/// [Float] is not constructible in the Dart code and serves purely as marker
+/// in type signatures.
+class Float extends _NativeDouble {
+  const Float();
+}
+
+/// Represents a native 64 bit double in C.
+///
+/// [Double] is not constructible in the Dart code and serves purely as marker
+/// in type signatures.
+class Double extends _NativeDouble {
+  const Double();
+}
+
+/// Represents a void type in C.
+///
+/// [Void] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@unsized
+abstract class Void extends NativeType {}
+
+/// Represents a function type in C.
+///
+/// [NativeFunction] is not constructible in the Dart code and serves purely as
+/// marker in type signatures.
+@unsized
+abstract class NativeFunction<T extends Function> extends NativeType {}
diff --git a/sdk_nnbd/lib/ffi/struct.dart b/sdk_nnbd/lib/ffi/struct.dart
new file mode 100644
index 0000000..23124eb
--- /dev/null
+++ b/sdk_nnbd/lib/ffi/struct.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.ffi;
+
+/// This class is extended to define structs.
+///
+/// Fields in a struct, annotated with a subtype of [NativeType], are
+/// automatically transformed into wrappers to access the fields of the struct
+/// in native memory.
+///
+/// All fields in a struct must either have a type which extends [NativeType] or
+/// else have an annotation indicating the corresponding native type (e.g.
+/// "@Int32()" for "int").
+///
+/// Instances of a subclass of [Struct] have reference semantics and are backed
+/// by native memory. The may allocated via [Pointer.allocate] or loaded from a
+/// [Pointer], but not by a generative constructor.
+abstract class Struct<S extends NativeType> extends NativeType {
+  /// Returns the address backing the reference.
+  final Pointer<S> addressOf;
+
+  Struct() : addressOf = null;
+  Struct.fromPointer(this.addressOf);
+}
diff --git a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
new file mode 100644
index 0000000..303ec9e
--- /dev/null
+++ b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
@@ -0,0 +1,39523 @@
+/**
+ * HTML elements and other resources for web-based applications that need to
+ * interact with the browser and the DOM (Document Object Model).
+ *
+ * This library includes DOM element types, CSS styling, local storage,
+ * media, speech, events, and more.
+ * To get started,
+ * check out the [Element] class, the base class for many of the HTML
+ * DOM types.
+ *
+ * For information on writing web apps with Dart, see https://webdev.dartlang.org.
+ *
+ * {@category Web}
+ */
+library dart.dom.html;
+
+import 'dart:async';
+import 'dart:collection' hide LinkedList, LinkedListEntry;
+import 'dart:_internal' hide Symbol;
+import 'dart:html_common';
+import 'dart:indexed_db';
+import "dart:convert";
+import 'dart:math';
+import 'dart:_native_typed_data';
+import 'dart:typed_data';
+import 'dart:svg' as svg;
+import 'dart:svg' show Matrix;
+import 'dart:svg' show SvgSvgElement;
+import 'dart:web_audio' as web_audio;
+import 'dart:web_audio' show AudioBuffer, AudioTrack, AudioTrackList;
+import 'dart:web_gl' as gl;
+import 'dart:web_gl' show RenderingContext, RenderingContext2;
+import 'dart:web_sql';
+import 'dart:_foreign_helper' show JS, JS_INTERCEPTOR_CONSTANT;
+// Copyright (c) 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.
+
+// DO NOT EDIT - unless you are editing documentation as per:
+// https://code.google.com/p/dart/wiki/ContributingHTMLDocumentation
+// Auto-generated dart:html library.
+
+// Not actually used, but imported since dart:html can generate these objects.
+import 'dart:_js_helper'
+    show
+        convertDartClosureToJS,
+        Creates,
+        JavaScriptIndexingBehavior,
+        JSName,
+        Native,
+        Returns,
+        ForceInline,
+        findDispatchTagForInterceptorClass,
+        setNativeSubclassDispatchRecord,
+        makeLeafDispatchRecord,
+        registerGlobalObject,
+        applyExtension;
+import 'dart:_interceptors'
+    show
+        Interceptor,
+        JavaScriptFunction,
+        JSExtendableArray,
+        JSUInt31,
+        findInterceptorConstructorForType,
+        findConstructorForNativeSubclassType,
+        getNativeInterceptor,
+        setDispatchProperty;
+
+export 'dart:math' show Rectangle, Point;
+export 'dart:_internal' show HttpStatus;
+
+/**
+ * Top-level container for a web page, which is usually a browser tab or window.
+ *
+ * Each web page loaded in the browser has its own [Window], which is a
+ * container for the web page.
+ *
+ * If the web page has any `<iframe>` elements, then each `<iframe>` has its own
+ * [Window] object, which is accessible only to that `<iframe>`.
+ *
+ * See also:
+ *
+ *   * [Window](https://developer.mozilla.org/en-US/docs/Web/API/window) from MDN.
+ */
+Window get window => JS('Window', 'window');
+
+/**
+ * Root node for all content in a web page.
+ */
+HtmlDocument get document =>
+    JS('returns:HtmlDocument;depends:none;effects:none;gvn:true', 'document');
+
+// Supoort to convert JS Promise to a Dart Future.
+Future<T> promiseToFuture<T>(jsPromise) {
+  var completer = new Completer<T>();
+
+  var thenSuccessCode = (promiseValue) => completer.complete(promiseValue);
+  var thenErrorCode = (promiseError) => completer.completeError(promiseError);
+
+  JS("", "#.then(#, #)", jsPromise, convertDartClosureToJS(thenSuccessCode, 1),
+      convertDartClosureToJS(thenErrorCode, 1));
+
+  return completer.future;
+}
+
+// Supoort to convert JS Promise to a Dart Future<Map<String, dynamic>>.  Each property of the JS
+// object is added to the Map as a key of type String with a value of type dynamic.
+Future<Map<String, dynamic>> promiseToFutureAsMap(jsPromise) {
+  var completer = new Completer<Map<String, dynamic>>();
+
+  var thenSuccessCode = (promiseValue) =>
+      completer.complete(convertNativeToDart_Dictionary(promiseValue));
+  var thenErrorCode = (promiseError) => completer.completeError(promiseError);
+
+  JS("", "#.then(#, #)", jsPromise, convertDartClosureToJS(thenSuccessCode, 1),
+      convertDartClosureToJS(thenErrorCode, 1));
+
+  return completer.future;
+}
+
+// Workaround for tags like <cite> that lack their own Element subclass --
+// Dart issue 1990.
+@Native("HTMLElement")
+class HtmlElement extends Element implements NoncedElement {
+  factory HtmlElement() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  HtmlElement.created() : super.created();
+
+  // From NoncedElement
+  String nonce;
+}
+
+/**
+ * Emitted for any setlike IDL entry needs a callback signature.
+ * Today there is only one.
+ */
+typedef void FontFaceSetForEachCallback(
+    FontFace fontFace, FontFace fontFaceAgain, FontFaceSet set);
+
+WorkerGlobalScope get _workerSelf => JS('WorkerGlobalScope', 'self');
+// Copyright (c) 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.
+
+@Native("AbortPaymentEvent")
+class AbortPaymentEvent extends ExtendableEvent {
+  // To suppress missing implicit constructor warnings.
+  factory AbortPaymentEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory AbortPaymentEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return AbortPaymentEvent._create_1(type, eventInitDict_1);
+  }
+  static AbortPaymentEvent _create_1(type, eventInitDict) => JS(
+      'AbortPaymentEvent', 'new AbortPaymentEvent(#,#)', type, eventInitDict);
+
+  void respondWith(Future paymentAbortedResponse) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("AbsoluteOrientationSensor")
+class AbsoluteOrientationSensor extends OrientationSensor {
+  // To suppress missing implicit constructor warnings.
+  factory AbsoluteOrientationSensor._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory AbsoluteOrientationSensor([Map sensorOptions]) {
+    if (sensorOptions != null) {
+      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
+      return AbsoluteOrientationSensor._create_1(sensorOptions_1);
+    }
+    return AbsoluteOrientationSensor._create_2();
+  }
+  static AbsoluteOrientationSensor _create_1(sensorOptions) => JS(
+      'AbsoluteOrientationSensor',
+      'new AbsoluteOrientationSensor(#)',
+      sensorOptions);
+  static AbsoluteOrientationSensor _create_2() =>
+      JS('AbsoluteOrientationSensor', 'new AbsoluteOrientationSensor()');
+}
+// 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.
+
+abstract class AbstractWorker extends Interceptor implements EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory AbstractWorker._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `error` events to event
+   * handlers that are not necessarily instances of [AbstractWorker].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  /// Stream of `error` events handled by this [AbstractWorker].
+  Stream<Event> get onError => errorEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("Accelerometer")
+class Accelerometer extends Sensor {
+  // To suppress missing implicit constructor warnings.
+  factory Accelerometer._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory Accelerometer([Map sensorOptions]) {
+    if (sensorOptions != null) {
+      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
+      return Accelerometer._create_1(sensorOptions_1);
+    }
+    return Accelerometer._create_2();
+  }
+  static Accelerometer _create_1(sensorOptions) =>
+      JS('Accelerometer', 'new Accelerometer(#)', sensorOptions);
+  static Accelerometer _create_2() =>
+      JS('Accelerometer', 'new Accelerometer()');
+
+  final num x;
+
+  final num y;
+
+  final num z;
+}
+// Copyright (c) 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.
+
+@Native("AccessibleNode")
+class AccessibleNode extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory AccessibleNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> accessibleClickEvent =
+      const EventStreamProvider<Event>('accessibleclick');
+
+  static const EventStreamProvider<Event> accessibleContextMenuEvent =
+      const EventStreamProvider<Event>('accessiblecontextmenu');
+
+  static const EventStreamProvider<Event> accessibleDecrementEvent =
+      const EventStreamProvider<Event>('accessibledecrement');
+
+  static const EventStreamProvider<Event> accessibleFocusEvent =
+      const EventStreamProvider<Event>('accessiblefocus');
+
+  static const EventStreamProvider<Event> accessibleIncrementEvent =
+      const EventStreamProvider<Event>('accessibleincrement');
+
+  static const EventStreamProvider<Event> accessibleScrollIntoViewEvent =
+      const EventStreamProvider<Event>('accessiblescrollintoview');
+
+  factory AccessibleNode() {
+    return AccessibleNode._create_1();
+  }
+  static AccessibleNode _create_1() =>
+      JS('AccessibleNode', 'new AccessibleNode()');
+
+  AccessibleNode activeDescendant;
+
+  bool atomic;
+
+  String autocomplete;
+
+  bool busy;
+
+  String checked;
+
+  int colCount;
+
+  int colIndex;
+
+  int colSpan;
+
+  AccessibleNodeList controls;
+
+  String current;
+
+  AccessibleNodeList describedBy;
+
+  AccessibleNode details;
+
+  bool disabled;
+
+  AccessibleNode errorMessage;
+
+  bool expanded;
+
+  AccessibleNodeList flowTo;
+
+  String hasPopUp;
+
+  bool hidden;
+
+  String invalid;
+
+  String keyShortcuts;
+
+  String label;
+
+  AccessibleNodeList labeledBy;
+
+  int level;
+
+  String live;
+
+  bool modal;
+
+  bool multiline;
+
+  bool multiselectable;
+
+  String orientation;
+
+  AccessibleNodeList owns;
+
+  String placeholder;
+
+  int posInSet;
+
+  String pressed;
+
+  bool readOnly;
+
+  String relevant;
+
+  bool required;
+
+  String role;
+
+  String roleDescription;
+
+  int rowCount;
+
+  int rowIndex;
+
+  int rowSpan;
+
+  bool selected;
+
+  int setSize;
+
+  String sort;
+
+  num valueMax;
+
+  num valueMin;
+
+  num valueNow;
+
+  String valueText;
+
+  void appendChild(AccessibleNode child) native;
+
+  Stream<Event> get onAccessibleClick => accessibleClickEvent.forTarget(this);
+
+  Stream<Event> get onAccessibleContextMenu =>
+      accessibleContextMenuEvent.forTarget(this);
+
+  Stream<Event> get onAccessibleDecrement =>
+      accessibleDecrementEvent.forTarget(this);
+
+  Stream<Event> get onAccessibleFocus => accessibleFocusEvent.forTarget(this);
+
+  Stream<Event> get onAccessibleIncrement =>
+      accessibleIncrementEvent.forTarget(this);
+
+  Stream<Event> get onAccessibleScrollIntoView =>
+      accessibleScrollIntoViewEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("AccessibleNodeList")
+class AccessibleNodeList extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AccessibleNodeList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory AccessibleNodeList([List<AccessibleNode> nodes]) {
+    if (nodes != null) {
+      return AccessibleNodeList._create_1(nodes);
+    }
+    return AccessibleNodeList._create_2();
+  }
+  static AccessibleNodeList _create_1(nodes) =>
+      JS('AccessibleNodeList', 'new AccessibleNodeList(#)', nodes);
+  static AccessibleNodeList _create_2() =>
+      JS('AccessibleNodeList', 'new AccessibleNodeList()');
+
+  int length;
+
+  void __setter__(int index, AccessibleNode node) native;
+
+  void add(AccessibleNode node, AccessibleNode before) native;
+
+  AccessibleNode item(int index) native;
+
+  void remove(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("AmbientLightSensor")
+class AmbientLightSensor extends Sensor {
+  // To suppress missing implicit constructor warnings.
+  factory AmbientLightSensor._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory AmbientLightSensor([Map sensorOptions]) {
+    if (sensorOptions != null) {
+      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
+      return AmbientLightSensor._create_1(sensorOptions_1);
+    }
+    return AmbientLightSensor._create_2();
+  }
+  static AmbientLightSensor _create_1(sensorOptions) =>
+      JS('AmbientLightSensor', 'new AmbientLightSensor(#)', sensorOptions);
+  static AmbientLightSensor _create_2() =>
+      JS('AmbientLightSensor', 'new AmbientLightSensor()');
+
+  final num illuminance;
+}
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("HTMLAnchorElement")
+class AnchorElement extends HtmlElement implements HtmlHyperlinkElementUtils {
+  // To suppress missing implicit constructor warnings.
+  factory AnchorElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory AnchorElement({String href}) {
+    AnchorElement e = JS('returns:AnchorElement;creates:AnchorElement;new:true',
+        '#.createElement(#)', document, "a");
+    if (href != null) e.href = href;
+    return e;
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AnchorElement.created() : super.created();
+
+  String download;
+
+  String hreflang;
+
+  String referrerPolicy;
+
+  String rel;
+
+  String target;
+
+  String type;
+
+  // From HTMLHyperlinkElementUtils
+
+  String hash;
+
+  String host;
+
+  String hostname;
+
+  String href;
+
+  final String origin;
+
+  String password;
+
+  String pathname;
+
+  String port;
+
+  String protocol;
+
+  String search;
+
+  String username;
+
+  String toString() => JS('String', 'String(#)', this);
+}
+// Copyright (c) 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.
+
+@Native("Animation")
+class Animation extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory Animation._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> cancelEvent =
+      const EventStreamProvider<Event>('cancel');
+
+  static const EventStreamProvider<Event> finishEvent =
+      const EventStreamProvider<Event>('finish');
+
+  factory Animation(
+      [AnimationEffectReadOnly effect, AnimationTimeline timeline]) {
+    if (timeline != null) {
+      return Animation._create_1(effect, timeline);
+    }
+    if (effect != null) {
+      return Animation._create_2(effect);
+    }
+    return Animation._create_3();
+  }
+  static Animation _create_1(effect, timeline) =>
+      JS('Animation', 'new Animation(#,#)', effect, timeline);
+  static Animation _create_2(effect) =>
+      JS('Animation', 'new Animation(#)', effect);
+  static Animation _create_3() => JS('Animation', 'new Animation()');
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(document.body.animate)');
+
+  num currentTime;
+
+  AnimationEffectReadOnly effect;
+
+  Future<Animation> get finished =>
+      promiseToFuture<Animation>(JS("", "#.finished", this));
+
+  String id;
+
+  final String playState;
+
+  num playbackRate;
+
+  Future<Animation> get ready =>
+      promiseToFuture<Animation>(JS("", "#.ready", this));
+
+  num startTime;
+
+  final AnimationTimeline timeline;
+
+  void cancel() native;
+
+  void finish() native;
+
+  void pause() native;
+
+  void play() native;
+
+  void reverse() native;
+
+  Stream<Event> get onCancel => cancelEvent.forTarget(this);
+
+  Stream<Event> get onFinish => finishEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("AnimationEffectReadOnly")
+class AnimationEffectReadOnly extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AnimationEffectReadOnly._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final AnimationEffectTimingReadOnly timing;
+
+  Map getComputedTiming() {
+    return convertNativeToDart_Dictionary(_getComputedTiming_1());
+  }
+
+  @JSName('getComputedTiming')
+  _getComputedTiming_1() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("AnimationEffectTiming")
+class AnimationEffectTiming extends AnimationEffectTimingReadOnly {
+  // To suppress missing implicit constructor warnings.
+  factory AnimationEffectTiming._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  // Shadowing definition.
+  num get delay => JS("num", "#.delay", this);
+
+  set delay(num value) {
+    JS("void", "#.delay = #", this, value);
+  }
+
+  // Shadowing definition.
+  String get direction => JS("String", "#.direction", this);
+
+  set direction(String value) {
+    JS("void", "#.direction = #", this, value);
+  }
+
+  // Shadowing definition.
+  Object get duration => JS("Object", "#.duration", this);
+
+  set duration(Object value) {
+    JS("void", "#.duration = #", this, value);
+  }
+
+  // Shadowing definition.
+  String get easing => JS("String", "#.easing", this);
+
+  set easing(String value) {
+    JS("void", "#.easing = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get endDelay => JS("num", "#.endDelay", this);
+
+  set endDelay(num value) {
+    JS("void", "#.endDelay = #", this, value);
+  }
+
+  // Shadowing definition.
+  String get fill => JS("String", "#.fill", this);
+
+  set fill(String value) {
+    JS("void", "#.fill = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get iterationStart => JS("num", "#.iterationStart", this);
+
+  set iterationStart(num value) {
+    JS("void", "#.iterationStart = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get iterations => JS("num", "#.iterations", this);
+
+  set iterations(num value) {
+    JS("void", "#.iterations = #", this, value);
+  }
+}
+// Copyright (c) 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.
+
+@Native("AnimationEffectTimingReadOnly")
+class AnimationEffectTimingReadOnly extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AnimationEffectTimingReadOnly._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num delay;
+
+  final String direction;
+
+  final Object duration;
+
+  final String easing;
+
+  final num endDelay;
+
+  final String fill;
+
+  final num iterationStart;
+
+  final num iterations;
+}
+// Copyright (c) 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.
+
+@Native("AnimationEvent")
+class AnimationEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory AnimationEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory AnimationEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return AnimationEvent._create_1(type, eventInitDict_1);
+    }
+    return AnimationEvent._create_2(type);
+  }
+  static AnimationEvent _create_1(type, eventInitDict) =>
+      JS('AnimationEvent', 'new AnimationEvent(#,#)', type, eventInitDict);
+  static AnimationEvent _create_2(type) =>
+      JS('AnimationEvent', 'new AnimationEvent(#)', type);
+
+  final String animationName;
+
+  final num elapsedTime;
+}
+// Copyright (c) 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.
+
+@Native("AnimationPlaybackEvent")
+class AnimationPlaybackEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory AnimationPlaybackEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory AnimationPlaybackEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return AnimationPlaybackEvent._create_1(type, eventInitDict_1);
+    }
+    return AnimationPlaybackEvent._create_2(type);
+  }
+  static AnimationPlaybackEvent _create_1(type, eventInitDict) => JS(
+      'AnimationPlaybackEvent',
+      'new AnimationPlaybackEvent(#,#)',
+      type,
+      eventInitDict);
+  static AnimationPlaybackEvent _create_2(type) =>
+      JS('AnimationPlaybackEvent', 'new AnimationPlaybackEvent(#)', type);
+
+  final num currentTime;
+
+  final num timelineTime;
+}
+// Copyright (c) 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.
+
+@Native("AnimationTimeline")
+class AnimationTimeline extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AnimationTimeline._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num currentTime;
+}
+// Copyright (c) 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.
+
+@Native("AnimationWorkletGlobalScope")
+class AnimationWorkletGlobalScope extends WorkletGlobalScope {
+  // To suppress missing implicit constructor warnings.
+  factory AnimationWorkletGlobalScope._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  void registerAnimator(String name, Object animatorConstructor) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * ApplicationCache is accessed via [Window.applicationCache].
+ */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.OPERA)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("ApplicationCache,DOMApplicationCache,OfflineResourceList")
+class ApplicationCache extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory ApplicationCache._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `cached` events to event
+   * handlers that are not necessarily instances of [ApplicationCache].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> cachedEvent =
+      const EventStreamProvider<Event>('cached');
+
+  /**
+   * Static factory designed to expose `checking` events to event
+   * handlers that are not necessarily instances of [ApplicationCache].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> checkingEvent =
+      const EventStreamProvider<Event>('checking');
+
+  /**
+   * Static factory designed to expose `downloading` events to event
+   * handlers that are not necessarily instances of [ApplicationCache].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> downloadingEvent =
+      const EventStreamProvider<Event>('downloading');
+
+  /**
+   * Static factory designed to expose `error` events to event
+   * handlers that are not necessarily instances of [ApplicationCache].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  /**
+   * Static factory designed to expose `noupdate` events to event
+   * handlers that are not necessarily instances of [ApplicationCache].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> noUpdateEvent =
+      const EventStreamProvider<Event>('noupdate');
+
+  /**
+   * Static factory designed to expose `obsolete` events to event
+   * handlers that are not necessarily instances of [ApplicationCache].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> obsoleteEvent =
+      const EventStreamProvider<Event>('obsolete');
+
+  /**
+   * Static factory designed to expose `progress` events to event
+   * handlers that are not necessarily instances of [ApplicationCache].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> progressEvent =
+      const EventStreamProvider<ProgressEvent>('progress');
+
+  /**
+   * Static factory designed to expose `updateready` events to event
+   * handlers that are not necessarily instances of [ApplicationCache].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> updateReadyEvent =
+      const EventStreamProvider<Event>('updateready');
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(window.applicationCache)');
+
+  static const int CHECKING = 2;
+
+  static const int DOWNLOADING = 3;
+
+  static const int IDLE = 1;
+
+  static const int OBSOLETE = 5;
+
+  static const int UNCACHED = 0;
+
+  static const int UPDATEREADY = 4;
+
+  final int status;
+
+  void abort() native;
+
+  void swapCache() native;
+
+  void update() native;
+
+  /// Stream of `cached` events handled by this [ApplicationCache].
+  Stream<Event> get onCached => cachedEvent.forTarget(this);
+
+  /// Stream of `checking` events handled by this [ApplicationCache].
+  Stream<Event> get onChecking => checkingEvent.forTarget(this);
+
+  /// Stream of `downloading` events handled by this [ApplicationCache].
+  Stream<Event> get onDownloading => downloadingEvent.forTarget(this);
+
+  /// Stream of `error` events handled by this [ApplicationCache].
+  Stream<Event> get onError => errorEvent.forTarget(this);
+
+  /// Stream of `noupdate` events handled by this [ApplicationCache].
+  Stream<Event> get onNoUpdate => noUpdateEvent.forTarget(this);
+
+  /// Stream of `obsolete` events handled by this [ApplicationCache].
+  Stream<Event> get onObsolete => obsoleteEvent.forTarget(this);
+
+  /// Stream of `progress` events handled by this [ApplicationCache].
+  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
+
+  /// Stream of `updateready` events handled by this [ApplicationCache].
+  Stream<Event> get onUpdateReady => updateReadyEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("ApplicationCacheErrorEvent")
+class ApplicationCacheErrorEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory ApplicationCacheErrorEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ApplicationCacheErrorEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return ApplicationCacheErrorEvent._create_1(type, eventInitDict_1);
+    }
+    return ApplicationCacheErrorEvent._create_2(type);
+  }
+  static ApplicationCacheErrorEvent _create_1(type, eventInitDict) => JS(
+      'ApplicationCacheErrorEvent',
+      'new ApplicationCacheErrorEvent(#,#)',
+      type,
+      eventInitDict);
+  static ApplicationCacheErrorEvent _create_2(type) => JS(
+      'ApplicationCacheErrorEvent', 'new ApplicationCacheErrorEvent(#)', type);
+
+  final String message;
+
+  final String reason;
+
+  final int status;
+
+  final String url;
+}
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * DOM Area Element, which links regions of an image map with a hyperlink.
+ *
+ * The element can also define an uninteractive region of the map.
+ *
+ * See also:
+ *
+ * * [`<area>`](https://developer.mozilla.org/en-US/docs/HTML/Element/area)
+ * on MDN.
+ */
+@Native("HTMLAreaElement")
+class AreaElement extends HtmlElement implements HtmlHyperlinkElementUtils {
+  // To suppress missing implicit constructor warnings.
+  factory AreaElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory AreaElement() => JS(
+      'returns:AreaElement;creates:AreaElement;new:true',
+      '#.createElement(#)',
+      document,
+      "area");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AreaElement.created() : super.created();
+
+  String alt;
+
+  String coords;
+
+  String download;
+
+  String referrerPolicy;
+
+  String rel;
+
+  String shape;
+
+  String target;
+
+  // From HTMLHyperlinkElementUtils
+
+  String hash;
+
+  String host;
+
+  String hostname;
+
+  String href;
+
+  final String origin;
+
+  String password;
+
+  String pathname;
+
+  String port;
+
+  String protocol;
+
+  String search;
+
+  String username;
+
+  String toString() => JS('String', 'String(#)', this);
+}
+// Copyright (c) 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.
+
+@Native("HTMLAudioElement")
+class AudioElement extends MediaElement {
+  factory AudioElement._([String src]) {
+    if (src != null) {
+      return AudioElement._create_1(src);
+    }
+    return AudioElement._create_2();
+  }
+  static AudioElement _create_1(src) => JS('AudioElement', 'new Audio(#)', src);
+  static AudioElement _create_2() => JS('AudioElement', 'new Audio()');
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AudioElement.created() : super.created();
+
+  factory AudioElement([String src]) => new AudioElement._(src);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("AuthenticatorAssertionResponse")
+class AuthenticatorAssertionResponse extends AuthenticatorResponse {
+  // To suppress missing implicit constructor warnings.
+  factory AuthenticatorAssertionResponse._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final ByteBuffer authenticatorData;
+
+  final ByteBuffer signature;
+}
+// Copyright (c) 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.
+
+@Native("AuthenticatorAttestationResponse")
+class AuthenticatorAttestationResponse extends AuthenticatorResponse {
+  // To suppress missing implicit constructor warnings.
+  factory AuthenticatorAttestationResponse._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final ByteBuffer attestationObject;
+}
+// Copyright (c) 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.
+
+@Native("AuthenticatorResponse")
+class AuthenticatorResponse extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AuthenticatorResponse._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('clientDataJSON')
+  final ByteBuffer clientDataJson;
+}
+// Copyright (c) 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.
+
+@Native("HTMLBRElement")
+class BRElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory BRElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory BRElement() => JS('returns:BRElement;creates:BRElement;new:true',
+      '#.createElement(#)', document, "br");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  BRElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Native("BackgroundFetchClickEvent")
+class BackgroundFetchClickEvent extends BackgroundFetchEvent {
+  // To suppress missing implicit constructor warnings.
+  factory BackgroundFetchClickEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory BackgroundFetchClickEvent(String type, Map init) {
+    var init_1 = convertDartToNative_Dictionary(init);
+    return BackgroundFetchClickEvent._create_1(type, init_1);
+  }
+  static BackgroundFetchClickEvent _create_1(type, init) => JS(
+      'BackgroundFetchClickEvent',
+      'new BackgroundFetchClickEvent(#,#)',
+      type,
+      init);
+
+  final String state;
+}
+// Copyright (c) 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.
+
+@Native("BackgroundFetchEvent")
+class BackgroundFetchEvent extends ExtendableEvent {
+  // To suppress missing implicit constructor warnings.
+  factory BackgroundFetchEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory BackgroundFetchEvent(String type, Map init) {
+    var init_1 = convertDartToNative_Dictionary(init);
+    return BackgroundFetchEvent._create_1(type, init_1);
+  }
+  static BackgroundFetchEvent _create_1(type, init) =>
+      JS('BackgroundFetchEvent', 'new BackgroundFetchEvent(#,#)', type, init);
+
+  final String id;
+}
+// Copyright (c) 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.
+
+@Native("BackgroundFetchFailEvent")
+class BackgroundFetchFailEvent extends BackgroundFetchEvent {
+  // To suppress missing implicit constructor warnings.
+  factory BackgroundFetchFailEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory BackgroundFetchFailEvent(String type, Map init) {
+    var init_1 = convertDartToNative_Dictionary(init);
+    return BackgroundFetchFailEvent._create_1(type, init_1);
+  }
+  static BackgroundFetchFailEvent _create_1(type, init) => JS(
+      'BackgroundFetchFailEvent',
+      'new BackgroundFetchFailEvent(#,#)',
+      type,
+      init);
+
+  final List<BackgroundFetchSettledFetch> fetches;
+}
+// Copyright (c) 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.
+
+@Native("BackgroundFetchFetch")
+class BackgroundFetchFetch extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory BackgroundFetchFetch._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final _Request request;
+}
+// Copyright (c) 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.
+
+@Native("BackgroundFetchManager")
+class BackgroundFetchManager extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory BackgroundFetchManager._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Future<BackgroundFetchRegistration> fetch(String id, Object requests,
+      [Map options]) {
+    var options_dict = null;
+    if (options != null) {
+      options_dict = convertDartToNative_Dictionary(options);
+    }
+    return promiseToFuture<BackgroundFetchRegistration>(
+        JS("", "#.fetch(#, #, #)", this, id, requests, options_dict));
+  }
+
+  Future<BackgroundFetchRegistration> get(String id) =>
+      promiseToFuture<BackgroundFetchRegistration>(
+          JS("", "#.get(#)", this, id));
+
+  Future<List<String>> getIds() =>
+      promiseToFuture<List<String>>(JS("", "#.getIds()", this));
+}
+// Copyright (c) 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.
+
+@Native("BackgroundFetchRegistration")
+class BackgroundFetchRegistration extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory BackgroundFetchRegistration._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int downloadTotal;
+
+  final int downloaded;
+
+  final String id;
+
+  final String title;
+
+  final int totalDownloadSize;
+
+  final int uploadTotal;
+
+  final int uploaded;
+
+  Future<bool> abort() => promiseToFuture<bool>(JS("", "#.abort()", this));
+}
+// Copyright (c) 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.
+
+@Native("BackgroundFetchSettledFetch")
+class BackgroundFetchSettledFetch extends BackgroundFetchFetch {
+  // To suppress missing implicit constructor warnings.
+  factory BackgroundFetchSettledFetch._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory BackgroundFetchSettledFetch(_Request request, _Response response) {
+    return BackgroundFetchSettledFetch._create_1(request, response);
+  }
+  static BackgroundFetchSettledFetch _create_1(request, response) => JS(
+      'BackgroundFetchSettledFetch',
+      'new BackgroundFetchSettledFetch(#,#)',
+      request,
+      response);
+
+  final _Response response;
+}
+// Copyright (c) 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.
+
+@Native("BackgroundFetchedEvent")
+class BackgroundFetchedEvent extends BackgroundFetchEvent {
+  // To suppress missing implicit constructor warnings.
+  factory BackgroundFetchedEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory BackgroundFetchedEvent(String type, Map init) {
+    var init_1 = convertDartToNative_Dictionary(init);
+    return BackgroundFetchedEvent._create_1(type, init_1);
+  }
+  static BackgroundFetchedEvent _create_1(type, init) => JS(
+      'BackgroundFetchedEvent', 'new BackgroundFetchedEvent(#,#)', type, init);
+
+  final List<BackgroundFetchSettledFetch> fetches;
+
+  Future updateUI(String title) =>
+      promiseToFuture(JS("", "#.updateUI(#)", this, title));
+}
+// Copyright (c) 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.
+
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#barprop
+@deprecated // standard
+@Native("BarProp")
+class BarProp extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory BarProp._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool visible;
+}
+// Copyright (c) 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.
+
+@Native("BarcodeDetector")
+class BarcodeDetector extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory BarcodeDetector._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory BarcodeDetector() {
+    return BarcodeDetector._create_1();
+  }
+  static BarcodeDetector _create_1() =>
+      JS('BarcodeDetector', 'new BarcodeDetector()');
+
+  Future<List<DetectedBarcode>> detect(/*ImageBitmapSource*/ image) =>
+      promiseToFuture<List<DetectedBarcode>>(
+          JS("", "#.detect(#)", this, image));
+}
+// Copyright (c) 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.
+
+@Native("HTMLBaseElement")
+class BaseElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory BaseElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory BaseElement() => JS(
+      'returns:BaseElement;creates:BaseElement;new:true',
+      '#.createElement(#)',
+      document,
+      "base");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  BaseElement.created() : super.created();
+
+  String href;
+
+  String target;
+}
+// Copyright (c) 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.
+
+@Native("BatteryManager")
+class BatteryManager extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory BatteryManager._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool charging;
+
+  final num chargingTime;
+
+  final num dischargingTime;
+
+  final num level;
+}
+// Copyright (c) 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.
+
+@Native("BeforeInstallPromptEvent")
+class BeforeInstallPromptEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory BeforeInstallPromptEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory BeforeInstallPromptEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return BeforeInstallPromptEvent._create_1(type, eventInitDict_1);
+    }
+    return BeforeInstallPromptEvent._create_2(type);
+  }
+  static BeforeInstallPromptEvent _create_1(type, eventInitDict) => JS(
+      'BeforeInstallPromptEvent',
+      'new BeforeInstallPromptEvent(#,#)',
+      type,
+      eventInitDict);
+  static BeforeInstallPromptEvent _create_2(type) =>
+      JS('BeforeInstallPromptEvent', 'new BeforeInstallPromptEvent(#)', type);
+
+  final List<String> platforms;
+
+  Future<Map<String, dynamic>> get userChoice =>
+      promiseToFutureAsMap(JS("", "#.userChoice", this));
+
+  Future prompt() => promiseToFuture(JS("", "#.prompt()", this));
+}
+// Copyright (c) 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.
+
+@Native("BeforeUnloadEvent")
+class BeforeUnloadEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory BeforeUnloadEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  // Shadowing definition.
+  String get returnValue => JS("String", "#.returnValue", this);
+
+  set returnValue(String value) {
+    JS("void", "#.returnValue = #", this, value);
+  }
+}
+// Copyright (c) 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.
+
+@Native("Blob")
+class Blob extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Blob._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int size;
+
+  final String type;
+
+  Blob slice([int start, int end, String contentType]) native;
+
+  factory Blob(List blobParts, [String type, String endings]) {
+    // TODO: validate that blobParts is a JS Array and convert if not.
+    // TODO: any coercions on the elements of blobParts, e.g. coerce a typed
+    // array to ArrayBuffer if it is a total view.
+    if (type == null && endings == null) {
+      return _create_1(blobParts);
+    }
+    var bag = _create_bag();
+    if (type != null) _bag_set(bag, 'type', type);
+    if (endings != null) _bag_set(bag, 'endings', endings);
+    return _create_2(blobParts, bag);
+  }
+
+  static _create_1(parts) => JS('Blob', 'new self.Blob(#)', parts);
+  static _create_2(parts, bag) => JS('Blob', 'new self.Blob(#, #)', parts, bag);
+
+  static _create_bag() => JS('var', '{}');
+  static _bag_set(bag, key, value) {
+    JS('void', '#[#] = #', bag, key, value);
+  }
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void BlobCallback(Blob blob);
+// Copyright (c) 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.
+
+@Native("BlobEvent")
+class BlobEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory BlobEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory BlobEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return BlobEvent._create_1(type, eventInitDict_1);
+  }
+  static BlobEvent _create_1(type, eventInitDict) =>
+      JS('BlobEvent', 'new BlobEvent(#,#)', type, eventInitDict);
+
+  final Blob data;
+
+  final num timecode;
+}
+// Copyright (c) 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.
+
+@Native("BluetoothRemoteGATTDescriptor")
+class BluetoothRemoteGattDescriptor extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory BluetoothRemoteGattDescriptor._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final _BluetoothRemoteGATTCharacteristic characteristic;
+
+  final String uuid;
+
+  final ByteData value;
+
+  Future readValue() => promiseToFuture(JS("", "#.readValue()", this));
+
+  Future writeValue(/*BufferSource*/ value) =>
+      promiseToFuture(JS("", "#.writeValue(#)", this, value));
+}
+// Copyright (c) 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.
+
+@Native("Body")
+class Body extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Body._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool bodyUsed;
+
+  Future arrayBuffer() => promiseToFuture(JS("", "#.arrayBuffer()", this));
+
+  Future<Blob> blob() => promiseToFuture<Blob>(JS("", "#.blob()", this));
+
+  Future<FormData> formData() =>
+      promiseToFuture<FormData>(JS("", "#.formData()", this));
+
+  Future json() => promiseToFuture(JS("", "#.json()", this));
+
+  Future<String> text() => promiseToFuture<String>(JS("", "#.text()", this));
+}
+// Copyright (c) 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.
+
+@Native("HTMLBodyElement")
+class BodyElement extends HtmlElement implements WindowEventHandlers {
+  // To suppress missing implicit constructor warnings.
+  factory BodyElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `blur` events to event
+   * handlers that are not necessarily instances of [BodyElement].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> blurEvent =
+      const EventStreamProvider<Event>('blur');
+
+  /**
+   * Static factory designed to expose `error` events to event
+   * handlers that are not necessarily instances of [BodyElement].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  /**
+   * Static factory designed to expose `focus` events to event
+   * handlers that are not necessarily instances of [BodyElement].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> focusEvent =
+      const EventStreamProvider<Event>('focus');
+
+  /**
+   * Static factory designed to expose `hashchange` events to event
+   * handlers that are not necessarily instances of [BodyElement].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> hashChangeEvent =
+      const EventStreamProvider<Event>('hashchange');
+
+  /**
+   * Static factory designed to expose `load` events to event
+   * handlers that are not necessarily instances of [BodyElement].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> loadEvent =
+      const EventStreamProvider<Event>('load');
+
+  /**
+   * Static factory designed to expose `message` events to event
+   * handlers that are not necessarily instances of [BodyElement].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MessageEvent> messageEvent =
+      const EventStreamProvider<MessageEvent>('message');
+
+  /**
+   * Static factory designed to expose `offline` events to event
+   * handlers that are not necessarily instances of [BodyElement].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> offlineEvent =
+      const EventStreamProvider<Event>('offline');
+
+  /**
+   * Static factory designed to expose `online` events to event
+   * handlers that are not necessarily instances of [BodyElement].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> onlineEvent =
+      const EventStreamProvider<Event>('online');
+
+  /**
+   * Static factory designed to expose `popstate` events to event
+   * handlers that are not necessarily instances of [BodyElement].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<PopStateEvent> popStateEvent =
+      const EventStreamProvider<PopStateEvent>('popstate');
+
+  /**
+   * Static factory designed to expose `resize` events to event
+   * handlers that are not necessarily instances of [BodyElement].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> resizeEvent =
+      const EventStreamProvider<Event>('resize');
+
+  static const EventStreamProvider<Event> scrollEvent =
+      const EventStreamProvider<Event>('scroll');
+
+  /**
+   * Static factory designed to expose `storage` events to event
+   * handlers that are not necessarily instances of [BodyElement].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<StorageEvent> storageEvent =
+      const EventStreamProvider<StorageEvent>('storage');
+
+  /**
+   * Static factory designed to expose `unload` events to event
+   * handlers that are not necessarily instances of [BodyElement].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> unloadEvent =
+      const EventStreamProvider<Event>('unload');
+
+  factory BodyElement() => JS(
+      'returns:BodyElement;creates:BodyElement;new:true',
+      '#.createElement(#)',
+      document,
+      "body");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  BodyElement.created() : super.created();
+
+  /// Stream of `blur` events handled by this [BodyElement].
+  ElementStream<Event> get onBlur => blurEvent.forElement(this);
+
+  /// Stream of `error` events handled by this [BodyElement].
+  ElementStream<Event> get onError => errorEvent.forElement(this);
+
+  /// Stream of `focus` events handled by this [BodyElement].
+  ElementStream<Event> get onFocus => focusEvent.forElement(this);
+
+  /// Stream of `hashchange` events handled by this [BodyElement].
+  ElementStream<Event> get onHashChange => hashChangeEvent.forElement(this);
+
+  /// Stream of `load` events handled by this [BodyElement].
+  ElementStream<Event> get onLoad => loadEvent.forElement(this);
+
+  /// Stream of `message` events handled by this [BodyElement].
+  ElementStream<MessageEvent> get onMessage => messageEvent.forElement(this);
+
+  /// Stream of `offline` events handled by this [BodyElement].
+  ElementStream<Event> get onOffline => offlineEvent.forElement(this);
+
+  /// Stream of `online` events handled by this [BodyElement].
+  ElementStream<Event> get onOnline => onlineEvent.forElement(this);
+
+  /// Stream of `popstate` events handled by this [BodyElement].
+  ElementStream<PopStateEvent> get onPopState => popStateEvent.forElement(this);
+
+  /// Stream of `resize` events handled by this [BodyElement].
+  ElementStream<Event> get onResize => resizeEvent.forElement(this);
+
+  ElementStream<Event> get onScroll => scrollEvent.forElement(this);
+
+  /// Stream of `storage` events handled by this [BodyElement].
+  ElementStream<StorageEvent> get onStorage => storageEvent.forElement(this);
+
+  /// Stream of `unload` events handled by this [BodyElement].
+  ElementStream<Event> get onUnload => unloadEvent.forElement(this);
+}
+// Copyright (c) 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.
+
+@Native("BroadcastChannel")
+class BroadcastChannel extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory BroadcastChannel._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<MessageEvent> messageEvent =
+      const EventStreamProvider<MessageEvent>('message');
+
+  factory BroadcastChannel(String name) {
+    return BroadcastChannel._create_1(name);
+  }
+  static BroadcastChannel _create_1(name) =>
+      JS('BroadcastChannel', 'new BroadcastChannel(#)', name);
+
+  final String name;
+
+  void close() native;
+
+  void postMessage(Object message) native;
+
+  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("BudgetState")
+class BudgetState extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory BudgetState._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num budgetAt;
+
+  final int time;
+}
+// Copyright (c) 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.
+
+@Native("HTMLButtonElement")
+class ButtonElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory ButtonElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ButtonElement() => JS(
+      'returns:ButtonElement;creates:ButtonElement;new:true',
+      '#.createElement(#)',
+      document,
+      "button");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ButtonElement.created() : super.created();
+
+  bool autofocus;
+
+  bool disabled;
+
+  final FormElement form;
+
+  String formAction;
+
+  String formEnctype;
+
+  String formMethod;
+
+  bool formNoValidate;
+
+  String formTarget;
+
+  @Unstable()
+  @Returns('NodeList|Null')
+  @Creates('NodeList')
+  final List<Node> labels;
+
+  String name;
+
+  String type;
+
+  final String validationMessage;
+
+  final ValidityState validity;
+
+  String value;
+
+  final bool willValidate;
+
+  bool checkValidity() native;
+
+  bool reportValidity() native;
+
+  void setCustomValidity(String error) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// http://dom.spec.whatwg.org/#cdatasection
+@deprecated // deprecated
+@Native("CDATASection")
+class CDataSection extends Text {
+  // To suppress missing implicit constructor warnings.
+  factory CDataSection._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("CacheStorage")
+class CacheStorage extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CacheStorage._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Future delete(String cacheName) =>
+      promiseToFuture(JS("", "#.delete(#)", this, cacheName));
+
+  Future has(String cacheName) =>
+      promiseToFuture(JS("", "#.has(#)", this, cacheName));
+
+  Future keys() => promiseToFuture(JS("", "#.keys()", this));
+
+  Future match(/*RequestInfo*/ request, [Map options]) {
+    var options_dict = null;
+    if (options != null) {
+      options_dict = convertDartToNative_Dictionary(options);
+    }
+    return promiseToFuture(
+        JS("", "#.match(#, #)", this, request, options_dict));
+  }
+
+  Future open(String cacheName) =>
+      promiseToFuture(JS("", "#.open(#)", this, cacheName));
+}
+// Copyright (c) 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.
+
+@Native("CanMakePaymentEvent")
+class CanMakePaymentEvent extends ExtendableEvent {
+  // To suppress missing implicit constructor warnings.
+  factory CanMakePaymentEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory CanMakePaymentEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return CanMakePaymentEvent._create_1(type, eventInitDict_1);
+  }
+  static CanMakePaymentEvent _create_1(type, eventInitDict) => JS(
+      'CanMakePaymentEvent',
+      'new CanMakePaymentEvent(#,#)',
+      type,
+      eventInitDict);
+
+  final List methodData;
+
+  final List modifiers;
+
+  final String paymentRequestOrigin;
+
+  final String topLevelOrigin;
+
+  void respondWith(Future canMakePaymentResponse) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("CanvasCaptureMediaStreamTrack")
+class CanvasCaptureMediaStreamTrack extends MediaStreamTrack {
+  // To suppress missing implicit constructor warnings.
+  factory CanvasCaptureMediaStreamTrack._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final CanvasElement canvas;
+
+  void requestFrame() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("HTMLCanvasElement")
+class CanvasElement extends HtmlElement implements CanvasImageSource {
+  // To suppress missing implicit constructor warnings.
+  factory CanvasElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `webglcontextlost` events to event
+   * handlers that are not necessarily instances of [CanvasElement].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<gl.ContextEvent> webGlContextLostEvent =
+      const EventStreamProvider<gl.ContextEvent>('webglcontextlost');
+
+  /**
+   * Static factory designed to expose `webglcontextrestored` events to event
+   * handlers that are not necessarily instances of [CanvasElement].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<gl.ContextEvent> webGlContextRestoredEvent =
+      const EventStreamProvider<gl.ContextEvent>('webglcontextrestored');
+
+  factory CanvasElement({int width, int height}) {
+    CanvasElement e = JS('returns:CanvasElement;creates:CanvasElement;new:true',
+        '#.createElement(#)', document, "canvas");
+    if (width != null) e.width = width;
+    if (height != null) e.height = height;
+    return e;
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  CanvasElement.created() : super.created();
+
+  /// The height of this canvas element in CSS pixels.
+  int height;
+
+  /// The width of this canvas element in CSS pixels.
+  int width;
+
+  MediaStream captureStream([num frameRate]) native;
+
+  @Creates('CanvasRenderingContext2D|RenderingContext|RenderingContext2')
+  @Returns('CanvasRenderingContext2D|RenderingContext|RenderingContext2|Null')
+  Object getContext(String contextId, [Map attributes]) {
+    if (attributes != null) {
+      var attributes_1 = convertDartToNative_Dictionary(attributes);
+      return _getContext_1(contextId, attributes_1);
+    }
+    return _getContext_2(contextId);
+  }
+
+  @JSName('getContext')
+  @Creates('CanvasRenderingContext2D|RenderingContext|RenderingContext2')
+  @Returns('CanvasRenderingContext2D|RenderingContext|RenderingContext2|Null')
+  Object _getContext_1(contextId, attributes) native;
+  @JSName('getContext')
+  @Creates('CanvasRenderingContext2D|RenderingContext|RenderingContext2')
+  @Returns('CanvasRenderingContext2D|RenderingContext|RenderingContext2|Null')
+  Object _getContext_2(contextId) native;
+
+  @JSName('toDataURL')
+  String _toDataUrl(String type, [arguments_OR_quality]) native;
+
+  OffscreenCanvas transferControlToOffscreen() native;
+
+  /// Stream of `webglcontextlost` events handled by this [CanvasElement].
+  ElementStream<gl.ContextEvent> get onWebGlContextLost =>
+      webGlContextLostEvent.forElement(this);
+
+  /// Stream of `webglcontextrestored` events handled by this [CanvasElement].
+  ElementStream<gl.ContextEvent> get onWebGlContextRestored =>
+      webGlContextRestoredEvent.forElement(this);
+
+  /** An API for drawing on this canvas. */
+  CanvasRenderingContext2D get context2D =>
+      JS('Null|CanvasRenderingContext2D', '#.getContext(#)', this, '2d');
+
+  /**
+   * Returns a new Web GL context for this canvas.
+   *
+   * ## Other resources
+   *
+   * * [WebGL fundamentals](http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/)
+   *   from HTML5Rocks.
+   * * [WebGL homepage](http://get.webgl.org/).
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  gl.RenderingContext getContext3d(
+      {alpha: true,
+      depth: true,
+      stencil: false,
+      antialias: true,
+      premultipliedAlpha: true,
+      preserveDrawingBuffer: false}) {
+    var options = {
+      'alpha': alpha,
+      'depth': depth,
+      'stencil': stencil,
+      'antialias': antialias,
+      'premultipliedAlpha': premultipliedAlpha,
+      'preserveDrawingBuffer': preserveDrawingBuffer,
+    };
+    var context = getContext('webgl', options);
+    if (context == null) {
+      context = getContext('experimental-webgl', options);
+    }
+    return context;
+  }
+
+  /**
+   * Returns a data URI containing a representation of the image in the
+   * format specified by type (defaults to 'image/png').
+   *
+   * Data Uri format is as follow
+   * `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`
+   *
+   * Optional parameter [quality] in the range of 0.0 and 1.0 can be used when
+   * requesting [type] 'image/jpeg' or 'image/webp'. If [quality] is not passed
+   * the default value is used. Note: the default value varies by browser.
+   *
+   * If the height or width of this canvas element is 0, then 'data:' is
+   * returned, representing no data.
+   *
+   * If the type requested is not 'image/png', and the returned value is
+   * 'data:image/png', then the requested type is not supported.
+   *
+   * Example usage:
+   *
+   *     CanvasElement canvas = new CanvasElement();
+   *     var ctx = canvas.context2D
+   *     ..fillStyle = "rgb(200,0,0)"
+   *     ..fillRect(10, 10, 55, 50);
+   *     var dataUrl = canvas.toDataUrl("image/jpeg", 0.95);
+   *     // The Data Uri would look similar to
+   *     // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
+   *     // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
+   *     // 9TXL0Y4OHwAAAABJRU5ErkJggg=='
+   *     //Create a new image element from the data URI.
+   *     var img = new ImageElement();
+   *     img.src = dataUrl;
+   *     document.body.children.add(img);
+   *
+   * See also:
+   *
+   * * [Data URI Scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) from Wikipedia.
+   *
+   * * [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/DOM/HTMLCanvasElement) from MDN.
+   *
+   * * [toDataUrl](http://dev.w3.org/html5/spec/the-canvas-element.html#dom-canvas-todataurl) from W3C.
+   */
+  String toDataUrl([String type = 'image/png', num quality]) =>
+      _toDataUrl(type, quality);
+
+  @JSName('toBlob')
+  void _toBlob(BlobCallback callback, String type, [Object arguments]) native;
+
+  Future<Blob> toBlob(String type, [Object arguments]) {
+    var completer = new Completer<Blob>();
+    _toBlob((value) {
+      completer.complete(value);
+    }, type, arguments);
+    return completer.future;
+  }
+}
+// Copyright (c) 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.
+
+/**
+ * An opaque canvas object representing a gradient.
+ *
+ * Created by calling [createLinearGradient] or [createRadialGradient] on a
+ * [CanvasRenderingContext2D] object.
+ *
+ * Example usage:
+ *
+ *     var canvas = new CanvasElement(width: 600, height: 600);
+ *     var ctx = canvas.context2D;
+ *     ctx.clearRect(0, 0, 600, 600);
+ *     ctx.save();
+ *     // Create radial gradient.
+ *     CanvasGradient gradient = ctx.createRadialGradient(0, 0, 0, 0, 0, 600);
+ *     gradient.addColorStop(0, '#000');
+ *     gradient.addColorStop(1, 'rgb(255, 255, 255)');
+ *     // Assign gradients to fill.
+ *     ctx.fillStyle = gradient;
+ *     // Draw a rectangle with a gradient fill.
+ *     ctx.fillRect(0, 0, 600, 600);
+ *     ctx.save();
+ *     document.body.children.add(canvas);
+ *
+ * See also:
+ *
+ * * [CanvasGradient](https://developer.mozilla.org/en-US/docs/DOM/CanvasGradient) from MDN.
+ * * [CanvasGradient](https://html.spec.whatwg.org/multipage/scripting.html#canvasgradient)
+ *   from WHATWG.
+ * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.
+ */
+@Native("CanvasGradient")
+class CanvasGradient extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CanvasGradient._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Adds a color stop to this gradient at the offset.
+   *
+   * The [offset] can range between 0.0 and 1.0.
+   *
+   * See also:
+   *
+   * * [Multiple Color Stops](https://developer.mozilla.org/en-US/docs/CSS/linear-gradient#Gradient_with_multiple_color_stops) from MDN.
+   */
+  void addColorStop(num offset, String color) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * An opaque object representing a pattern of image, canvas, or video.
+ *
+ * Created by calling [createPattern] on a [CanvasRenderingContext2D] object.
+ *
+ * Example usage:
+ *
+ *     var canvas = new CanvasElement(width: 600, height: 600);
+ *     var ctx = canvas.context2D;
+ *     var img = new ImageElement();
+ *     // Image src needs to be loaded before pattern is applied.
+ *     img.onLoad.listen((event) {
+ *       // When the image is loaded, create a pattern
+ *       // from the ImageElement.
+ *       CanvasPattern pattern = ctx.createPattern(img, 'repeat');
+ *       ctx.rect(0, 0, canvas.width, canvas.height);
+ *       ctx.fillStyle = pattern;
+ *       ctx.fill();
+ *     });
+ *     img.src = "images/foo.jpg";
+ *     document.body.children.add(canvas);
+ *
+ * See also:
+ * * [CanvasPattern](https://developer.mozilla.org/en-US/docs/DOM/CanvasPattern) from MDN.
+ * * [CanvasPattern](https://html.spec.whatwg.org/multipage/scripting.html#canvaspattern)
+ *   from WHATWG.
+ * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.
+ */
+@Native("CanvasPattern")
+class CanvasPattern extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CanvasPattern._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  void setTransform(Matrix transform) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+abstract class CanvasRenderingContext {
+  CanvasElement get canvas;
+}
+
+@Native("CanvasRenderingContext2D")
+class CanvasRenderingContext2D extends Interceptor
+    implements CanvasRenderingContext {
+  // To suppress missing implicit constructor warnings.
+  factory CanvasRenderingContext2D._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final CanvasElement canvas;
+
+  Matrix currentTransform;
+
+  String direction;
+
+  @Creates('String|CanvasGradient|CanvasPattern')
+  @Returns('String|CanvasGradient|CanvasPattern')
+  Object fillStyle;
+
+  String filter;
+
+  String font;
+
+  num globalAlpha;
+
+  String globalCompositeOperation;
+
+  /**
+   * Whether images and patterns on this canvas will be smoothed when this
+   * canvas is scaled.
+   *
+   * ## Other resources
+   *
+   * * [Image
+   *   smoothing](https://html.spec.whatwg.org/multipage/scripting.html#image-smoothing)
+   *   from WHATWG.
+   */
+  bool imageSmoothingEnabled;
+
+  String imageSmoothingQuality;
+
+  String lineCap;
+
+  String lineJoin;
+
+  num lineWidth;
+
+  num miterLimit;
+
+  num shadowBlur;
+
+  String shadowColor;
+
+  num shadowOffsetX;
+
+  num shadowOffsetY;
+
+  @Creates('String|CanvasGradient|CanvasPattern')
+  @Returns('String|CanvasGradient|CanvasPattern')
+  Object strokeStyle;
+
+  String textAlign;
+
+  String textBaseline;
+
+  void addHitRegion([Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      _addHitRegion_1(options_1);
+      return;
+    }
+    _addHitRegion_2();
+    return;
+  }
+
+  @JSName('addHitRegion')
+  void _addHitRegion_1(options) native;
+  @JSName('addHitRegion')
+  void _addHitRegion_2() native;
+
+  void beginPath() native;
+
+  void clearHitRegions() native;
+
+  void clearRect(num x, num y, num width, num height) native;
+
+  void clip([path_OR_winding, String winding]) native;
+
+  @Creates('ImageData|=Object')
+  ImageData createImageData(data_OR_imagedata_OR_sw,
+      [int sh_OR_sw,
+      imageDataColorSettings_OR_sh,
+      Map imageDataColorSettings]) {
+    if ((data_OR_imagedata_OR_sw is ImageData) &&
+        sh_OR_sw == null &&
+        imageDataColorSettings_OR_sh == null &&
+        imageDataColorSettings == null) {
+      var imagedata_1 = convertDartToNative_ImageData(data_OR_imagedata_OR_sw);
+      return convertNativeToDart_ImageData(_createImageData_1(imagedata_1));
+    }
+    if (sh_OR_sw != null &&
+        (data_OR_imagedata_OR_sw is int) &&
+        imageDataColorSettings_OR_sh == null &&
+        imageDataColorSettings == null) {
+      return convertNativeToDart_ImageData(
+          _createImageData_2(data_OR_imagedata_OR_sw, sh_OR_sw));
+    }
+    if ((imageDataColorSettings_OR_sh is Map) &&
+        sh_OR_sw != null &&
+        (data_OR_imagedata_OR_sw is int) &&
+        imageDataColorSettings == null) {
+      var imageDataColorSettings_1 =
+          convertDartToNative_Dictionary(imageDataColorSettings_OR_sh);
+      return convertNativeToDart_ImageData(_createImageData_3(
+          data_OR_imagedata_OR_sw, sh_OR_sw, imageDataColorSettings_1));
+    }
+    if ((imageDataColorSettings_OR_sh is int) &&
+        sh_OR_sw != null &&
+        data_OR_imagedata_OR_sw != null &&
+        imageDataColorSettings == null) {
+      return convertNativeToDart_ImageData(_createImageData_4(
+          data_OR_imagedata_OR_sw, sh_OR_sw, imageDataColorSettings_OR_sh));
+    }
+    if (imageDataColorSettings != null &&
+        (imageDataColorSettings_OR_sh is int) &&
+        sh_OR_sw != null &&
+        data_OR_imagedata_OR_sw != null) {
+      var imageDataColorSettings_1 =
+          convertDartToNative_Dictionary(imageDataColorSettings);
+      return convertNativeToDart_ImageData(_createImageData_5(
+          data_OR_imagedata_OR_sw,
+          sh_OR_sw,
+          imageDataColorSettings_OR_sh,
+          imageDataColorSettings_1));
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('createImageData')
+  @Creates('ImageData|=Object')
+  _createImageData_1(imagedata) native;
+  @JSName('createImageData')
+  @Creates('ImageData|=Object')
+  _createImageData_2(int sw, sh) native;
+  @JSName('createImageData')
+  @Creates('ImageData|=Object')
+  _createImageData_3(int sw, sh, imageDataColorSettings) native;
+  @JSName('createImageData')
+  @Creates('ImageData|=Object')
+  _createImageData_4(data, sw, int sh) native;
+  @JSName('createImageData')
+  @Creates('ImageData|=Object')
+  _createImageData_5(data, sw, int sh, imageDataColorSettings) native;
+
+  CanvasGradient createLinearGradient(num x0, num y0, num x1, num y1) native;
+
+  CanvasPattern createPattern(Object image, String repetitionType) native;
+
+  CanvasGradient createRadialGradient(
+      num x0, num y0, num r0, num x1, num y1, num r1) native;
+
+  void drawFocusIfNeeded(element_OR_path, [Element element]) native;
+
+  void fill([path_OR_winding, String winding]) native;
+
+  void fillRect(num x, num y, num width, num height) native;
+
+  Map getContextAttributes() {
+    return convertNativeToDart_Dictionary(_getContextAttributes_1());
+  }
+
+  @JSName('getContextAttributes')
+  _getContextAttributes_1() native;
+
+  @Creates('ImageData|=Object')
+  ImageData getImageData(int sx, int sy, int sw, int sh) {
+    return convertNativeToDart_ImageData(_getImageData_1(sx, sy, sw, sh));
+  }
+
+  @JSName('getImageData')
+  @Creates('ImageData|=Object')
+  _getImageData_1(sx, sy, sw, sh) native;
+
+  @JSName('getLineDash')
+  List<num> _getLineDash() native;
+
+  bool isContextLost() native;
+
+  bool isPointInPath(path_OR_x, num x_OR_y, [winding_OR_y, String winding])
+      native;
+
+  bool isPointInStroke(path_OR_x, num x_OR_y, [num y]) native;
+
+  TextMetrics measureText(String text) native;
+
+  void putImageData(ImageData imagedata, int dx, int dy,
+      [int dirtyX, int dirtyY, int dirtyWidth, int dirtyHeight]) {
+    if (dirtyX == null &&
+        dirtyY == null &&
+        dirtyWidth == null &&
+        dirtyHeight == null) {
+      var imagedata_1 = convertDartToNative_ImageData(imagedata);
+      _putImageData_1(imagedata_1, dx, dy);
+      return;
+    }
+    if (dirtyHeight != null &&
+        dirtyWidth != null &&
+        dirtyY != null &&
+        dirtyX != null) {
+      var imagedata_1 = convertDartToNative_ImageData(imagedata);
+      _putImageData_2(
+          imagedata_1, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
+      return;
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('putImageData')
+  void _putImageData_1(imagedata, dx, dy) native;
+  @JSName('putImageData')
+  void _putImageData_2(
+      imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) native;
+
+  void removeHitRegion(String id) native;
+
+  void resetTransform() native;
+
+  void restore() native;
+
+  void rotate(num angle) native;
+
+  void save() native;
+
+  void scale(num x, num y) native;
+
+  void scrollPathIntoView([Path2D path]) native;
+
+  void setTransform(num a, num b, num c, num d, num e, num f) native;
+
+  void stroke([Path2D path]) native;
+
+  void strokeRect(num x, num y, num width, num height) native;
+
+  void strokeText(String text, num x, num y, [num maxWidth]) native;
+
+  void transform(num a, num b, num c, num d, num e, num f) native;
+
+  void translate(num x, num y) native;
+
+  // From CanvasPath
+
+  @JSName('arc')
+  void _arc(num x, num y, num radius, num startAngle, num endAngle,
+      bool anticlockwise) native;
+
+  void arcTo(num x1, num y1, num x2, num y2, num radius) native;
+
+  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y)
+      native;
+
+  void closePath() native;
+
+  void ellipse(num x, num y, num radiusX, num radiusY, num rotation,
+      num startAngle, num endAngle, bool anticlockwise) native;
+
+  void lineTo(num x, num y) native;
+
+  void moveTo(num x, num y) native;
+
+  void quadraticCurveTo(num cpx, num cpy, num x, num y) native;
+
+  void rect(num x, num y, num width, num height) native;
+
+  ImageData createImageDataFromImageData(ImageData imagedata) =>
+      JS('ImageData', '#.createImageData(#)', this, imagedata);
+
+  /**
+   * Sets the color used inside shapes.
+   * [r], [g], [b] are 0-255, [a] is 0-1.
+   */
+  void setFillColorRgb(int r, int g, int b, [num a = 1]) {
+    this.fillStyle = 'rgba($r, $g, $b, $a)';
+  }
+
+  /**
+   * Sets the color used inside shapes.
+   * [h] is in degrees, 0-360.
+   * [s], [l] are in percent, 0-100.
+   * [a] is 0-1.
+   */
+  void setFillColorHsl(int h, num s, num l, [num a = 1]) {
+    this.fillStyle = 'hsla($h, $s%, $l%, $a)';
+  }
+
+  /**
+   * Sets the color used for stroking shapes.
+   * [r], [g], [b] are 0-255, [a] is 0-1.
+   */
+  void setStrokeColorRgb(int r, int g, int b, [num a = 1]) {
+    this.strokeStyle = 'rgba($r, $g, $b, $a)';
+  }
+
+  /**
+   * Sets the color used for stroking shapes.
+   * [h] is in degrees, 0-360.
+   * [s], [l] are in percent, 0-100.
+   * [a] is 0-1.
+   */
+  void setStrokeColorHsl(int h, num s, num l, [num a = 1]) {
+    this.strokeStyle = 'hsla($h, $s%, $l%, $a)';
+  }
+
+  void arc(num x, num y, num radius, num startAngle, num endAngle,
+      [bool anticlockwise = false]) {
+    // TODO(terry): This should not be needed: dartbug.com/20939.
+    JS('void', '#.arc(#, #, #, #, #, #)', this, x, y, radius, startAngle,
+        endAngle, anticlockwise);
+  }
+
+  CanvasPattern createPatternFromImage(
+          ImageElement image, String repetitionType) =>
+      JS('CanvasPattern', '#.createPattern(#, #)', this, image, repetitionType);
+
+  /**
+   * Draws an image from a CanvasImageSource to an area of this canvas.
+   *
+   * The image will be drawn to an area of this canvas defined by
+   * [destRect]. [sourceRect] defines the region of the source image that is
+   * drawn.
+   * If [sourceRect] is not provided, then
+   * the entire rectangular image from [source] will be drawn to this context.
+   *
+   * If the image is larger than canvas
+   * will allow, the image will be clipped to fit the available space.
+   *
+   *     CanvasElement canvas = new CanvasElement(width: 600, height: 600);
+   *     CanvasRenderingContext2D ctx = canvas.context2D;
+   *     ImageElement img = document.query('img');
+   *     img.width = 100;
+   *     img.height = 100;
+   *
+   *     // Scale the image to 20x20.
+   *     ctx.drawImageToRect(img, new Rectangle(50, 50, 20, 20));
+   *
+   *     VideoElement video = document.query('video');
+   *     video.width = 100;
+   *     video.height = 100;
+   *     // Take the middle 20x20 pixels from the video and stretch them.
+   *     ctx.drawImageToRect(video, new Rectangle(50, 50, 100, 100),
+   *         sourceRect: new Rectangle(40, 40, 20, 20));
+   *
+   *     // Draw the top 100x20 pixels from the otherCanvas.
+   *     CanvasElement otherCanvas = document.query('canvas');
+   *     ctx.drawImageToRect(otherCanvas, new Rectangle(0, 0, 100, 20),
+   *         sourceRect: new Rectangle(0, 0, 100, 20));
+   *
+   * See also:
+   *
+   *   * [CanvasImageSource] for more information on what data is retrieved
+   * from [source].
+   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
+   * from the WHATWG.
+   */
+  void drawImageToRect(CanvasImageSource source, Rectangle destRect,
+      {Rectangle sourceRect}) {
+    if (sourceRect == null) {
+      drawImageScaled(
+          source, destRect.left, destRect.top, destRect.width, destRect.height);
+    } else {
+      drawImageScaledFromSource(
+          source,
+          sourceRect.left,
+          sourceRect.top,
+          sourceRect.width,
+          sourceRect.height,
+          destRect.left,
+          destRect.top,
+          destRect.width,
+          destRect.height);
+    }
+  }
+
+  /**
+   * Draws an image from a CanvasImageSource to this canvas.
+   *
+   * The entire image from [source] will be drawn to this context with its top
+   * left corner at the point ([destX], [destY]). If the image is
+   * larger than canvas will allow, the image will be clipped to fit the
+   * available space.
+   *
+   *     CanvasElement canvas = new CanvasElement(width: 600, height: 600);
+   *     CanvasRenderingContext2D ctx = canvas.context2D;
+   *     ImageElement img = document.query('img');
+   *
+   *     ctx.drawImage(img, 100, 100);
+   *
+   *     VideoElement video = document.query('video');
+   *     ctx.drawImage(video, 0, 0);
+   *
+   *     CanvasElement otherCanvas = document.query('canvas');
+   *     otherCanvas.width = 100;
+   *     otherCanvas.height = 100;
+   *     ctx.drawImage(otherCanvas, 590, 590); // will get clipped
+   *
+   * See also:
+   *
+   *   * [CanvasImageSource] for more information on what data is retrieved
+   * from [source].
+   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
+   * from the WHATWG.
+   */
+  @JSName('drawImage')
+  void drawImage(CanvasImageSource source, num destX, num destY) native;
+
+  /**
+   * Draws an image from a CanvasImageSource to an area of this canvas.
+   *
+   * The image will be drawn to this context with its top left corner at the
+   * point ([destX], [destY]) and will be scaled to be [destWidth] wide and
+   * [destHeight] tall.
+   *
+   * If the image is larger than canvas
+   * will allow, the image will be clipped to fit the available space.
+   *
+   *     CanvasElement canvas = new CanvasElement(width: 600, height: 600);
+   *     CanvasRenderingContext2D ctx = canvas.context2D;
+   *     ImageElement img = document.query('img');
+   *     img.width = 100;
+   *     img.height = 100;
+   *
+   *     // Scale the image to 300x50 at the point (20, 20)
+   *     ctx.drawImageScaled(img, 20, 20, 300, 50);
+   *
+   * See also:
+   *
+   *   * [CanvasImageSource] for more information on what data is retrieved
+   * from [source].
+   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
+   * from the WHATWG.
+   */
+  @JSName('drawImage')
+  void drawImageScaled(CanvasImageSource source, num destX, num destY,
+      num destWidth, num destHeight) native;
+
+  /**
+   * Draws an image from a CanvasImageSource to an area of this canvas.
+   *
+   * The image is a region of [source] that is [sourceWidth] wide and
+   * [destHeight] tall with top left corner at ([sourceX], [sourceY]).
+   * The image will be drawn to this context with its top left corner at the
+   * point ([destX], [destY]) and will be scaled to be [destWidth] wide and
+   * [destHeight] tall.
+   *
+   * If the image is larger than canvas
+   * will allow, the image will be clipped to fit the available space.
+   *
+   *     VideoElement video = document.query('video');
+   *     video.width = 100;
+   *     video.height = 100;
+   *     // Take the middle 20x20 pixels from the video and stretch them.
+   *     ctx.drawImageScaledFromSource(video, 40, 40, 20, 20, 50, 50, 100, 100);
+   *
+   *     // Draw the top 100x20 pixels from the otherCanvas to this one.
+   *     CanvasElement otherCanvas = document.query('canvas');
+   *     ctx.drawImageScaledFromSource(otherCanvas, 0, 0, 100, 20, 0, 0, 100, 20);
+   *
+   * See also:
+   *
+   *   * [CanvasImageSource] for more information on what data is retrieved
+   * from [source].
+   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
+   * from the WHATWG.
+   */
+  @JSName('drawImage')
+  void drawImageScaledFromSource(
+      CanvasImageSource source,
+      num sourceX,
+      num sourceY,
+      num sourceWidth,
+      num sourceHeight,
+      num destX,
+      num destY,
+      num destWidth,
+      num destHeight) native;
+
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @SupportedBrowser(SupportedBrowser.IE, '11')
+  @Unstable()
+  // TODO(14316): Firefox has this functionality with mozDashOffset, but it
+  // needs to be polyfilled.
+  num get lineDashOffset =>
+      JS('num', '#.lineDashOffset || #.webkitLineDashOffset', this, this);
+
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @SupportedBrowser(SupportedBrowser.IE, '11')
+  @Unstable()
+  // TODO(14316): Firefox has this functionality with mozDashOffset, but it
+  // needs to be polyfilled.
+  set lineDashOffset(num value) {
+    JS(
+        'void',
+        'typeof #.lineDashOffset != "undefined" ? #.lineDashOffset = # : '
+            '#.webkitLineDashOffset = #',
+        this,
+        this,
+        value,
+        this,
+        value);
+  }
+
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @SupportedBrowser(SupportedBrowser.IE, '11')
+  @Unstable()
+  List<num> getLineDash() {
+    // TODO(14316): Firefox has this functionality with mozDash, but it's a bit
+    // different.
+    if (JS('bool', '!!#.getLineDash', this)) {
+      return JS('List<num>', '#.getLineDash()', this);
+    } else if (JS('bool', '!!#.webkitLineDash', this)) {
+      return JS('List<num>', '#.webkitLineDash', this);
+    }
+  }
+
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @SupportedBrowser(SupportedBrowser.IE, '11')
+  @Unstable()
+  void setLineDash(List<num> dash) {
+    // TODO(14316): Firefox has this functionality with mozDash, but it's a bit
+    // different.
+    if (JS('bool', '!!#.setLineDash', this)) {
+      JS('void', '#.setLineDash(#)', this, dash);
+    } else if (JS('bool', '!!#.webkitLineDash', this)) {
+      JS('void', '#.webkitLineDash = #', this, dash);
+    }
+  }
+
+  /**
+   * Draws text to the canvas.
+   *
+   * The text is drawn starting at coordinates ([x], [y]).
+   * If [maxWidth] is provided and the [text] is computed to be wider than
+   * [maxWidth], then the drawn text is scaled down horizontally to fit.
+   *
+   * The text uses the current [CanvasRenderingContext2D.font] property for font
+   * options, such as typeface and size, and the current
+   * [CanvasRenderingContext2D.fillStyle] for style options such as color.
+   * The current [CanvasRenderingContext2D.textAlign] and
+   * [CanvasRenderingContext2D.textBaseLine] properties are also applied to the
+   * drawn text.
+   */
+  void fillText(String text, num x, num y, [num maxWidth]) {
+    if (maxWidth != null) {
+      JS('void', '#.fillText(#, #, #, #)', this, text, x, y, maxWidth);
+    } else {
+      JS('void', '#.fillText(#, #, #)', this, text, x, y);
+    }
+  }
+
+  /** Deprecated always returns 1.0 */
+  @deprecated
+  double get backingStorePixelRatio => 1.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.
+
+@Native("CharacterData")
+class CharacterData extends Node
+    implements NonDocumentTypeChildNode, ChildNode {
+  // To suppress missing implicit constructor warnings.
+  factory CharacterData._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  String data;
+
+  final int length;
+
+  void appendData(String data) native;
+
+  void deleteData(int offset, int count) native;
+
+  void insertData(int offset, String data) native;
+
+  void replaceData(int offset, int count, String data) native;
+
+  String substringData(int offset, int count) native;
+
+  // From ChildNode
+
+  void after(Object nodes) native;
+
+  void before(Object nodes) native;
+
+  // From NonDocumentTypeChildNode
+
+  final Element nextElementSibling;
+
+  final Element previousElementSibling;
+}
+// Copyright (c) 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.
+
+abstract class ChildNode extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ChildNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  void after(Object nodes);
+
+  void before(Object nodes);
+
+  void remove();
+}
+// Copyright (c) 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.
+
+@Native("Client")
+class Client extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Client._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String frameType;
+
+  final String id;
+
+  final String type;
+
+  final String url;
+
+  void postMessage(Object message, [List<Object> transfer]) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("Clients")
+class Clients extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Clients._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Future claim() => promiseToFuture(JS("", "#.claim()", this));
+
+  Future get(String id) => promiseToFuture(JS("", "#.get(#)", this, id));
+
+  Future<List<Client>> matchAll([Map options]) {
+    var options_dict = null;
+    if (options != null) {
+      options_dict = convertDartToNative_Dictionary(options);
+    }
+    return promiseToFuture<List<Client>>(
+        JS("", "#.matchAll(#)", this, options_dict));
+  }
+
+  Future<WindowClient> openWindow(String url) =>
+      promiseToFuture<WindowClient>(JS("", "#.openWindow(#)", this, url));
+}
+// Copyright (c) 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.
+
+@Native("ClipboardEvent")
+class ClipboardEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory ClipboardEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ClipboardEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return ClipboardEvent._create_1(type, eventInitDict_1);
+    }
+    return ClipboardEvent._create_2(type);
+  }
+  static ClipboardEvent _create_1(type, eventInitDict) =>
+      JS('ClipboardEvent', 'new ClipboardEvent(#,#)', type, eventInitDict);
+  static ClipboardEvent _create_2(type) =>
+      JS('ClipboardEvent', 'new ClipboardEvent(#)', type);
+
+  final DataTransfer clipboardData;
+}
+// Copyright (c) 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.
+
+@Native("CloseEvent")
+class CloseEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory CloseEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory CloseEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return CloseEvent._create_1(type, eventInitDict_1);
+    }
+    return CloseEvent._create_2(type);
+  }
+  static CloseEvent _create_1(type, eventInitDict) =>
+      JS('CloseEvent', 'new CloseEvent(#,#)', type, eventInitDict);
+  static CloseEvent _create_2(type) =>
+      JS('CloseEvent', 'new CloseEvent(#)', type);
+
+  final int code;
+
+  final String reason;
+
+  final bool wasClean;
+}
+// Copyright (c) 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.
+
+@Native("Comment")
+class Comment extends CharacterData {
+  factory Comment([String data]) {
+    return JS('returns:Comment;depends:none;effects:none;new:true',
+        '#.createComment(#)', document, data == null ? "" : data);
+  }
+  // To suppress missing implicit constructor warnings.
+  factory Comment._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@Native("CompositionEvent")
+class CompositionEvent extends UIEvent {
+  factory CompositionEvent(String type,
+      {bool canBubble: false,
+      bool cancelable: false,
+      Window view,
+      String data,
+      String locale}) {
+    if (view == null) {
+      view = window;
+    }
+    CompositionEvent e = document._createEvent("CompositionEvent");
+
+    if (Device.isFirefox) {
+      // Firefox requires the locale parameter that isn't supported elsewhere.
+      JS('void', '#.initCompositionEvent(#, #, #, #, #, #)', e, type, canBubble,
+          cancelable, view, data, locale);
+    } else {
+      e._initCompositionEvent(type, canBubble, cancelable, view, data);
+    }
+
+    return e;
+  }
+
+  factory CompositionEvent._(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return CompositionEvent._create_1(type, eventInitDict_1);
+    }
+    return CompositionEvent._create_2(type);
+  }
+  static CompositionEvent _create_1(type, eventInitDict) =>
+      JS('CompositionEvent', 'new CompositionEvent(#,#)', type, eventInitDict);
+  static CompositionEvent _create_2(type) =>
+      JS('CompositionEvent', 'new CompositionEvent(#)', type);
+
+  final String data;
+
+  @JSName('initCompositionEvent')
+  void _initCompositionEvent(String type, bool bubbles, bool cancelable,
+      Window view, String data) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME, '26')
+@Native("HTMLContentElement")
+class ContentElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory ContentElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ContentElement() => document.createElement("content");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ContentElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => Element.isTagSupported('content');
+
+  String select;
+
+  @Returns('NodeList|Null')
+  @Creates('NodeList')
+  List<Node> getDistributedNodes() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("CookieStore")
+class CookieStore extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CookieStore._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Future getAll([Map options]) {
+    var options_dict = null;
+    if (options != null) {
+      options_dict = convertDartToNative_Dictionary(options);
+    }
+    return promiseToFuture(JS("", "#.getAll(#)", this, options_dict));
+  }
+
+  Future set(String name, String value, [Map options]) {
+    var options_dict = null;
+    if (options != null) {
+      options_dict = convertDartToNative_Dictionary(options);
+    }
+    return promiseToFuture(
+        JS("", "#.set(#, #, #)", this, name, value, options_dict));
+  }
+}
+// Copyright (c) 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.
+
+@Native("Coordinates")
+class Coordinates extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Coordinates._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num accuracy;
+
+  final num altitude;
+
+  final num altitudeAccuracy;
+
+  final num heading;
+
+  final num latitude;
+
+  final num longitude;
+
+  final num speed;
+}
+// Copyright (c) 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.
+
+@Native("Credential")
+class Credential extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Credential._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String id;
+
+  final String type;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("CredentialUserData")
+class CredentialUserData extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CredentialUserData._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('iconURL')
+  final String iconUrl;
+
+  final String name;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("CredentialsContainer")
+class CredentialsContainer extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CredentialsContainer._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Future create([Map options]) {
+    var options_dict = null;
+    if (options != null) {
+      options_dict = convertDartToNative_Dictionary(options);
+    }
+    return promiseToFuture(JS("", "#.create(#)", this, options_dict));
+  }
+
+  Future get([Map options]) {
+    var options_dict = null;
+    if (options != null) {
+      options_dict = convertDartToNative_Dictionary(options);
+    }
+    return promiseToFuture(JS("", "#.get(#)", this, options_dict));
+  }
+
+  Future preventSilentAccess() =>
+      promiseToFuture(JS("", "#.preventSilentAccess()", this));
+
+  Future requireUserMediation() =>
+      promiseToFuture(JS("", "#.requireUserMediation()", this));
+
+  Future store(Credential credential) =>
+      promiseToFuture(JS("", "#.store(#)", this, credential));
+}
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Native("Crypto")
+class Crypto extends Interceptor {
+  TypedData getRandomValues(TypedData array) {
+    return _getRandomValues(array);
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory Crypto._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      JS('bool', '!!(window.crypto && window.crypto.getRandomValues)');
+
+  final _SubtleCrypto subtle;
+
+  @JSName('getRandomValues')
+  @Creates('TypedData')
+  @Returns('TypedData|Null')
+  TypedData _getRandomValues(TypedData array) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("CryptoKey")
+class CryptoKey extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CryptoKey._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @Creates('Null')
+  final Object algorithm;
+
+  final bool extractable;
+
+  final String type;
+
+  final Object usages;
+}
+// Copyright (c) 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.
+
+@Native("CSS")
+class Css extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Css._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static final _Worklet paintWorklet;
+
+  static CssUnitValue Hz(num value) native;
+
+  static CssUnitValue ch(num value) native;
+
+  static CssUnitValue cm(num value) native;
+
+  static CssUnitValue deg(num value) native;
+
+  static CssUnitValue dpcm(num value) native;
+
+  static CssUnitValue dpi(num value) native;
+
+  static CssUnitValue dppx(num value) native;
+
+  static CssUnitValue em(num value) native;
+
+  static String escape(String ident) native;
+
+  static CssUnitValue ex(num value) native;
+
+  static CssUnitValue fr(num value) native;
+
+  static CssUnitValue grad(num value) native;
+
+  @JSName('in')
+  static CssUnitValue inch(num value) native;
+
+  static CssUnitValue kHz(num value) native;
+
+  static CssUnitValue mm(num value) native;
+
+  static CssUnitValue ms(num value) native;
+
+  static CssUnitValue number(num value) native;
+
+  static CssUnitValue pc(num value) native;
+
+  static CssUnitValue percent(num value) native;
+
+  static CssUnitValue pt(num value) native;
+
+  static CssUnitValue px(num value) native;
+
+  static CssUnitValue rad(num value) native;
+
+  static void registerProperty(Map descriptor) {
+    var descriptor_1 = convertDartToNative_Dictionary(descriptor);
+    _registerProperty_1(descriptor_1);
+    return;
+  }
+
+  @JSName('registerProperty')
+  static void _registerProperty_1(descriptor) native;
+
+  static CssUnitValue rem(num value) native;
+
+  static CssUnitValue s(num value) native;
+
+  static bool supports(String property, String value) native;
+
+  @JSName('supports')
+  static bool supportsCondition(String conditionText) native;
+
+  static CssUnitValue turn(num value) native;
+
+  static CssUnitValue vh(num value) native;
+
+  static CssUnitValue vmax(num value) native;
+
+  static CssUnitValue vmin(num value) native;
+
+  static CssUnitValue vw(num value) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("CSSCharsetRule")
+class CssCharsetRule extends CssRule {
+  // To suppress missing implicit constructor warnings.
+  factory CssCharsetRule._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  String encoding;
+}
+// Copyright (c) 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.
+
+@Native("CSSConditionRule")
+class CssConditionRule extends CssGroupingRule {
+  // To suppress missing implicit constructor warnings.
+  factory CssConditionRule._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String conditionText;
+}
+// Copyright (c) 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.
+
+@Native("CSSFontFaceRule")
+class CssFontFaceRule extends CssRule {
+  // To suppress missing implicit constructor warnings.
+  factory CssFontFaceRule._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final CssStyleDeclaration style;
+}
+// Copyright (c) 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.
+
+@Native("CSSGroupingRule")
+class CssGroupingRule extends CssRule {
+  // To suppress missing implicit constructor warnings.
+  factory CssGroupingRule._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @Returns('_CssRuleList|Null')
+  @Creates('_CssRuleList')
+  final List<CssRule> cssRules;
+
+  void deleteRule(int index) native;
+
+  int insertRule(String rule, int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("CSSImageValue")
+class CssImageValue extends CssResourceValue {
+  // To suppress missing implicit constructor warnings.
+  factory CssImageValue._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num intrinsicHeight;
+
+  final num intrinsicRatio;
+
+  final num intrinsicWidth;
+}
+// Copyright (c) 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.
+
+@Native("CSSImportRule")
+class CssImportRule extends CssRule {
+  // To suppress missing implicit constructor warnings.
+  factory CssImportRule._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String href;
+
+  final MediaList media;
+
+  final CssStyleSheet styleSheet;
+}
+// Copyright (c) 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.
+
+@Native("CSSKeyframeRule,MozCSSKeyframeRule,WebKitCSSKeyframeRule")
+class CssKeyframeRule extends CssRule {
+  // To suppress missing implicit constructor warnings.
+  factory CssKeyframeRule._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  String keyText;
+
+  final CssStyleDeclaration style;
+}
+// Copyright (c) 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.
+
+@Native("CSSKeyframesRule,MozCSSKeyframesRule,WebKitCSSKeyframesRule")
+class CssKeyframesRule extends CssRule {
+  // To suppress missing implicit constructor warnings.
+  factory CssKeyframesRule._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @Returns('_CssRuleList|Null')
+  @Creates('_CssRuleList')
+  final List<CssRule> cssRules;
+
+  String name;
+
+  CssKeyframeRule __getter__(int index) native;
+
+  void appendRule(String rule) native;
+
+  void deleteRule(String select) native;
+
+  CssKeyframeRule findRule(String select) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("CSSKeywordValue")
+class CssKeywordValue extends CssStyleValue {
+  // To suppress missing implicit constructor warnings.
+  factory CssKeywordValue._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory CssKeywordValue(String keyword) {
+    return CssKeywordValue._create_1(keyword);
+  }
+  static CssKeywordValue _create_1(keyword) =>
+      JS('CssKeywordValue', 'new CSSKeywordValue(#)', keyword);
+
+  String value;
+}
+// Copyright (c) 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.
+
+@Native("CSSMatrixComponent")
+class CssMatrixComponent extends CssTransformComponent {
+  // To suppress missing implicit constructor warnings.
+  factory CssMatrixComponent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory CssMatrixComponent(DomMatrixReadOnly matrix, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return CssMatrixComponent._create_1(matrix, options_1);
+    }
+    return CssMatrixComponent._create_2(matrix);
+  }
+  static CssMatrixComponent _create_1(matrix, options) =>
+      JS('CssMatrixComponent', 'new CSSMatrixComponent(#,#)', matrix, options);
+  static CssMatrixComponent _create_2(matrix) =>
+      JS('CssMatrixComponent', 'new CSSMatrixComponent(#)', matrix);
+
+  DomMatrix matrix;
+}
+// Copyright (c) 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.
+
+@Native("CSSMediaRule")
+class CssMediaRule extends CssConditionRule {
+  // To suppress missing implicit constructor warnings.
+  factory CssMediaRule._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final MediaList media;
+}
+// Copyright (c) 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.
+
+@Native("CSSNamespaceRule")
+class CssNamespaceRule extends CssRule {
+  // To suppress missing implicit constructor warnings.
+  factory CssNamespaceRule._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('namespaceURI')
+  final String namespaceUri;
+
+  final String prefix;
+}
+// Copyright (c) 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.
+
+@Native("CSSNumericValue")
+class CssNumericValue extends CssStyleValue {
+  // To suppress missing implicit constructor warnings.
+  factory CssNumericValue._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  CssNumericValue add(CssNumericValue value) native;
+
+  CssNumericValue div(num value) native;
+
+  CssNumericValue mul(num value) native;
+
+  static CssNumericValue parse(String cssText) native;
+
+  CssNumericValue sub(CssNumericValue value) native;
+
+  CssNumericValue to(String unit) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("CSSPageRule")
+class CssPageRule extends CssRule {
+  // To suppress missing implicit constructor warnings.
+  factory CssPageRule._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  String selectorText;
+
+  final CssStyleDeclaration style;
+}
+// Copyright (c) 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.
+
+@Native("CSSPerspective")
+class CssPerspective extends CssTransformComponent {
+  // To suppress missing implicit constructor warnings.
+  factory CssPerspective._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory CssPerspective(CssNumericValue length) {
+    return CssPerspective._create_1(length);
+  }
+  static CssPerspective _create_1(length) =>
+      JS('CssPerspective', 'new CSSPerspective(#)', length);
+
+  CssNumericValue length;
+}
+// Copyright (c) 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.
+
+@Native("CSSPositionValue")
+class CssPositionValue extends CssStyleValue {
+  // To suppress missing implicit constructor warnings.
+  factory CssPositionValue._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory CssPositionValue(CssNumericValue x, CssNumericValue y) {
+    return CssPositionValue._create_1(x, y);
+  }
+  static CssPositionValue _create_1(x, y) =>
+      JS('CssPositionValue', 'new CSSPositionValue(#,#)', x, y);
+
+  CssNumericValue x;
+
+  CssNumericValue y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("CSSResourceValue")
+class CssResourceValue extends CssStyleValue {
+  // To suppress missing implicit constructor warnings.
+  factory CssResourceValue._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String state;
+}
+// Copyright (c) 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.
+
+@Native("CSSRotation")
+class CssRotation extends CssTransformComponent {
+  // To suppress missing implicit constructor warnings.
+  factory CssRotation._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory CssRotation(angleValue_OR_x, [num y, num z, CssNumericValue angle]) {
+    if ((angleValue_OR_x is CssNumericValue) &&
+        y == null &&
+        z == null &&
+        angle == null) {
+      return CssRotation._create_1(angleValue_OR_x);
+    }
+    if ((angle is CssNumericValue) &&
+        (z is num) &&
+        (y is num) &&
+        (angleValue_OR_x is num)) {
+      return CssRotation._create_2(angleValue_OR_x, y, z, angle);
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+  static CssRotation _create_1(angleValue_OR_x) =>
+      JS('CssRotation', 'new CSSRotation(#)', angleValue_OR_x);
+  static CssRotation _create_2(angleValue_OR_x, y, z, angle) => JS(
+      'CssRotation', 'new CSSRotation(#,#,#,#)', angleValue_OR_x, y, z, angle);
+
+  CssNumericValue angle;
+
+  num x;
+
+  num y;
+
+  num z;
+}
+// Copyright (c) 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.
+
+@Native("CSSRule")
+class CssRule extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CssRule._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int CHARSET_RULE = 2;
+
+  static const int FONT_FACE_RULE = 5;
+
+  static const int IMPORT_RULE = 3;
+
+  static const int KEYFRAMES_RULE = 7;
+
+  static const int KEYFRAME_RULE = 8;
+
+  static const int MEDIA_RULE = 4;
+
+  static const int NAMESPACE_RULE = 10;
+
+  static const int PAGE_RULE = 6;
+
+  static const int STYLE_RULE = 1;
+
+  static const int SUPPORTS_RULE = 12;
+
+  static const int VIEWPORT_RULE = 15;
+
+  String cssText;
+
+  final CssRule parentRule;
+
+  final CssStyleSheet parentStyleSheet;
+
+  final int type;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("CSSScale")
+class CssScale extends CssTransformComponent {
+  // To suppress missing implicit constructor warnings.
+  factory CssScale._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory CssScale(num x, num y, [num z]) {
+    if ((y is num) && (x is num) && z == null) {
+      return CssScale._create_1(x, y);
+    }
+    if ((z is num) && (y is num) && (x is num)) {
+      return CssScale._create_2(x, y, z);
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+  static CssScale _create_1(x, y) => JS('CssScale', 'new CSSScale(#,#)', x, y);
+  static CssScale _create_2(x, y, z) =>
+      JS('CssScale', 'new CSSScale(#,#,#)', x, y, z);
+
+  num x;
+
+  num y;
+
+  num z;
+}
+// Copyright (c) 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.
+
+@Native("CSSSkew")
+class CssSkew extends CssTransformComponent {
+  // To suppress missing implicit constructor warnings.
+  factory CssSkew._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory CssSkew(CssNumericValue ax, CssNumericValue ay) {
+    return CssSkew._create_1(ax, ay);
+  }
+  static CssSkew _create_1(ax, ay) => JS('CssSkew', 'new CSSSkew(#,#)', ax, ay);
+
+  CssNumericValue ax;
+
+  CssNumericValue ay;
+}
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: DO NOT EDIT THIS TEMPLATE FILE.
+// The template file was generated by scripts/css_code_generator.py
+
+// Source of CSS properties:
+//   CSSPropertyNames.in
+
+@Native("CSSStyleDeclaration,MSStyleCSSProperties,CSS2Properties")
+class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase {
+  factory CssStyleDeclaration() => new CssStyleDeclaration.css('');
+
+  factory CssStyleDeclaration.css(String css) {
+    final style = new DivElement().style;
+    style.cssText = css;
+    return style;
+  }
+
+  /// Returns the value of the property if the provided *CSS* property
+  /// name is supported on this element and if the value is set. Otherwise
+  /// returns an empty string.
+  ///
+  /// Please note the property name uses camelCase, not-hyphens.
+  String getPropertyValue(String propertyName) {
+    var propValue = _getPropertyValueHelper(propertyName);
+    return propValue ?? '';
+  }
+
+  String _getPropertyValueHelper(String propertyName) {
+    return _getPropertyValue(_browserPropertyName(propertyName));
+  }
+
+  /**
+   * Returns true if the provided *CSS* property name is supported on this
+   * element.
+   *
+   * Please note the property name camelCase, not-hyphens. This
+   * method returns true if the property is accessible via an unprefixed _or_
+   * prefixed property.
+   */
+  bool supportsProperty(String propertyName) {
+    return _supportsProperty(propertyName) ||
+        _supportsProperty(_camelCase("${Device.cssPrefix}$propertyName"));
+  }
+
+  bool _supportsProperty(String propertyName) {
+    return JS('bool', '# in #', propertyName, this);
+  }
+
+  void setProperty(String propertyName, String value, [String priority]) {
+    return _setPropertyHelper(
+        _browserPropertyName(propertyName), value, priority);
+  }
+
+  String _browserPropertyName(String propertyName) {
+    String name = _readCache(propertyName);
+    if (name is String) return name;
+    name = _supportedBrowserPropertyName(propertyName);
+    _writeCache(propertyName, name);
+    return name;
+  }
+
+  String _supportedBrowserPropertyName(String propertyName) {
+    if (_supportsProperty(_camelCase(propertyName))) {
+      return propertyName;
+    }
+    var prefixed = "${Device.cssPrefix}$propertyName";
+    if (_supportsProperty(prefixed)) {
+      return prefixed;
+    }
+    // May be a CSS variable, just use it as provided.
+    return propertyName;
+  }
+
+  static final _propertyCache = JS('', '{}');
+  static String _readCache(String key) =>
+      JS('String|Null', '#[#]', _propertyCache, key);
+  static void _writeCache(String key, String value) {
+    JS('void', '#[#] = #', _propertyCache, key, value);
+  }
+
+  static String _camelCase(String hyphenated) {
+    var replacedMs = JS('String', r'#.replace(/^-ms-/, "ms-")', hyphenated);
+    return JS(
+        'String',
+        r'#.replace(/-([\da-z])/ig,'
+            r'function(_, letter) { return letter.toUpperCase();})',
+        replacedMs);
+  }
+
+  void _setPropertyHelper(String propertyName, String value,
+      [String priority]) {
+    if (value == null) value = '';
+    if (priority == null) priority = '';
+    JS('void', '#.setProperty(#, #, #)', this, propertyName, value, priority);
+  }
+
+  /**
+   * Checks to see if CSS Transitions are supported.
+   */
+  static bool get supportsTransitions {
+    return document.body.style.supportsProperty('transition');
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory CssStyleDeclaration._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  String cssFloat;
+
+  String cssText;
+
+  final int length;
+
+  final CssRule parentRule;
+
+  String getPropertyPriority(String property) native;
+
+  @JSName('getPropertyValue')
+  String _getPropertyValue(String property) native;
+
+  String item(int index) native;
+
+  String removeProperty(String property) native;
+
+  /** Gets the value of "background" */
+  String get background => this._background;
+
+  /** Sets the value of "background" */
+  set background(String value) {
+    _background = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('background')
+  String _background;
+
+  /** Gets the value of "background-attachment" */
+  String get backgroundAttachment => this._backgroundAttachment;
+
+  /** Sets the value of "background-attachment" */
+  set backgroundAttachment(String value) {
+    _backgroundAttachment = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('backgroundAttachment')
+  String _backgroundAttachment;
+
+  /** Gets the value of "background-color" */
+  String get backgroundColor => this._backgroundColor;
+
+  /** Sets the value of "background-color" */
+  set backgroundColor(String value) {
+    _backgroundColor = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('backgroundColor')
+  String _backgroundColor;
+
+  /** Gets the value of "background-image" */
+  String get backgroundImage => this._backgroundImage;
+
+  /** Sets the value of "background-image" */
+  set backgroundImage(String value) {
+    _backgroundImage = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('backgroundImage')
+  String _backgroundImage;
+
+  /** Gets the value of "background-position" */
+  String get backgroundPosition => this._backgroundPosition;
+
+  /** Sets the value of "background-position" */
+  set backgroundPosition(String value) {
+    _backgroundPosition = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('backgroundPosition')
+  String _backgroundPosition;
+
+  /** Gets the value of "background-repeat" */
+  String get backgroundRepeat => this._backgroundRepeat;
+
+  /** Sets the value of "background-repeat" */
+  set backgroundRepeat(String value) {
+    _backgroundRepeat = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('backgroundRepeat')
+  String _backgroundRepeat;
+
+  /** Gets the value of "border" */
+  String get border => this._border;
+
+  /** Sets the value of "border" */
+  set border(String value) {
+    _border = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('border')
+  String _border;
+
+  /** Gets the value of "border-bottom" */
+  String get borderBottom => this._borderBottom;
+
+  /** Sets the value of "border-bottom" */
+  set borderBottom(String value) {
+    _borderBottom = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderBottom')
+  String _borderBottom;
+
+  /** Gets the value of "border-bottom-color" */
+  String get borderBottomColor => this._borderBottomColor;
+
+  /** Sets the value of "border-bottom-color" */
+  set borderBottomColor(String value) {
+    _borderBottomColor = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderBottomColor')
+  String _borderBottomColor;
+
+  /** Gets the value of "border-bottom-style" */
+  String get borderBottomStyle => this._borderBottomStyle;
+
+  /** Sets the value of "border-bottom-style" */
+  set borderBottomStyle(String value) {
+    _borderBottomStyle = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderBottomStyle')
+  String _borderBottomStyle;
+
+  /** Gets the value of "border-bottom-width" */
+  String get borderBottomWidth => this._borderBottomWidth;
+
+  /** Sets the value of "border-bottom-width" */
+  set borderBottomWidth(String value) {
+    _borderBottomWidth = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderBottomWidth')
+  String _borderBottomWidth;
+
+  /** Gets the value of "border-collapse" */
+  String get borderCollapse => this._borderCollapse;
+
+  /** Sets the value of "border-collapse" */
+  set borderCollapse(String value) {
+    _borderCollapse = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderCollapse')
+  String _borderCollapse;
+
+  /** Gets the value of "border-color" */
+  String get borderColor => this._borderColor;
+
+  /** Sets the value of "border-color" */
+  set borderColor(String value) {
+    _borderColor = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderColor')
+  String _borderColor;
+
+  /** Gets the value of "border-left" */
+  String get borderLeft => this._borderLeft;
+
+  /** Sets the value of "border-left" */
+  set borderLeft(String value) {
+    _borderLeft = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderLeft')
+  String _borderLeft;
+
+  /** Gets the value of "border-left-color" */
+  String get borderLeftColor => this._borderLeftColor;
+
+  /** Sets the value of "border-left-color" */
+  set borderLeftColor(String value) {
+    _borderLeftColor = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderLeftColor')
+  String _borderLeftColor;
+
+  /** Gets the value of "border-left-style" */
+  String get borderLeftStyle => this._borderLeftStyle;
+
+  /** Sets the value of "border-left-style" */
+  set borderLeftStyle(String value) {
+    _borderLeftStyle = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderLeftStyle')
+  String _borderLeftStyle;
+
+  /** Gets the value of "border-left-width" */
+  String get borderLeftWidth => this._borderLeftWidth;
+
+  /** Sets the value of "border-left-width" */
+  set borderLeftWidth(String value) {
+    _borderLeftWidth = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderLeftWidth')
+  String _borderLeftWidth;
+
+  /** Gets the value of "border-right" */
+  String get borderRight => this._borderRight;
+
+  /** Sets the value of "border-right" */
+  set borderRight(String value) {
+    _borderRight = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderRight')
+  String _borderRight;
+
+  /** Gets the value of "border-right-color" */
+  String get borderRightColor => this._borderRightColor;
+
+  /** Sets the value of "border-right-color" */
+  set borderRightColor(String value) {
+    _borderRightColor = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderRightColor')
+  String _borderRightColor;
+
+  /** Gets the value of "border-right-style" */
+  String get borderRightStyle => this._borderRightStyle;
+
+  /** Sets the value of "border-right-style" */
+  set borderRightStyle(String value) {
+    _borderRightStyle = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderRightStyle')
+  String _borderRightStyle;
+
+  /** Gets the value of "border-right-width" */
+  String get borderRightWidth => this._borderRightWidth;
+
+  /** Sets the value of "border-right-width" */
+  set borderRightWidth(String value) {
+    _borderRightWidth = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderRightWidth')
+  String _borderRightWidth;
+
+  /** Gets the value of "border-spacing" */
+  String get borderSpacing => this._borderSpacing;
+
+  /** Sets the value of "border-spacing" */
+  set borderSpacing(String value) {
+    _borderSpacing = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderSpacing')
+  String _borderSpacing;
+
+  /** Gets the value of "border-style" */
+  String get borderStyle => this._borderStyle;
+
+  /** Sets the value of "border-style" */
+  set borderStyle(String value) {
+    _borderStyle = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderStyle')
+  String _borderStyle;
+
+  /** Gets the value of "border-top" */
+  String get borderTop => this._borderTop;
+
+  /** Sets the value of "border-top" */
+  set borderTop(String value) {
+    _borderTop = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderTop')
+  String _borderTop;
+
+  /** Gets the value of "border-top-color" */
+  String get borderTopColor => this._borderTopColor;
+
+  /** Sets the value of "border-top-color" */
+  set borderTopColor(String value) {
+    _borderTopColor = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderTopColor')
+  String _borderTopColor;
+
+  /** Gets the value of "border-top-style" */
+  String get borderTopStyle => this._borderTopStyle;
+
+  /** Sets the value of "border-top-style" */
+  set borderTopStyle(String value) {
+    _borderTopStyle = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderTopStyle')
+  String _borderTopStyle;
+
+  /** Gets the value of "border-top-width" */
+  String get borderTopWidth => this._borderTopWidth;
+
+  /** Sets the value of "border-top-width" */
+  set borderTopWidth(String value) {
+    _borderTopWidth = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderTopWidth')
+  String _borderTopWidth;
+
+  /** Gets the value of "border-width" */
+  String get borderWidth => this._borderWidth;
+
+  /** Sets the value of "border-width" */
+  set borderWidth(String value) {
+    _borderWidth = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('borderWidth')
+  String _borderWidth;
+
+  /** Gets the value of "bottom" */
+  String get bottom => this._bottom;
+
+  /** Sets the value of "bottom" */
+  set bottom(String value) {
+    _bottom = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('bottom')
+  String _bottom;
+
+  /** Gets the value of "caption-side" */
+  String get captionSide => this._captionSide;
+
+  /** Sets the value of "caption-side" */
+  set captionSide(String value) {
+    _captionSide = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('captionSide')
+  String _captionSide;
+
+  /** Gets the value of "clear" */
+  String get clear => this._clear;
+
+  /** Sets the value of "clear" */
+  set clear(String value) {
+    _clear = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('clear')
+  String _clear;
+
+  /** Gets the value of "clip" */
+  String get clip => this._clip;
+
+  /** Sets the value of "clip" */
+  set clip(String value) {
+    _clip = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('clip')
+  String _clip;
+
+  /** Gets the value of "color" */
+  String get color => this._color;
+
+  /** Sets the value of "color" */
+  set color(String value) {
+    _color = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('color')
+  String _color;
+
+  /** Gets the value of "content" */
+  String get content => this._content;
+
+  /** Sets the value of "content" */
+  set content(String value) {
+    _content = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('content')
+  String _content;
+
+  /** Gets the value of "cursor" */
+  String get cursor => this._cursor;
+
+  /** Sets the value of "cursor" */
+  set cursor(String value) {
+    _cursor = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('cursor')
+  String _cursor;
+
+  /** Gets the value of "direction" */
+  String get direction => this._direction;
+
+  /** Sets the value of "direction" */
+  set direction(String value) {
+    _direction = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('direction')
+  String _direction;
+
+  /** Gets the value of "display" */
+  String get display => this._display;
+
+  /** Sets the value of "display" */
+  set display(String value) {
+    _display = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('display')
+  String _display;
+
+  /** Gets the value of "empty-cells" */
+  String get emptyCells => this._emptyCells;
+
+  /** Sets the value of "empty-cells" */
+  set emptyCells(String value) {
+    _emptyCells = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('emptyCells')
+  String _emptyCells;
+
+  /** Gets the value of "font" */
+  String get font => this._font;
+
+  /** Sets the value of "font" */
+  set font(String value) {
+    _font = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('font')
+  String _font;
+
+  /** Gets the value of "font-family" */
+  String get fontFamily => this._fontFamily;
+
+  /** Sets the value of "font-family" */
+  set fontFamily(String value) {
+    _fontFamily = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('fontFamily')
+  String _fontFamily;
+
+  /** Gets the value of "font-size" */
+  String get fontSize => this._fontSize;
+
+  /** Sets the value of "font-size" */
+  set fontSize(String value) {
+    _fontSize = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('fontSize')
+  String _fontSize;
+
+  /** Gets the value of "font-style" */
+  String get fontStyle => this._fontStyle;
+
+  /** Sets the value of "font-style" */
+  set fontStyle(String value) {
+    _fontStyle = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('fontStyle')
+  String _fontStyle;
+
+  /** Gets the value of "font-variant" */
+  String get fontVariant => this._fontVariant;
+
+  /** Sets the value of "font-variant" */
+  set fontVariant(String value) {
+    _fontVariant = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('fontVariant')
+  String _fontVariant;
+
+  /** Gets the value of "font-weight" */
+  String get fontWeight => this._fontWeight;
+
+  /** Sets the value of "font-weight" */
+  set fontWeight(String value) {
+    _fontWeight = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('fontWeight')
+  String _fontWeight;
+
+  /** Gets the value of "height" */
+  String get height => this._height;
+
+  /** Sets the value of "height" */
+  set height(String value) {
+    _height = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('height')
+  String _height;
+
+  /** Gets the value of "left" */
+  String get left => this._left;
+
+  /** Sets the value of "left" */
+  set left(String value) {
+    _left = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('left')
+  String _left;
+
+  /** Gets the value of "letter-spacing" */
+  String get letterSpacing => this._letterSpacing;
+
+  /** Sets the value of "letter-spacing" */
+  set letterSpacing(String value) {
+    _letterSpacing = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('letterSpacing')
+  String _letterSpacing;
+
+  /** Gets the value of "line-height" */
+  String get lineHeight => this._lineHeight;
+
+  /** Sets the value of "line-height" */
+  set lineHeight(String value) {
+    _lineHeight = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('lineHeight')
+  String _lineHeight;
+
+  /** Gets the value of "list-style" */
+  String get listStyle => this._listStyle;
+
+  /** Sets the value of "list-style" */
+  set listStyle(String value) {
+    _listStyle = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('listStyle')
+  String _listStyle;
+
+  /** Gets the value of "list-style-image" */
+  String get listStyleImage => this._listStyleImage;
+
+  /** Sets the value of "list-style-image" */
+  set listStyleImage(String value) {
+    _listStyleImage = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('listStyleImage')
+  String _listStyleImage;
+
+  /** Gets the value of "list-style-position" */
+  String get listStylePosition => this._listStylePosition;
+
+  /** Sets the value of "list-style-position" */
+  set listStylePosition(String value) {
+    _listStylePosition = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('listStylePosition')
+  String _listStylePosition;
+
+  /** Gets the value of "list-style-type" */
+  String get listStyleType => this._listStyleType;
+
+  /** Sets the value of "list-style-type" */
+  set listStyleType(String value) {
+    _listStyleType = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('listStyleType')
+  String _listStyleType;
+
+  /** Gets the value of "margin" */
+  String get margin => this._margin;
+
+  /** Sets the value of "margin" */
+  set margin(String value) {
+    _margin = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('margin')
+  String _margin;
+
+  /** Gets the value of "margin-bottom" */
+  String get marginBottom => this._marginBottom;
+
+  /** Sets the value of "margin-bottom" */
+  set marginBottom(String value) {
+    _marginBottom = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('marginBottom')
+  String _marginBottom;
+
+  /** Gets the value of "margin-left" */
+  String get marginLeft => this._marginLeft;
+
+  /** Sets the value of "margin-left" */
+  set marginLeft(String value) {
+    _marginLeft = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('marginLeft')
+  String _marginLeft;
+
+  /** Gets the value of "margin-right" */
+  String get marginRight => this._marginRight;
+
+  /** Sets the value of "margin-right" */
+  set marginRight(String value) {
+    _marginRight = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('marginRight')
+  String _marginRight;
+
+  /** Gets the value of "margin-top" */
+  String get marginTop => this._marginTop;
+
+  /** Sets the value of "margin-top" */
+  set marginTop(String value) {
+    _marginTop = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('marginTop')
+  String _marginTop;
+
+  /** Gets the value of "max-height" */
+  String get maxHeight => this._maxHeight;
+
+  /** Sets the value of "max-height" */
+  set maxHeight(String value) {
+    _maxHeight = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('maxHeight')
+  String _maxHeight;
+
+  /** Gets the value of "max-width" */
+  String get maxWidth => this._maxWidth;
+
+  /** Sets the value of "max-width" */
+  set maxWidth(String value) {
+    _maxWidth = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('maxWidth')
+  String _maxWidth;
+
+  /** Gets the value of "min-height" */
+  String get minHeight => this._minHeight;
+
+  /** Sets the value of "min-height" */
+  set minHeight(String value) {
+    _minHeight = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('minHeight')
+  String _minHeight;
+
+  /** Gets the value of "min-width" */
+  String get minWidth => this._minWidth;
+
+  /** Sets the value of "min-width" */
+  set minWidth(String value) {
+    _minWidth = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('minWidth')
+  String _minWidth;
+
+  /** Gets the value of "outline" */
+  String get outline => this._outline;
+
+  /** Sets the value of "outline" */
+  set outline(String value) {
+    _outline = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('outline')
+  String _outline;
+
+  /** Gets the value of "outline-color" */
+  String get outlineColor => this._outlineColor;
+
+  /** Sets the value of "outline-color" */
+  set outlineColor(String value) {
+    _outlineColor = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('outlineColor')
+  String _outlineColor;
+
+  /** Gets the value of "outline-style" */
+  String get outlineStyle => this._outlineStyle;
+
+  /** Sets the value of "outline-style" */
+  set outlineStyle(String value) {
+    _outlineStyle = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('outlineStyle')
+  String _outlineStyle;
+
+  /** Gets the value of "outline-width" */
+  String get outlineWidth => this._outlineWidth;
+
+  /** Sets the value of "outline-width" */
+  set outlineWidth(String value) {
+    _outlineWidth = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('outlineWidth')
+  String _outlineWidth;
+
+  /** Gets the value of "overflow" */
+  String get overflow => this._overflow;
+
+  /** Sets the value of "overflow" */
+  set overflow(String value) {
+    _overflow = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('overflow')
+  String _overflow;
+
+  /** Gets the value of "padding" */
+  String get padding => this._padding;
+
+  /** Sets the value of "padding" */
+  set padding(String value) {
+    _padding = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('padding')
+  String _padding;
+
+  /** Gets the value of "padding-bottom" */
+  String get paddingBottom => this._paddingBottom;
+
+  /** Sets the value of "padding-bottom" */
+  set paddingBottom(String value) {
+    _paddingBottom = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('paddingBottom')
+  String _paddingBottom;
+
+  /** Gets the value of "padding-left" */
+  String get paddingLeft => this._paddingLeft;
+
+  /** Sets the value of "padding-left" */
+  set paddingLeft(String value) {
+    _paddingLeft = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('paddingLeft')
+  String _paddingLeft;
+
+  /** Gets the value of "padding-right" */
+  String get paddingRight => this._paddingRight;
+
+  /** Sets the value of "padding-right" */
+  set paddingRight(String value) {
+    _paddingRight = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('paddingRight')
+  String _paddingRight;
+
+  /** Gets the value of "padding-top" */
+  String get paddingTop => this._paddingTop;
+
+  /** Sets the value of "padding-top" */
+  set paddingTop(String value) {
+    _paddingTop = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('paddingTop')
+  String _paddingTop;
+
+  /** Gets the value of "page-break-after" */
+  String get pageBreakAfter => this._pageBreakAfter;
+
+  /** Sets the value of "page-break-after" */
+  set pageBreakAfter(String value) {
+    _pageBreakAfter = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('pageBreakAfter')
+  String _pageBreakAfter;
+
+  /** Gets the value of "page-break-before" */
+  String get pageBreakBefore => this._pageBreakBefore;
+
+  /** Sets the value of "page-break-before" */
+  set pageBreakBefore(String value) {
+    _pageBreakBefore = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('pageBreakBefore')
+  String _pageBreakBefore;
+
+  /** Gets the value of "page-break-inside" */
+  String get pageBreakInside => this._pageBreakInside;
+
+  /** Sets the value of "page-break-inside" */
+  set pageBreakInside(String value) {
+    _pageBreakInside = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('pageBreakInside')
+  String _pageBreakInside;
+
+  /** Gets the value of "position" */
+  String get position => this._position;
+
+  /** Sets the value of "position" */
+  set position(String value) {
+    _position = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('position')
+  String _position;
+
+  /** Gets the value of "quotes" */
+  String get quotes => this._quotes;
+
+  /** Sets the value of "quotes" */
+  set quotes(String value) {
+    _quotes = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('quotes')
+  String _quotes;
+
+  /** Gets the value of "right" */
+  String get right => this._right;
+
+  /** Sets the value of "right" */
+  set right(String value) {
+    _right = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('right')
+  String _right;
+
+  /** Gets the value of "table-layout" */
+  String get tableLayout => this._tableLayout;
+
+  /** Sets the value of "table-layout" */
+  set tableLayout(String value) {
+    _tableLayout = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('tableLayout')
+  String _tableLayout;
+
+  /** Gets the value of "text-align" */
+  String get textAlign => this._textAlign;
+
+  /** Sets the value of "text-align" */
+  set textAlign(String value) {
+    _textAlign = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('textAlign')
+  String _textAlign;
+
+  /** Gets the value of "text-decoration" */
+  String get textDecoration => this._textDecoration;
+
+  /** Sets the value of "text-decoration" */
+  set textDecoration(String value) {
+    _textDecoration = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('textDecoration')
+  String _textDecoration;
+
+  /** Gets the value of "text-indent" */
+  String get textIndent => this._textIndent;
+
+  /** Sets the value of "text-indent" */
+  set textIndent(String value) {
+    _textIndent = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('textIndent')
+  String _textIndent;
+
+  /** Gets the value of "text-transform" */
+  String get textTransform => this._textTransform;
+
+  /** Sets the value of "text-transform" */
+  set textTransform(String value) {
+    _textTransform = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('textTransform')
+  String _textTransform;
+
+  /** Gets the value of "top" */
+  String get top => this._top;
+
+  /** Sets the value of "top" */
+  set top(String value) {
+    _top = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('top')
+  String _top;
+
+  /** Gets the value of "unicode-bidi" */
+  String get unicodeBidi => this._unicodeBidi;
+
+  /** Sets the value of "unicode-bidi" */
+  set unicodeBidi(String value) {
+    _unicodeBidi = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('unicodeBidi')
+  String _unicodeBidi;
+
+  /** Gets the value of "vertical-align" */
+  String get verticalAlign => this._verticalAlign;
+
+  /** Sets the value of "vertical-align" */
+  set verticalAlign(String value) {
+    _verticalAlign = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('verticalAlign')
+  String _verticalAlign;
+
+  /** Gets the value of "visibility" */
+  String get visibility => this._visibility;
+
+  /** Sets the value of "visibility" */
+  set visibility(String value) {
+    _visibility = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('visibility')
+  String _visibility;
+
+  /** Gets the value of "white-space" */
+  String get whiteSpace => this._whiteSpace;
+
+  /** Sets the value of "white-space" */
+  set whiteSpace(String value) {
+    _whiteSpace = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('whiteSpace')
+  String _whiteSpace;
+
+  /** Gets the value of "width" */
+  String get width => this._width;
+
+  /** Sets the value of "width" */
+  set width(String value) {
+    _width = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('width')
+  String _width;
+
+  /** Gets the value of "word-spacing" */
+  String get wordSpacing => this._wordSpacing;
+
+  /** Sets the value of "word-spacing" */
+  set wordSpacing(String value) {
+    _wordSpacing = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('wordSpacing')
+  String _wordSpacing;
+
+  /** Gets the value of "z-index" */
+  String get zIndex => this._zIndex;
+
+  /** Sets the value of "z-index" */
+  set zIndex(String value) {
+    _zIndex = value == null ? '' : value;
+  }
+
+  @Returns('String')
+  @JSName('zIndex')
+  String _zIndex;
+}
+
+class _CssStyleDeclarationSet extends Object with CssStyleDeclarationBase {
+  final Iterable<Element> _elementIterable;
+  Iterable<CssStyleDeclaration> _elementCssStyleDeclarationSetIterable;
+
+  _CssStyleDeclarationSet(this._elementIterable) {
+    _elementCssStyleDeclarationSetIterable =
+        new List.from(_elementIterable).map((e) => e.style);
+  }
+
+  String getPropertyValue(String propertyName) =>
+      _elementCssStyleDeclarationSetIterable.first
+          .getPropertyValue(propertyName);
+
+  void setProperty(String propertyName, String value, [String priority]) {
+    _elementCssStyleDeclarationSetIterable
+        .forEach((e) => e.setProperty(propertyName, value, priority));
+  }
+
+  void _setAll(String propertyName, String value) {
+    value = value == null ? '' : value;
+    for (Element element in _elementIterable) {
+      JS('void', '#.style[#] = #', element, propertyName, value);
+    }
+  }
+
+  /** Sets the value of "background" */
+  set background(String value) {
+    _setAll('background', value);
+  }
+
+  /** Sets the value of "background-attachment" */
+  set backgroundAttachment(String value) {
+    _setAll('backgroundAttachment', value);
+  }
+
+  /** Sets the value of "background-color" */
+  set backgroundColor(String value) {
+    _setAll('backgroundColor', value);
+  }
+
+  /** Sets the value of "background-image" */
+  set backgroundImage(String value) {
+    _setAll('backgroundImage', value);
+  }
+
+  /** Sets the value of "background-position" */
+  set backgroundPosition(String value) {
+    _setAll('backgroundPosition', value);
+  }
+
+  /** Sets the value of "background-repeat" */
+  set backgroundRepeat(String value) {
+    _setAll('backgroundRepeat', value);
+  }
+
+  /** Sets the value of "border" */
+  set border(String value) {
+    _setAll('border', value);
+  }
+
+  /** Sets the value of "border-bottom" */
+  set borderBottom(String value) {
+    _setAll('borderBottom', value);
+  }
+
+  /** Sets the value of "border-bottom-color" */
+  set borderBottomColor(String value) {
+    _setAll('borderBottomColor', value);
+  }
+
+  /** Sets the value of "border-bottom-style" */
+  set borderBottomStyle(String value) {
+    _setAll('borderBottomStyle', value);
+  }
+
+  /** Sets the value of "border-bottom-width" */
+  set borderBottomWidth(String value) {
+    _setAll('borderBottomWidth', value);
+  }
+
+  /** Sets the value of "border-collapse" */
+  set borderCollapse(String value) {
+    _setAll('borderCollapse', value);
+  }
+
+  /** Sets the value of "border-color" */
+  set borderColor(String value) {
+    _setAll('borderColor', value);
+  }
+
+  /** Sets the value of "border-left" */
+  set borderLeft(String value) {
+    _setAll('borderLeft', value);
+  }
+
+  /** Sets the value of "border-left-color" */
+  set borderLeftColor(String value) {
+    _setAll('borderLeftColor', value);
+  }
+
+  /** Sets the value of "border-left-style" */
+  set borderLeftStyle(String value) {
+    _setAll('borderLeftStyle', value);
+  }
+
+  /** Sets the value of "border-left-width" */
+  set borderLeftWidth(String value) {
+    _setAll('borderLeftWidth', value);
+  }
+
+  /** Sets the value of "border-right" */
+  set borderRight(String value) {
+    _setAll('borderRight', value);
+  }
+
+  /** Sets the value of "border-right-color" */
+  set borderRightColor(String value) {
+    _setAll('borderRightColor', value);
+  }
+
+  /** Sets the value of "border-right-style" */
+  set borderRightStyle(String value) {
+    _setAll('borderRightStyle', value);
+  }
+
+  /** Sets the value of "border-right-width" */
+  set borderRightWidth(String value) {
+    _setAll('borderRightWidth', value);
+  }
+
+  /** Sets the value of "border-spacing" */
+  set borderSpacing(String value) {
+    _setAll('borderSpacing', value);
+  }
+
+  /** Sets the value of "border-style" */
+  set borderStyle(String value) {
+    _setAll('borderStyle', value);
+  }
+
+  /** Sets the value of "border-top" */
+  set borderTop(String value) {
+    _setAll('borderTop', value);
+  }
+
+  /** Sets the value of "border-top-color" */
+  set borderTopColor(String value) {
+    _setAll('borderTopColor', value);
+  }
+
+  /** Sets the value of "border-top-style" */
+  set borderTopStyle(String value) {
+    _setAll('borderTopStyle', value);
+  }
+
+  /** Sets the value of "border-top-width" */
+  set borderTopWidth(String value) {
+    _setAll('borderTopWidth', value);
+  }
+
+  /** Sets the value of "border-width" */
+  set borderWidth(String value) {
+    _setAll('borderWidth', value);
+  }
+
+  /** Sets the value of "bottom" */
+  set bottom(String value) {
+    _setAll('bottom', value);
+  }
+
+  /** Sets the value of "caption-side" */
+  set captionSide(String value) {
+    _setAll('captionSide', value);
+  }
+
+  /** Sets the value of "clear" */
+  set clear(String value) {
+    _setAll('clear', value);
+  }
+
+  /** Sets the value of "clip" */
+  set clip(String value) {
+    _setAll('clip', value);
+  }
+
+  /** Sets the value of "color" */
+  set color(String value) {
+    _setAll('color', value);
+  }
+
+  /** Sets the value of "content" */
+  set content(String value) {
+    _setAll('content', value);
+  }
+
+  /** Sets the value of "cursor" */
+  set cursor(String value) {
+    _setAll('cursor', value);
+  }
+
+  /** Sets the value of "direction" */
+  set direction(String value) {
+    _setAll('direction', value);
+  }
+
+  /** Sets the value of "display" */
+  set display(String value) {
+    _setAll('display', value);
+  }
+
+  /** Sets the value of "empty-cells" */
+  set emptyCells(String value) {
+    _setAll('emptyCells', value);
+  }
+
+  /** Sets the value of "font" */
+  set font(String value) {
+    _setAll('font', value);
+  }
+
+  /** Sets the value of "font-family" */
+  set fontFamily(String value) {
+    _setAll('fontFamily', value);
+  }
+
+  /** Sets the value of "font-size" */
+  set fontSize(String value) {
+    _setAll('fontSize', value);
+  }
+
+  /** Sets the value of "font-style" */
+  set fontStyle(String value) {
+    _setAll('fontStyle', value);
+  }
+
+  /** Sets the value of "font-variant" */
+  set fontVariant(String value) {
+    _setAll('fontVariant', value);
+  }
+
+  /** Sets the value of "font-weight" */
+  set fontWeight(String value) {
+    _setAll('fontWeight', value);
+  }
+
+  /** Sets the value of "height" */
+  set height(String value) {
+    _setAll('height', value);
+  }
+
+  /** Sets the value of "left" */
+  set left(String value) {
+    _setAll('left', value);
+  }
+
+  /** Sets the value of "letter-spacing" */
+  set letterSpacing(String value) {
+    _setAll('letterSpacing', value);
+  }
+
+  /** Sets the value of "line-height" */
+  set lineHeight(String value) {
+    _setAll('lineHeight', value);
+  }
+
+  /** Sets the value of "list-style" */
+  set listStyle(String value) {
+    _setAll('listStyle', value);
+  }
+
+  /** Sets the value of "list-style-image" */
+  set listStyleImage(String value) {
+    _setAll('listStyleImage', value);
+  }
+
+  /** Sets the value of "list-style-position" */
+  set listStylePosition(String value) {
+    _setAll('listStylePosition', value);
+  }
+
+  /** Sets the value of "list-style-type" */
+  set listStyleType(String value) {
+    _setAll('listStyleType', value);
+  }
+
+  /** Sets the value of "margin" */
+  set margin(String value) {
+    _setAll('margin', value);
+  }
+
+  /** Sets the value of "margin-bottom" */
+  set marginBottom(String value) {
+    _setAll('marginBottom', value);
+  }
+
+  /** Sets the value of "margin-left" */
+  set marginLeft(String value) {
+    _setAll('marginLeft', value);
+  }
+
+  /** Sets the value of "margin-right" */
+  set marginRight(String value) {
+    _setAll('marginRight', value);
+  }
+
+  /** Sets the value of "margin-top" */
+  set marginTop(String value) {
+    _setAll('marginTop', value);
+  }
+
+  /** Sets the value of "max-height" */
+  set maxHeight(String value) {
+    _setAll('maxHeight', value);
+  }
+
+  /** Sets the value of "max-width" */
+  set maxWidth(String value) {
+    _setAll('maxWidth', value);
+  }
+
+  /** Sets the value of "min-height" */
+  set minHeight(String value) {
+    _setAll('minHeight', value);
+  }
+
+  /** Sets the value of "min-width" */
+  set minWidth(String value) {
+    _setAll('minWidth', value);
+  }
+
+  /** Sets the value of "outline" */
+  set outline(String value) {
+    _setAll('outline', value);
+  }
+
+  /** Sets the value of "outline-color" */
+  set outlineColor(String value) {
+    _setAll('outlineColor', value);
+  }
+
+  /** Sets the value of "outline-style" */
+  set outlineStyle(String value) {
+    _setAll('outlineStyle', value);
+  }
+
+  /** Sets the value of "outline-width" */
+  set outlineWidth(String value) {
+    _setAll('outlineWidth', value);
+  }
+
+  /** Sets the value of "overflow" */
+  set overflow(String value) {
+    _setAll('overflow', value);
+  }
+
+  /** Sets the value of "padding" */
+  set padding(String value) {
+    _setAll('padding', value);
+  }
+
+  /** Sets the value of "padding-bottom" */
+  set paddingBottom(String value) {
+    _setAll('paddingBottom', value);
+  }
+
+  /** Sets the value of "padding-left" */
+  set paddingLeft(String value) {
+    _setAll('paddingLeft', value);
+  }
+
+  /** Sets the value of "padding-right" */
+  set paddingRight(String value) {
+    _setAll('paddingRight', value);
+  }
+
+  /** Sets the value of "padding-top" */
+  set paddingTop(String value) {
+    _setAll('paddingTop', value);
+  }
+
+  /** Sets the value of "page-break-after" */
+  set pageBreakAfter(String value) {
+    _setAll('pageBreakAfter', value);
+  }
+
+  /** Sets the value of "page-break-before" */
+  set pageBreakBefore(String value) {
+    _setAll('pageBreakBefore', value);
+  }
+
+  /** Sets the value of "page-break-inside" */
+  set pageBreakInside(String value) {
+    _setAll('pageBreakInside', value);
+  }
+
+  /** Sets the value of "position" */
+  set position(String value) {
+    _setAll('position', value);
+  }
+
+  /** Sets the value of "quotes" */
+  set quotes(String value) {
+    _setAll('quotes', value);
+  }
+
+  /** Sets the value of "right" */
+  set right(String value) {
+    _setAll('right', value);
+  }
+
+  /** Sets the value of "table-layout" */
+  set tableLayout(String value) {
+    _setAll('tableLayout', value);
+  }
+
+  /** Sets the value of "text-align" */
+  set textAlign(String value) {
+    _setAll('textAlign', value);
+  }
+
+  /** Sets the value of "text-decoration" */
+  set textDecoration(String value) {
+    _setAll('textDecoration', value);
+  }
+
+  /** Sets the value of "text-indent" */
+  set textIndent(String value) {
+    _setAll('textIndent', value);
+  }
+
+  /** Sets the value of "text-transform" */
+  set textTransform(String value) {
+    _setAll('textTransform', value);
+  }
+
+  /** Sets the value of "top" */
+  set top(String value) {
+    _setAll('top', value);
+  }
+
+  /** Sets the value of "unicode-bidi" */
+  set unicodeBidi(String value) {
+    _setAll('unicodeBidi', value);
+  }
+
+  /** Sets the value of "vertical-align" */
+  set verticalAlign(String value) {
+    _setAll('verticalAlign', value);
+  }
+
+  /** Sets the value of "visibility" */
+  set visibility(String value) {
+    _setAll('visibility', value);
+  }
+
+  /** Sets the value of "white-space" */
+  set whiteSpace(String value) {
+    _setAll('whiteSpace', value);
+  }
+
+  /** Sets the value of "width" */
+  set width(String value) {
+    _setAll('width', value);
+  }
+
+  /** Sets the value of "word-spacing" */
+  set wordSpacing(String value) {
+    _setAll('wordSpacing', value);
+  }
+
+  /** Sets the value of "z-index" */
+  set zIndex(String value) {
+    _setAll('zIndex', value);
+  }
+
+  // Important note: CssStyleDeclarationSet does NOT implement every method
+  // available in CssStyleDeclaration. Some of the methods don't make so much
+  // sense in terms of having a resonable value to return when you're
+  // considering a list of Elements. You will need to manually add any of the
+  // items in the MEMBERS set if you want that functionality.
+}
+
+abstract class CssStyleDeclarationBase {
+  String getPropertyValue(String propertyName);
+  void setProperty(String propertyName, String value, [String priority]);
+
+  /** Gets the value of "align-content" */
+  String get alignContent => getPropertyValue('align-content');
+
+  /** Sets the value of "align-content" */
+  set alignContent(String value) {
+    setProperty('align-content', value, '');
+  }
+
+  /** Gets the value of "align-items" */
+  String get alignItems => getPropertyValue('align-items');
+
+  /** Sets the value of "align-items" */
+  set alignItems(String value) {
+    setProperty('align-items', value, '');
+  }
+
+  /** Gets the value of "align-self" */
+  String get alignSelf => getPropertyValue('align-self');
+
+  /** Sets the value of "align-self" */
+  set alignSelf(String value) {
+    setProperty('align-self', value, '');
+  }
+
+  /** Gets the value of "animation" */
+  String get animation => getPropertyValue('animation');
+
+  /** Sets the value of "animation" */
+  set animation(String value) {
+    setProperty('animation', value, '');
+  }
+
+  /** Gets the value of "animation-delay" */
+  String get animationDelay => getPropertyValue('animation-delay');
+
+  /** Sets the value of "animation-delay" */
+  set animationDelay(String value) {
+    setProperty('animation-delay', value, '');
+  }
+
+  /** Gets the value of "animation-direction" */
+  String get animationDirection => getPropertyValue('animation-direction');
+
+  /** Sets the value of "animation-direction" */
+  set animationDirection(String value) {
+    setProperty('animation-direction', value, '');
+  }
+
+  /** Gets the value of "animation-duration" */
+  String get animationDuration => getPropertyValue('animation-duration');
+
+  /** Sets the value of "animation-duration" */
+  set animationDuration(String value) {
+    setProperty('animation-duration', value, '');
+  }
+
+  /** Gets the value of "animation-fill-mode" */
+  String get animationFillMode => getPropertyValue('animation-fill-mode');
+
+  /** Sets the value of "animation-fill-mode" */
+  set animationFillMode(String value) {
+    setProperty('animation-fill-mode', value, '');
+  }
+
+  /** Gets the value of "animation-iteration-count" */
+  String get animationIterationCount =>
+      getPropertyValue('animation-iteration-count');
+
+  /** Sets the value of "animation-iteration-count" */
+  set animationIterationCount(String value) {
+    setProperty('animation-iteration-count', value, '');
+  }
+
+  /** Gets the value of "animation-name" */
+  String get animationName => getPropertyValue('animation-name');
+
+  /** Sets the value of "animation-name" */
+  set animationName(String value) {
+    setProperty('animation-name', value, '');
+  }
+
+  /** Gets the value of "animation-play-state" */
+  String get animationPlayState => getPropertyValue('animation-play-state');
+
+  /** Sets the value of "animation-play-state" */
+  set animationPlayState(String value) {
+    setProperty('animation-play-state', value, '');
+  }
+
+  /** Gets the value of "animation-timing-function" */
+  String get animationTimingFunction =>
+      getPropertyValue('animation-timing-function');
+
+  /** Sets the value of "animation-timing-function" */
+  set animationTimingFunction(String value) {
+    setProperty('animation-timing-function', value, '');
+  }
+
+  /** Gets the value of "app-region" */
+  String get appRegion => getPropertyValue('app-region');
+
+  /** Sets the value of "app-region" */
+  set appRegion(String value) {
+    setProperty('app-region', value, '');
+  }
+
+  /** Gets the value of "appearance" */
+  String get appearance => getPropertyValue('appearance');
+
+  /** Sets the value of "appearance" */
+  set appearance(String value) {
+    setProperty('appearance', value, '');
+  }
+
+  /** Gets the value of "aspect-ratio" */
+  String get aspectRatio => getPropertyValue('aspect-ratio');
+
+  /** Sets the value of "aspect-ratio" */
+  set aspectRatio(String value) {
+    setProperty('aspect-ratio', value, '');
+  }
+
+  /** Gets the value of "backface-visibility" */
+  String get backfaceVisibility => getPropertyValue('backface-visibility');
+
+  /** Sets the value of "backface-visibility" */
+  set backfaceVisibility(String value) {
+    setProperty('backface-visibility', value, '');
+  }
+
+  /** Gets the value of "background" */
+  String get background => getPropertyValue('background');
+
+  /** Sets the value of "background" */
+  set background(String value) {
+    setProperty('background', value, '');
+  }
+
+  /** Gets the value of "background-attachment" */
+  String get backgroundAttachment => getPropertyValue('background-attachment');
+
+  /** Sets the value of "background-attachment" */
+  set backgroundAttachment(String value) {
+    setProperty('background-attachment', value, '');
+  }
+
+  /** Gets the value of "background-blend-mode" */
+  String get backgroundBlendMode => getPropertyValue('background-blend-mode');
+
+  /** Sets the value of "background-blend-mode" */
+  set backgroundBlendMode(String value) {
+    setProperty('background-blend-mode', value, '');
+  }
+
+  /** Gets the value of "background-clip" */
+  String get backgroundClip => getPropertyValue('background-clip');
+
+  /** Sets the value of "background-clip" */
+  set backgroundClip(String value) {
+    setProperty('background-clip', value, '');
+  }
+
+  /** Gets the value of "background-color" */
+  String get backgroundColor => getPropertyValue('background-color');
+
+  /** Sets the value of "background-color" */
+  set backgroundColor(String value) {
+    setProperty('background-color', value, '');
+  }
+
+  /** Gets the value of "background-composite" */
+  String get backgroundComposite => getPropertyValue('background-composite');
+
+  /** Sets the value of "background-composite" */
+  set backgroundComposite(String value) {
+    setProperty('background-composite', value, '');
+  }
+
+  /** Gets the value of "background-image" */
+  String get backgroundImage => getPropertyValue('background-image');
+
+  /** Sets the value of "background-image" */
+  set backgroundImage(String value) {
+    setProperty('background-image', value, '');
+  }
+
+  /** Gets the value of "background-origin" */
+  String get backgroundOrigin => getPropertyValue('background-origin');
+
+  /** Sets the value of "background-origin" */
+  set backgroundOrigin(String value) {
+    setProperty('background-origin', value, '');
+  }
+
+  /** Gets the value of "background-position" */
+  String get backgroundPosition => getPropertyValue('background-position');
+
+  /** Sets the value of "background-position" */
+  set backgroundPosition(String value) {
+    setProperty('background-position', value, '');
+  }
+
+  /** Gets the value of "background-position-x" */
+  String get backgroundPositionX => getPropertyValue('background-position-x');
+
+  /** Sets the value of "background-position-x" */
+  set backgroundPositionX(String value) {
+    setProperty('background-position-x', value, '');
+  }
+
+  /** Gets the value of "background-position-y" */
+  String get backgroundPositionY => getPropertyValue('background-position-y');
+
+  /** Sets the value of "background-position-y" */
+  set backgroundPositionY(String value) {
+    setProperty('background-position-y', value, '');
+  }
+
+  /** Gets the value of "background-repeat" */
+  String get backgroundRepeat => getPropertyValue('background-repeat');
+
+  /** Sets the value of "background-repeat" */
+  set backgroundRepeat(String value) {
+    setProperty('background-repeat', value, '');
+  }
+
+  /** Gets the value of "background-repeat-x" */
+  String get backgroundRepeatX => getPropertyValue('background-repeat-x');
+
+  /** Sets the value of "background-repeat-x" */
+  set backgroundRepeatX(String value) {
+    setProperty('background-repeat-x', value, '');
+  }
+
+  /** Gets the value of "background-repeat-y" */
+  String get backgroundRepeatY => getPropertyValue('background-repeat-y');
+
+  /** Sets the value of "background-repeat-y" */
+  set backgroundRepeatY(String value) {
+    setProperty('background-repeat-y', value, '');
+  }
+
+  /** Gets the value of "background-size" */
+  String get backgroundSize => getPropertyValue('background-size');
+
+  /** Sets the value of "background-size" */
+  set backgroundSize(String value) {
+    setProperty('background-size', value, '');
+  }
+
+  /** Gets the value of "border" */
+  String get border => getPropertyValue('border');
+
+  /** Sets the value of "border" */
+  set border(String value) {
+    setProperty('border', value, '');
+  }
+
+  /** Gets the value of "border-after" */
+  String get borderAfter => getPropertyValue('border-after');
+
+  /** Sets the value of "border-after" */
+  set borderAfter(String value) {
+    setProperty('border-after', value, '');
+  }
+
+  /** Gets the value of "border-after-color" */
+  String get borderAfterColor => getPropertyValue('border-after-color');
+
+  /** Sets the value of "border-after-color" */
+  set borderAfterColor(String value) {
+    setProperty('border-after-color', value, '');
+  }
+
+  /** Gets the value of "border-after-style" */
+  String get borderAfterStyle => getPropertyValue('border-after-style');
+
+  /** Sets the value of "border-after-style" */
+  set borderAfterStyle(String value) {
+    setProperty('border-after-style', value, '');
+  }
+
+  /** Gets the value of "border-after-width" */
+  String get borderAfterWidth => getPropertyValue('border-after-width');
+
+  /** Sets the value of "border-after-width" */
+  set borderAfterWidth(String value) {
+    setProperty('border-after-width', value, '');
+  }
+
+  /** Gets the value of "border-before" */
+  String get borderBefore => getPropertyValue('border-before');
+
+  /** Sets the value of "border-before" */
+  set borderBefore(String value) {
+    setProperty('border-before', value, '');
+  }
+
+  /** Gets the value of "border-before-color" */
+  String get borderBeforeColor => getPropertyValue('border-before-color');
+
+  /** Sets the value of "border-before-color" */
+  set borderBeforeColor(String value) {
+    setProperty('border-before-color', value, '');
+  }
+
+  /** Gets the value of "border-before-style" */
+  String get borderBeforeStyle => getPropertyValue('border-before-style');
+
+  /** Sets the value of "border-before-style" */
+  set borderBeforeStyle(String value) {
+    setProperty('border-before-style', value, '');
+  }
+
+  /** Gets the value of "border-before-width" */
+  String get borderBeforeWidth => getPropertyValue('border-before-width');
+
+  /** Sets the value of "border-before-width" */
+  set borderBeforeWidth(String value) {
+    setProperty('border-before-width', value, '');
+  }
+
+  /** Gets the value of "border-bottom" */
+  String get borderBottom => getPropertyValue('border-bottom');
+
+  /** Sets the value of "border-bottom" */
+  set borderBottom(String value) {
+    setProperty('border-bottom', value, '');
+  }
+
+  /** Gets the value of "border-bottom-color" */
+  String get borderBottomColor => getPropertyValue('border-bottom-color');
+
+  /** Sets the value of "border-bottom-color" */
+  set borderBottomColor(String value) {
+    setProperty('border-bottom-color', value, '');
+  }
+
+  /** Gets the value of "border-bottom-left-radius" */
+  String get borderBottomLeftRadius =>
+      getPropertyValue('border-bottom-left-radius');
+
+  /** Sets the value of "border-bottom-left-radius" */
+  set borderBottomLeftRadius(String value) {
+    setProperty('border-bottom-left-radius', value, '');
+  }
+
+  /** Gets the value of "border-bottom-right-radius" */
+  String get borderBottomRightRadius =>
+      getPropertyValue('border-bottom-right-radius');
+
+  /** Sets the value of "border-bottom-right-radius" */
+  set borderBottomRightRadius(String value) {
+    setProperty('border-bottom-right-radius', value, '');
+  }
+
+  /** Gets the value of "border-bottom-style" */
+  String get borderBottomStyle => getPropertyValue('border-bottom-style');
+
+  /** Sets the value of "border-bottom-style" */
+  set borderBottomStyle(String value) {
+    setProperty('border-bottom-style', value, '');
+  }
+
+  /** Gets the value of "border-bottom-width" */
+  String get borderBottomWidth => getPropertyValue('border-bottom-width');
+
+  /** Sets the value of "border-bottom-width" */
+  set borderBottomWidth(String value) {
+    setProperty('border-bottom-width', value, '');
+  }
+
+  /** Gets the value of "border-collapse" */
+  String get borderCollapse => getPropertyValue('border-collapse');
+
+  /** Sets the value of "border-collapse" */
+  set borderCollapse(String value) {
+    setProperty('border-collapse', value, '');
+  }
+
+  /** Gets the value of "border-color" */
+  String get borderColor => getPropertyValue('border-color');
+
+  /** Sets the value of "border-color" */
+  set borderColor(String value) {
+    setProperty('border-color', value, '');
+  }
+
+  /** Gets the value of "border-end" */
+  String get borderEnd => getPropertyValue('border-end');
+
+  /** Sets the value of "border-end" */
+  set borderEnd(String value) {
+    setProperty('border-end', value, '');
+  }
+
+  /** Gets the value of "border-end-color" */
+  String get borderEndColor => getPropertyValue('border-end-color');
+
+  /** Sets the value of "border-end-color" */
+  set borderEndColor(String value) {
+    setProperty('border-end-color', value, '');
+  }
+
+  /** Gets the value of "border-end-style" */
+  String get borderEndStyle => getPropertyValue('border-end-style');
+
+  /** Sets the value of "border-end-style" */
+  set borderEndStyle(String value) {
+    setProperty('border-end-style', value, '');
+  }
+
+  /** Gets the value of "border-end-width" */
+  String get borderEndWidth => getPropertyValue('border-end-width');
+
+  /** Sets the value of "border-end-width" */
+  set borderEndWidth(String value) {
+    setProperty('border-end-width', value, '');
+  }
+
+  /** Gets the value of "border-fit" */
+  String get borderFit => getPropertyValue('border-fit');
+
+  /** Sets the value of "border-fit" */
+  set borderFit(String value) {
+    setProperty('border-fit', value, '');
+  }
+
+  /** Gets the value of "border-horizontal-spacing" */
+  String get borderHorizontalSpacing =>
+      getPropertyValue('border-horizontal-spacing');
+
+  /** Sets the value of "border-horizontal-spacing" */
+  set borderHorizontalSpacing(String value) {
+    setProperty('border-horizontal-spacing', value, '');
+  }
+
+  /** Gets the value of "border-image" */
+  String get borderImage => getPropertyValue('border-image');
+
+  /** Sets the value of "border-image" */
+  set borderImage(String value) {
+    setProperty('border-image', value, '');
+  }
+
+  /** Gets the value of "border-image-outset" */
+  String get borderImageOutset => getPropertyValue('border-image-outset');
+
+  /** Sets the value of "border-image-outset" */
+  set borderImageOutset(String value) {
+    setProperty('border-image-outset', value, '');
+  }
+
+  /** Gets the value of "border-image-repeat" */
+  String get borderImageRepeat => getPropertyValue('border-image-repeat');
+
+  /** Sets the value of "border-image-repeat" */
+  set borderImageRepeat(String value) {
+    setProperty('border-image-repeat', value, '');
+  }
+
+  /** Gets the value of "border-image-slice" */
+  String get borderImageSlice => getPropertyValue('border-image-slice');
+
+  /** Sets the value of "border-image-slice" */
+  set borderImageSlice(String value) {
+    setProperty('border-image-slice', value, '');
+  }
+
+  /** Gets the value of "border-image-source" */
+  String get borderImageSource => getPropertyValue('border-image-source');
+
+  /** Sets the value of "border-image-source" */
+  set borderImageSource(String value) {
+    setProperty('border-image-source', value, '');
+  }
+
+  /** Gets the value of "border-image-width" */
+  String get borderImageWidth => getPropertyValue('border-image-width');
+
+  /** Sets the value of "border-image-width" */
+  set borderImageWidth(String value) {
+    setProperty('border-image-width', value, '');
+  }
+
+  /** Gets the value of "border-left" */
+  String get borderLeft => getPropertyValue('border-left');
+
+  /** Sets the value of "border-left" */
+  set borderLeft(String value) {
+    setProperty('border-left', value, '');
+  }
+
+  /** Gets the value of "border-left-color" */
+  String get borderLeftColor => getPropertyValue('border-left-color');
+
+  /** Sets the value of "border-left-color" */
+  set borderLeftColor(String value) {
+    setProperty('border-left-color', value, '');
+  }
+
+  /** Gets the value of "border-left-style" */
+  String get borderLeftStyle => getPropertyValue('border-left-style');
+
+  /** Sets the value of "border-left-style" */
+  set borderLeftStyle(String value) {
+    setProperty('border-left-style', value, '');
+  }
+
+  /** Gets the value of "border-left-width" */
+  String get borderLeftWidth => getPropertyValue('border-left-width');
+
+  /** Sets the value of "border-left-width" */
+  set borderLeftWidth(String value) {
+    setProperty('border-left-width', value, '');
+  }
+
+  /** Gets the value of "border-radius" */
+  String get borderRadius => getPropertyValue('border-radius');
+
+  /** Sets the value of "border-radius" */
+  set borderRadius(String value) {
+    setProperty('border-radius', value, '');
+  }
+
+  /** Gets the value of "border-right" */
+  String get borderRight => getPropertyValue('border-right');
+
+  /** Sets the value of "border-right" */
+  set borderRight(String value) {
+    setProperty('border-right', value, '');
+  }
+
+  /** Gets the value of "border-right-color" */
+  String get borderRightColor => getPropertyValue('border-right-color');
+
+  /** Sets the value of "border-right-color" */
+  set borderRightColor(String value) {
+    setProperty('border-right-color', value, '');
+  }
+
+  /** Gets the value of "border-right-style" */
+  String get borderRightStyle => getPropertyValue('border-right-style');
+
+  /** Sets the value of "border-right-style" */
+  set borderRightStyle(String value) {
+    setProperty('border-right-style', value, '');
+  }
+
+  /** Gets the value of "border-right-width" */
+  String get borderRightWidth => getPropertyValue('border-right-width');
+
+  /** Sets the value of "border-right-width" */
+  set borderRightWidth(String value) {
+    setProperty('border-right-width', value, '');
+  }
+
+  /** Gets the value of "border-spacing" */
+  String get borderSpacing => getPropertyValue('border-spacing');
+
+  /** Sets the value of "border-spacing" */
+  set borderSpacing(String value) {
+    setProperty('border-spacing', value, '');
+  }
+
+  /** Gets the value of "border-start" */
+  String get borderStart => getPropertyValue('border-start');
+
+  /** Sets the value of "border-start" */
+  set borderStart(String value) {
+    setProperty('border-start', value, '');
+  }
+
+  /** Gets the value of "border-start-color" */
+  String get borderStartColor => getPropertyValue('border-start-color');
+
+  /** Sets the value of "border-start-color" */
+  set borderStartColor(String value) {
+    setProperty('border-start-color', value, '');
+  }
+
+  /** Gets the value of "border-start-style" */
+  String get borderStartStyle => getPropertyValue('border-start-style');
+
+  /** Sets the value of "border-start-style" */
+  set borderStartStyle(String value) {
+    setProperty('border-start-style', value, '');
+  }
+
+  /** Gets the value of "border-start-width" */
+  String get borderStartWidth => getPropertyValue('border-start-width');
+
+  /** Sets the value of "border-start-width" */
+  set borderStartWidth(String value) {
+    setProperty('border-start-width', value, '');
+  }
+
+  /** Gets the value of "border-style" */
+  String get borderStyle => getPropertyValue('border-style');
+
+  /** Sets the value of "border-style" */
+  set borderStyle(String value) {
+    setProperty('border-style', value, '');
+  }
+
+  /** Gets the value of "border-top" */
+  String get borderTop => getPropertyValue('border-top');
+
+  /** Sets the value of "border-top" */
+  set borderTop(String value) {
+    setProperty('border-top', value, '');
+  }
+
+  /** Gets the value of "border-top-color" */
+  String get borderTopColor => getPropertyValue('border-top-color');
+
+  /** Sets the value of "border-top-color" */
+  set borderTopColor(String value) {
+    setProperty('border-top-color', value, '');
+  }
+
+  /** Gets the value of "border-top-left-radius" */
+  String get borderTopLeftRadius => getPropertyValue('border-top-left-radius');
+
+  /** Sets the value of "border-top-left-radius" */
+  set borderTopLeftRadius(String value) {
+    setProperty('border-top-left-radius', value, '');
+  }
+
+  /** Gets the value of "border-top-right-radius" */
+  String get borderTopRightRadius =>
+      getPropertyValue('border-top-right-radius');
+
+  /** Sets the value of "border-top-right-radius" */
+  set borderTopRightRadius(String value) {
+    setProperty('border-top-right-radius', value, '');
+  }
+
+  /** Gets the value of "border-top-style" */
+  String get borderTopStyle => getPropertyValue('border-top-style');
+
+  /** Sets the value of "border-top-style" */
+  set borderTopStyle(String value) {
+    setProperty('border-top-style', value, '');
+  }
+
+  /** Gets the value of "border-top-width" */
+  String get borderTopWidth => getPropertyValue('border-top-width');
+
+  /** Sets the value of "border-top-width" */
+  set borderTopWidth(String value) {
+    setProperty('border-top-width', value, '');
+  }
+
+  /** Gets the value of "border-vertical-spacing" */
+  String get borderVerticalSpacing =>
+      getPropertyValue('border-vertical-spacing');
+
+  /** Sets the value of "border-vertical-spacing" */
+  set borderVerticalSpacing(String value) {
+    setProperty('border-vertical-spacing', value, '');
+  }
+
+  /** Gets the value of "border-width" */
+  String get borderWidth => getPropertyValue('border-width');
+
+  /** Sets the value of "border-width" */
+  set borderWidth(String value) {
+    setProperty('border-width', value, '');
+  }
+
+  /** Gets the value of "bottom" */
+  String get bottom => getPropertyValue('bottom');
+
+  /** Sets the value of "bottom" */
+  set bottom(String value) {
+    setProperty('bottom', value, '');
+  }
+
+  /** Gets the value of "box-align" */
+  String get boxAlign => getPropertyValue('box-align');
+
+  /** Sets the value of "box-align" */
+  set boxAlign(String value) {
+    setProperty('box-align', value, '');
+  }
+
+  /** Gets the value of "box-decoration-break" */
+  String get boxDecorationBreak => getPropertyValue('box-decoration-break');
+
+  /** Sets the value of "box-decoration-break" */
+  set boxDecorationBreak(String value) {
+    setProperty('box-decoration-break', value, '');
+  }
+
+  /** Gets the value of "box-direction" */
+  String get boxDirection => getPropertyValue('box-direction');
+
+  /** Sets the value of "box-direction" */
+  set boxDirection(String value) {
+    setProperty('box-direction', value, '');
+  }
+
+  /** Gets the value of "box-flex" */
+  String get boxFlex => getPropertyValue('box-flex');
+
+  /** Sets the value of "box-flex" */
+  set boxFlex(String value) {
+    setProperty('box-flex', value, '');
+  }
+
+  /** Gets the value of "box-flex-group" */
+  String get boxFlexGroup => getPropertyValue('box-flex-group');
+
+  /** Sets the value of "box-flex-group" */
+  set boxFlexGroup(String value) {
+    setProperty('box-flex-group', value, '');
+  }
+
+  /** Gets the value of "box-lines" */
+  String get boxLines => getPropertyValue('box-lines');
+
+  /** Sets the value of "box-lines" */
+  set boxLines(String value) {
+    setProperty('box-lines', value, '');
+  }
+
+  /** Gets the value of "box-ordinal-group" */
+  String get boxOrdinalGroup => getPropertyValue('box-ordinal-group');
+
+  /** Sets the value of "box-ordinal-group" */
+  set boxOrdinalGroup(String value) {
+    setProperty('box-ordinal-group', value, '');
+  }
+
+  /** Gets the value of "box-orient" */
+  String get boxOrient => getPropertyValue('box-orient');
+
+  /** Sets the value of "box-orient" */
+  set boxOrient(String value) {
+    setProperty('box-orient', value, '');
+  }
+
+  /** Gets the value of "box-pack" */
+  String get boxPack => getPropertyValue('box-pack');
+
+  /** Sets the value of "box-pack" */
+  set boxPack(String value) {
+    setProperty('box-pack', value, '');
+  }
+
+  /** Gets the value of "box-reflect" */
+  String get boxReflect => getPropertyValue('box-reflect');
+
+  /** Sets the value of "box-reflect" */
+  set boxReflect(String value) {
+    setProperty('box-reflect', value, '');
+  }
+
+  /** Gets the value of "box-shadow" */
+  String get boxShadow => getPropertyValue('box-shadow');
+
+  /** Sets the value of "box-shadow" */
+  set boxShadow(String value) {
+    setProperty('box-shadow', value, '');
+  }
+
+  /** Gets the value of "box-sizing" */
+  String get boxSizing => getPropertyValue('box-sizing');
+
+  /** Sets the value of "box-sizing" */
+  set boxSizing(String value) {
+    setProperty('box-sizing', value, '');
+  }
+
+  /** Gets the value of "caption-side" */
+  String get captionSide => getPropertyValue('caption-side');
+
+  /** Sets the value of "caption-side" */
+  set captionSide(String value) {
+    setProperty('caption-side', value, '');
+  }
+
+  /** Gets the value of "clear" */
+  String get clear => getPropertyValue('clear');
+
+  /** Sets the value of "clear" */
+  set clear(String value) {
+    setProperty('clear', value, '');
+  }
+
+  /** Gets the value of "clip" */
+  String get clip => getPropertyValue('clip');
+
+  /** Sets the value of "clip" */
+  set clip(String value) {
+    setProperty('clip', value, '');
+  }
+
+  /** Gets the value of "clip-path" */
+  String get clipPath => getPropertyValue('clip-path');
+
+  /** Sets the value of "clip-path" */
+  set clipPath(String value) {
+    setProperty('clip-path', value, '');
+  }
+
+  /** Gets the value of "color" */
+  String get color => getPropertyValue('color');
+
+  /** Sets the value of "color" */
+  set color(String value) {
+    setProperty('color', value, '');
+  }
+
+  /** Gets the value of "column-break-after" */
+  String get columnBreakAfter => getPropertyValue('column-break-after');
+
+  /** Sets the value of "column-break-after" */
+  set columnBreakAfter(String value) {
+    setProperty('column-break-after', value, '');
+  }
+
+  /** Gets the value of "column-break-before" */
+  String get columnBreakBefore => getPropertyValue('column-break-before');
+
+  /** Sets the value of "column-break-before" */
+  set columnBreakBefore(String value) {
+    setProperty('column-break-before', value, '');
+  }
+
+  /** Gets the value of "column-break-inside" */
+  String get columnBreakInside => getPropertyValue('column-break-inside');
+
+  /** Sets the value of "column-break-inside" */
+  set columnBreakInside(String value) {
+    setProperty('column-break-inside', value, '');
+  }
+
+  /** Gets the value of "column-count" */
+  String get columnCount => getPropertyValue('column-count');
+
+  /** Sets the value of "column-count" */
+  set columnCount(String value) {
+    setProperty('column-count', value, '');
+  }
+
+  /** Gets the value of "column-fill" */
+  String get columnFill => getPropertyValue('column-fill');
+
+  /** Sets the value of "column-fill" */
+  set columnFill(String value) {
+    setProperty('column-fill', value, '');
+  }
+
+  /** Gets the value of "column-gap" */
+  String get columnGap => getPropertyValue('column-gap');
+
+  /** Sets the value of "column-gap" */
+  set columnGap(String value) {
+    setProperty('column-gap', value, '');
+  }
+
+  /** Gets the value of "column-rule" */
+  String get columnRule => getPropertyValue('column-rule');
+
+  /** Sets the value of "column-rule" */
+  set columnRule(String value) {
+    setProperty('column-rule', value, '');
+  }
+
+  /** Gets the value of "column-rule-color" */
+  String get columnRuleColor => getPropertyValue('column-rule-color');
+
+  /** Sets the value of "column-rule-color" */
+  set columnRuleColor(String value) {
+    setProperty('column-rule-color', value, '');
+  }
+
+  /** Gets the value of "column-rule-style" */
+  String get columnRuleStyle => getPropertyValue('column-rule-style');
+
+  /** Sets the value of "column-rule-style" */
+  set columnRuleStyle(String value) {
+    setProperty('column-rule-style', value, '');
+  }
+
+  /** Gets the value of "column-rule-width" */
+  String get columnRuleWidth => getPropertyValue('column-rule-width');
+
+  /** Sets the value of "column-rule-width" */
+  set columnRuleWidth(String value) {
+    setProperty('column-rule-width', value, '');
+  }
+
+  /** Gets the value of "column-span" */
+  String get columnSpan => getPropertyValue('column-span');
+
+  /** Sets the value of "column-span" */
+  set columnSpan(String value) {
+    setProperty('column-span', value, '');
+  }
+
+  /** Gets the value of "column-width" */
+  String get columnWidth => getPropertyValue('column-width');
+
+  /** Sets the value of "column-width" */
+  set columnWidth(String value) {
+    setProperty('column-width', value, '');
+  }
+
+  /** Gets the value of "columns" */
+  String get columns => getPropertyValue('columns');
+
+  /** Sets the value of "columns" */
+  set columns(String value) {
+    setProperty('columns', value, '');
+  }
+
+  /** Gets the value of "content" */
+  String get content => getPropertyValue('content');
+
+  /** Sets the value of "content" */
+  set content(String value) {
+    setProperty('content', value, '');
+  }
+
+  /** Gets the value of "counter-increment" */
+  String get counterIncrement => getPropertyValue('counter-increment');
+
+  /** Sets the value of "counter-increment" */
+  set counterIncrement(String value) {
+    setProperty('counter-increment', value, '');
+  }
+
+  /** Gets the value of "counter-reset" */
+  String get counterReset => getPropertyValue('counter-reset');
+
+  /** Sets the value of "counter-reset" */
+  set counterReset(String value) {
+    setProperty('counter-reset', value, '');
+  }
+
+  /** Gets the value of "cursor" */
+  String get cursor => getPropertyValue('cursor');
+
+  /** Sets the value of "cursor" */
+  set cursor(String value) {
+    setProperty('cursor', value, '');
+  }
+
+  /** Gets the value of "direction" */
+  String get direction => getPropertyValue('direction');
+
+  /** Sets the value of "direction" */
+  set direction(String value) {
+    setProperty('direction', value, '');
+  }
+
+  /** Gets the value of "display" */
+  String get display => getPropertyValue('display');
+
+  /** Sets the value of "display" */
+  set display(String value) {
+    setProperty('display', value, '');
+  }
+
+  /** Gets the value of "empty-cells" */
+  String get emptyCells => getPropertyValue('empty-cells');
+
+  /** Sets the value of "empty-cells" */
+  set emptyCells(String value) {
+    setProperty('empty-cells', value, '');
+  }
+
+  /** Gets the value of "filter" */
+  String get filter => getPropertyValue('filter');
+
+  /** Sets the value of "filter" */
+  set filter(String value) {
+    setProperty('filter', value, '');
+  }
+
+  /** Gets the value of "flex" */
+  String get flex => getPropertyValue('flex');
+
+  /** Sets the value of "flex" */
+  set flex(String value) {
+    setProperty('flex', value, '');
+  }
+
+  /** Gets the value of "flex-basis" */
+  String get flexBasis => getPropertyValue('flex-basis');
+
+  /** Sets the value of "flex-basis" */
+  set flexBasis(String value) {
+    setProperty('flex-basis', value, '');
+  }
+
+  /** Gets the value of "flex-direction" */
+  String get flexDirection => getPropertyValue('flex-direction');
+
+  /** Sets the value of "flex-direction" */
+  set flexDirection(String value) {
+    setProperty('flex-direction', value, '');
+  }
+
+  /** Gets the value of "flex-flow" */
+  String get flexFlow => getPropertyValue('flex-flow');
+
+  /** Sets the value of "flex-flow" */
+  set flexFlow(String value) {
+    setProperty('flex-flow', value, '');
+  }
+
+  /** Gets the value of "flex-grow" */
+  String get flexGrow => getPropertyValue('flex-grow');
+
+  /** Sets the value of "flex-grow" */
+  set flexGrow(String value) {
+    setProperty('flex-grow', value, '');
+  }
+
+  /** Gets the value of "flex-shrink" */
+  String get flexShrink => getPropertyValue('flex-shrink');
+
+  /** Sets the value of "flex-shrink" */
+  set flexShrink(String value) {
+    setProperty('flex-shrink', value, '');
+  }
+
+  /** Gets the value of "flex-wrap" */
+  String get flexWrap => getPropertyValue('flex-wrap');
+
+  /** Sets the value of "flex-wrap" */
+  set flexWrap(String value) {
+    setProperty('flex-wrap', value, '');
+  }
+
+  /** Gets the value of "float" */
+  String get float => getPropertyValue('float');
+
+  /** Sets the value of "float" */
+  set float(String value) {
+    setProperty('float', value, '');
+  }
+
+  /** Gets the value of "font" */
+  String get font => getPropertyValue('font');
+
+  /** Sets the value of "font" */
+  set font(String value) {
+    setProperty('font', value, '');
+  }
+
+  /** Gets the value of "font-family" */
+  String get fontFamily => getPropertyValue('font-family');
+
+  /** Sets the value of "font-family" */
+  set fontFamily(String value) {
+    setProperty('font-family', value, '');
+  }
+
+  /** Gets the value of "font-feature-settings" */
+  String get fontFeatureSettings => getPropertyValue('font-feature-settings');
+
+  /** Sets the value of "font-feature-settings" */
+  set fontFeatureSettings(String value) {
+    setProperty('font-feature-settings', value, '');
+  }
+
+  /** Gets the value of "font-kerning" */
+  String get fontKerning => getPropertyValue('font-kerning');
+
+  /** Sets the value of "font-kerning" */
+  set fontKerning(String value) {
+    setProperty('font-kerning', value, '');
+  }
+
+  /** Gets the value of "font-size" */
+  String get fontSize => getPropertyValue('font-size');
+
+  /** Sets the value of "font-size" */
+  set fontSize(String value) {
+    setProperty('font-size', value, '');
+  }
+
+  /** Gets the value of "font-size-delta" */
+  String get fontSizeDelta => getPropertyValue('font-size-delta');
+
+  /** Sets the value of "font-size-delta" */
+  set fontSizeDelta(String value) {
+    setProperty('font-size-delta', value, '');
+  }
+
+  /** Gets the value of "font-smoothing" */
+  String get fontSmoothing => getPropertyValue('font-smoothing');
+
+  /** Sets the value of "font-smoothing" */
+  set fontSmoothing(String value) {
+    setProperty('font-smoothing', value, '');
+  }
+
+  /** Gets the value of "font-stretch" */
+  String get fontStretch => getPropertyValue('font-stretch');
+
+  /** Sets the value of "font-stretch" */
+  set fontStretch(String value) {
+    setProperty('font-stretch', value, '');
+  }
+
+  /** Gets the value of "font-style" */
+  String get fontStyle => getPropertyValue('font-style');
+
+  /** Sets the value of "font-style" */
+  set fontStyle(String value) {
+    setProperty('font-style', value, '');
+  }
+
+  /** Gets the value of "font-variant" */
+  String get fontVariant => getPropertyValue('font-variant');
+
+  /** Sets the value of "font-variant" */
+  set fontVariant(String value) {
+    setProperty('font-variant', value, '');
+  }
+
+  /** Gets the value of "font-variant-ligatures" */
+  String get fontVariantLigatures => getPropertyValue('font-variant-ligatures');
+
+  /** Sets the value of "font-variant-ligatures" */
+  set fontVariantLigatures(String value) {
+    setProperty('font-variant-ligatures', value, '');
+  }
+
+  /** Gets the value of "font-weight" */
+  String get fontWeight => getPropertyValue('font-weight');
+
+  /** Sets the value of "font-weight" */
+  set fontWeight(String value) {
+    setProperty('font-weight', value, '');
+  }
+
+  /** Gets the value of "grid" */
+  String get grid => getPropertyValue('grid');
+
+  /** Sets the value of "grid" */
+  set grid(String value) {
+    setProperty('grid', value, '');
+  }
+
+  /** Gets the value of "grid-area" */
+  String get gridArea => getPropertyValue('grid-area');
+
+  /** Sets the value of "grid-area" */
+  set gridArea(String value) {
+    setProperty('grid-area', value, '');
+  }
+
+  /** Gets the value of "grid-auto-columns" */
+  String get gridAutoColumns => getPropertyValue('grid-auto-columns');
+
+  /** Sets the value of "grid-auto-columns" */
+  set gridAutoColumns(String value) {
+    setProperty('grid-auto-columns', value, '');
+  }
+
+  /** Gets the value of "grid-auto-flow" */
+  String get gridAutoFlow => getPropertyValue('grid-auto-flow');
+
+  /** Sets the value of "grid-auto-flow" */
+  set gridAutoFlow(String value) {
+    setProperty('grid-auto-flow', value, '');
+  }
+
+  /** Gets the value of "grid-auto-rows" */
+  String get gridAutoRows => getPropertyValue('grid-auto-rows');
+
+  /** Sets the value of "grid-auto-rows" */
+  set gridAutoRows(String value) {
+    setProperty('grid-auto-rows', value, '');
+  }
+
+  /** Gets the value of "grid-column" */
+  String get gridColumn => getPropertyValue('grid-column');
+
+  /** Sets the value of "grid-column" */
+  set gridColumn(String value) {
+    setProperty('grid-column', value, '');
+  }
+
+  /** Gets the value of "grid-column-end" */
+  String get gridColumnEnd => getPropertyValue('grid-column-end');
+
+  /** Sets the value of "grid-column-end" */
+  set gridColumnEnd(String value) {
+    setProperty('grid-column-end', value, '');
+  }
+
+  /** Gets the value of "grid-column-start" */
+  String get gridColumnStart => getPropertyValue('grid-column-start');
+
+  /** Sets the value of "grid-column-start" */
+  set gridColumnStart(String value) {
+    setProperty('grid-column-start', value, '');
+  }
+
+  /** Gets the value of "grid-row" */
+  String get gridRow => getPropertyValue('grid-row');
+
+  /** Sets the value of "grid-row" */
+  set gridRow(String value) {
+    setProperty('grid-row', value, '');
+  }
+
+  /** Gets the value of "grid-row-end" */
+  String get gridRowEnd => getPropertyValue('grid-row-end');
+
+  /** Sets the value of "grid-row-end" */
+  set gridRowEnd(String value) {
+    setProperty('grid-row-end', value, '');
+  }
+
+  /** Gets the value of "grid-row-start" */
+  String get gridRowStart => getPropertyValue('grid-row-start');
+
+  /** Sets the value of "grid-row-start" */
+  set gridRowStart(String value) {
+    setProperty('grid-row-start', value, '');
+  }
+
+  /** Gets the value of "grid-template" */
+  String get gridTemplate => getPropertyValue('grid-template');
+
+  /** Sets the value of "grid-template" */
+  set gridTemplate(String value) {
+    setProperty('grid-template', value, '');
+  }
+
+  /** Gets the value of "grid-template-areas" */
+  String get gridTemplateAreas => getPropertyValue('grid-template-areas');
+
+  /** Sets the value of "grid-template-areas" */
+  set gridTemplateAreas(String value) {
+    setProperty('grid-template-areas', value, '');
+  }
+
+  /** Gets the value of "grid-template-columns" */
+  String get gridTemplateColumns => getPropertyValue('grid-template-columns');
+
+  /** Sets the value of "grid-template-columns" */
+  set gridTemplateColumns(String value) {
+    setProperty('grid-template-columns', value, '');
+  }
+
+  /** Gets the value of "grid-template-rows" */
+  String get gridTemplateRows => getPropertyValue('grid-template-rows');
+
+  /** Sets the value of "grid-template-rows" */
+  set gridTemplateRows(String value) {
+    setProperty('grid-template-rows', value, '');
+  }
+
+  /** Gets the value of "height" */
+  String get height => getPropertyValue('height');
+
+  /** Sets the value of "height" */
+  set height(String value) {
+    setProperty('height', value, '');
+  }
+
+  /** Gets the value of "highlight" */
+  String get highlight => getPropertyValue('highlight');
+
+  /** Sets the value of "highlight" */
+  set highlight(String value) {
+    setProperty('highlight', value, '');
+  }
+
+  /** Gets the value of "hyphenate-character" */
+  String get hyphenateCharacter => getPropertyValue('hyphenate-character');
+
+  /** Sets the value of "hyphenate-character" */
+  set hyphenateCharacter(String value) {
+    setProperty('hyphenate-character', value, '');
+  }
+
+  /** Gets the value of "image-rendering" */
+  String get imageRendering => getPropertyValue('image-rendering');
+
+  /** Sets the value of "image-rendering" */
+  set imageRendering(String value) {
+    setProperty('image-rendering', value, '');
+  }
+
+  /** Gets the value of "isolation" */
+  String get isolation => getPropertyValue('isolation');
+
+  /** Sets the value of "isolation" */
+  set isolation(String value) {
+    setProperty('isolation', value, '');
+  }
+
+  /** Gets the value of "justify-content" */
+  String get justifyContent => getPropertyValue('justify-content');
+
+  /** Sets the value of "justify-content" */
+  set justifyContent(String value) {
+    setProperty('justify-content', value, '');
+  }
+
+  /** Gets the value of "justify-self" */
+  String get justifySelf => getPropertyValue('justify-self');
+
+  /** Sets the value of "justify-self" */
+  set justifySelf(String value) {
+    setProperty('justify-self', value, '');
+  }
+
+  /** Gets the value of "left" */
+  String get left => getPropertyValue('left');
+
+  /** Sets the value of "left" */
+  set left(String value) {
+    setProperty('left', value, '');
+  }
+
+  /** Gets the value of "letter-spacing" */
+  String get letterSpacing => getPropertyValue('letter-spacing');
+
+  /** Sets the value of "letter-spacing" */
+  set letterSpacing(String value) {
+    setProperty('letter-spacing', value, '');
+  }
+
+  /** Gets the value of "line-box-contain" */
+  String get lineBoxContain => getPropertyValue('line-box-contain');
+
+  /** Sets the value of "line-box-contain" */
+  set lineBoxContain(String value) {
+    setProperty('line-box-contain', value, '');
+  }
+
+  /** Gets the value of "line-break" */
+  String get lineBreak => getPropertyValue('line-break');
+
+  /** Sets the value of "line-break" */
+  set lineBreak(String value) {
+    setProperty('line-break', value, '');
+  }
+
+  /** Gets the value of "line-clamp" */
+  String get lineClamp => getPropertyValue('line-clamp');
+
+  /** Sets the value of "line-clamp" */
+  set lineClamp(String value) {
+    setProperty('line-clamp', value, '');
+  }
+
+  /** Gets the value of "line-height" */
+  String get lineHeight => getPropertyValue('line-height');
+
+  /** Sets the value of "line-height" */
+  set lineHeight(String value) {
+    setProperty('line-height', value, '');
+  }
+
+  /** Gets the value of "list-style" */
+  String get listStyle => getPropertyValue('list-style');
+
+  /** Sets the value of "list-style" */
+  set listStyle(String value) {
+    setProperty('list-style', value, '');
+  }
+
+  /** Gets the value of "list-style-image" */
+  String get listStyleImage => getPropertyValue('list-style-image');
+
+  /** Sets the value of "list-style-image" */
+  set listStyleImage(String value) {
+    setProperty('list-style-image', value, '');
+  }
+
+  /** Gets the value of "list-style-position" */
+  String get listStylePosition => getPropertyValue('list-style-position');
+
+  /** Sets the value of "list-style-position" */
+  set listStylePosition(String value) {
+    setProperty('list-style-position', value, '');
+  }
+
+  /** Gets the value of "list-style-type" */
+  String get listStyleType => getPropertyValue('list-style-type');
+
+  /** Sets the value of "list-style-type" */
+  set listStyleType(String value) {
+    setProperty('list-style-type', value, '');
+  }
+
+  /** Gets the value of "locale" */
+  String get locale => getPropertyValue('locale');
+
+  /** Sets the value of "locale" */
+  set locale(String value) {
+    setProperty('locale', value, '');
+  }
+
+  /** Gets the value of "logical-height" */
+  String get logicalHeight => getPropertyValue('logical-height');
+
+  /** Sets the value of "logical-height" */
+  set logicalHeight(String value) {
+    setProperty('logical-height', value, '');
+  }
+
+  /** Gets the value of "logical-width" */
+  String get logicalWidth => getPropertyValue('logical-width');
+
+  /** Sets the value of "logical-width" */
+  set logicalWidth(String value) {
+    setProperty('logical-width', value, '');
+  }
+
+  /** Gets the value of "margin" */
+  String get margin => getPropertyValue('margin');
+
+  /** Sets the value of "margin" */
+  set margin(String value) {
+    setProperty('margin', value, '');
+  }
+
+  /** Gets the value of "margin-after" */
+  String get marginAfter => getPropertyValue('margin-after');
+
+  /** Sets the value of "margin-after" */
+  set marginAfter(String value) {
+    setProperty('margin-after', value, '');
+  }
+
+  /** Gets the value of "margin-after-collapse" */
+  String get marginAfterCollapse => getPropertyValue('margin-after-collapse');
+
+  /** Sets the value of "margin-after-collapse" */
+  set marginAfterCollapse(String value) {
+    setProperty('margin-after-collapse', value, '');
+  }
+
+  /** Gets the value of "margin-before" */
+  String get marginBefore => getPropertyValue('margin-before');
+
+  /** Sets the value of "margin-before" */
+  set marginBefore(String value) {
+    setProperty('margin-before', value, '');
+  }
+
+  /** Gets the value of "margin-before-collapse" */
+  String get marginBeforeCollapse => getPropertyValue('margin-before-collapse');
+
+  /** Sets the value of "margin-before-collapse" */
+  set marginBeforeCollapse(String value) {
+    setProperty('margin-before-collapse', value, '');
+  }
+
+  /** Gets the value of "margin-bottom" */
+  String get marginBottom => getPropertyValue('margin-bottom');
+
+  /** Sets the value of "margin-bottom" */
+  set marginBottom(String value) {
+    setProperty('margin-bottom', value, '');
+  }
+
+  /** Gets the value of "margin-bottom-collapse" */
+  String get marginBottomCollapse => getPropertyValue('margin-bottom-collapse');
+
+  /** Sets the value of "margin-bottom-collapse" */
+  set marginBottomCollapse(String value) {
+    setProperty('margin-bottom-collapse', value, '');
+  }
+
+  /** Gets the value of "margin-collapse" */
+  String get marginCollapse => getPropertyValue('margin-collapse');
+
+  /** Sets the value of "margin-collapse" */
+  set marginCollapse(String value) {
+    setProperty('margin-collapse', value, '');
+  }
+
+  /** Gets the value of "margin-end" */
+  String get marginEnd => getPropertyValue('margin-end');
+
+  /** Sets the value of "margin-end" */
+  set marginEnd(String value) {
+    setProperty('margin-end', value, '');
+  }
+
+  /** Gets the value of "margin-left" */
+  String get marginLeft => getPropertyValue('margin-left');
+
+  /** Sets the value of "margin-left" */
+  set marginLeft(String value) {
+    setProperty('margin-left', value, '');
+  }
+
+  /** Gets the value of "margin-right" */
+  String get marginRight => getPropertyValue('margin-right');
+
+  /** Sets the value of "margin-right" */
+  set marginRight(String value) {
+    setProperty('margin-right', value, '');
+  }
+
+  /** Gets the value of "margin-start" */
+  String get marginStart => getPropertyValue('margin-start');
+
+  /** Sets the value of "margin-start" */
+  set marginStart(String value) {
+    setProperty('margin-start', value, '');
+  }
+
+  /** Gets the value of "margin-top" */
+  String get marginTop => getPropertyValue('margin-top');
+
+  /** Sets the value of "margin-top" */
+  set marginTop(String value) {
+    setProperty('margin-top', value, '');
+  }
+
+  /** Gets the value of "margin-top-collapse" */
+  String get marginTopCollapse => getPropertyValue('margin-top-collapse');
+
+  /** Sets the value of "margin-top-collapse" */
+  set marginTopCollapse(String value) {
+    setProperty('margin-top-collapse', value, '');
+  }
+
+  /** Gets the value of "mask" */
+  String get mask => getPropertyValue('mask');
+
+  /** Sets the value of "mask" */
+  set mask(String value) {
+    setProperty('mask', value, '');
+  }
+
+  /** Gets the value of "mask-box-image" */
+  String get maskBoxImage => getPropertyValue('mask-box-image');
+
+  /** Sets the value of "mask-box-image" */
+  set maskBoxImage(String value) {
+    setProperty('mask-box-image', value, '');
+  }
+
+  /** Gets the value of "mask-box-image-outset" */
+  String get maskBoxImageOutset => getPropertyValue('mask-box-image-outset');
+
+  /** Sets the value of "mask-box-image-outset" */
+  set maskBoxImageOutset(String value) {
+    setProperty('mask-box-image-outset', value, '');
+  }
+
+  /** Gets the value of "mask-box-image-repeat" */
+  String get maskBoxImageRepeat => getPropertyValue('mask-box-image-repeat');
+
+  /** Sets the value of "mask-box-image-repeat" */
+  set maskBoxImageRepeat(String value) {
+    setProperty('mask-box-image-repeat', value, '');
+  }
+
+  /** Gets the value of "mask-box-image-slice" */
+  String get maskBoxImageSlice => getPropertyValue('mask-box-image-slice');
+
+  /** Sets the value of "mask-box-image-slice" */
+  set maskBoxImageSlice(String value) {
+    setProperty('mask-box-image-slice', value, '');
+  }
+
+  /** Gets the value of "mask-box-image-source" */
+  String get maskBoxImageSource => getPropertyValue('mask-box-image-source');
+
+  /** Sets the value of "mask-box-image-source" */
+  set maskBoxImageSource(String value) {
+    setProperty('mask-box-image-source', value, '');
+  }
+
+  /** Gets the value of "mask-box-image-width" */
+  String get maskBoxImageWidth => getPropertyValue('mask-box-image-width');
+
+  /** Sets the value of "mask-box-image-width" */
+  set maskBoxImageWidth(String value) {
+    setProperty('mask-box-image-width', value, '');
+  }
+
+  /** Gets the value of "mask-clip" */
+  String get maskClip => getPropertyValue('mask-clip');
+
+  /** Sets the value of "mask-clip" */
+  set maskClip(String value) {
+    setProperty('mask-clip', value, '');
+  }
+
+  /** Gets the value of "mask-composite" */
+  String get maskComposite => getPropertyValue('mask-composite');
+
+  /** Sets the value of "mask-composite" */
+  set maskComposite(String value) {
+    setProperty('mask-composite', value, '');
+  }
+
+  /** Gets the value of "mask-image" */
+  String get maskImage => getPropertyValue('mask-image');
+
+  /** Sets the value of "mask-image" */
+  set maskImage(String value) {
+    setProperty('mask-image', value, '');
+  }
+
+  /** Gets the value of "mask-origin" */
+  String get maskOrigin => getPropertyValue('mask-origin');
+
+  /** Sets the value of "mask-origin" */
+  set maskOrigin(String value) {
+    setProperty('mask-origin', value, '');
+  }
+
+  /** Gets the value of "mask-position" */
+  String get maskPosition => getPropertyValue('mask-position');
+
+  /** Sets the value of "mask-position" */
+  set maskPosition(String value) {
+    setProperty('mask-position', value, '');
+  }
+
+  /** Gets the value of "mask-position-x" */
+  String get maskPositionX => getPropertyValue('mask-position-x');
+
+  /** Sets the value of "mask-position-x" */
+  set maskPositionX(String value) {
+    setProperty('mask-position-x', value, '');
+  }
+
+  /** Gets the value of "mask-position-y" */
+  String get maskPositionY => getPropertyValue('mask-position-y');
+
+  /** Sets the value of "mask-position-y" */
+  set maskPositionY(String value) {
+    setProperty('mask-position-y', value, '');
+  }
+
+  /** Gets the value of "mask-repeat" */
+  String get maskRepeat => getPropertyValue('mask-repeat');
+
+  /** Sets the value of "mask-repeat" */
+  set maskRepeat(String value) {
+    setProperty('mask-repeat', value, '');
+  }
+
+  /** Gets the value of "mask-repeat-x" */
+  String get maskRepeatX => getPropertyValue('mask-repeat-x');
+
+  /** Sets the value of "mask-repeat-x" */
+  set maskRepeatX(String value) {
+    setProperty('mask-repeat-x', value, '');
+  }
+
+  /** Gets the value of "mask-repeat-y" */
+  String get maskRepeatY => getPropertyValue('mask-repeat-y');
+
+  /** Sets the value of "mask-repeat-y" */
+  set maskRepeatY(String value) {
+    setProperty('mask-repeat-y', value, '');
+  }
+
+  /** Gets the value of "mask-size" */
+  String get maskSize => getPropertyValue('mask-size');
+
+  /** Sets the value of "mask-size" */
+  set maskSize(String value) {
+    setProperty('mask-size', value, '');
+  }
+
+  /** Gets the value of "mask-source-type" */
+  String get maskSourceType => getPropertyValue('mask-source-type');
+
+  /** Sets the value of "mask-source-type" */
+  set maskSourceType(String value) {
+    setProperty('mask-source-type', value, '');
+  }
+
+  /** Gets the value of "max-height" */
+  String get maxHeight => getPropertyValue('max-height');
+
+  /** Sets the value of "max-height" */
+  set maxHeight(String value) {
+    setProperty('max-height', value, '');
+  }
+
+  /** Gets the value of "max-logical-height" */
+  String get maxLogicalHeight => getPropertyValue('max-logical-height');
+
+  /** Sets the value of "max-logical-height" */
+  set maxLogicalHeight(String value) {
+    setProperty('max-logical-height', value, '');
+  }
+
+  /** Gets the value of "max-logical-width" */
+  String get maxLogicalWidth => getPropertyValue('max-logical-width');
+
+  /** Sets the value of "max-logical-width" */
+  set maxLogicalWidth(String value) {
+    setProperty('max-logical-width', value, '');
+  }
+
+  /** Gets the value of "max-width" */
+  String get maxWidth => getPropertyValue('max-width');
+
+  /** Sets the value of "max-width" */
+  set maxWidth(String value) {
+    setProperty('max-width', value, '');
+  }
+
+  /** Gets the value of "max-zoom" */
+  String get maxZoom => getPropertyValue('max-zoom');
+
+  /** Sets the value of "max-zoom" */
+  set maxZoom(String value) {
+    setProperty('max-zoom', value, '');
+  }
+
+  /** Gets the value of "min-height" */
+  String get minHeight => getPropertyValue('min-height');
+
+  /** Sets the value of "min-height" */
+  set minHeight(String value) {
+    setProperty('min-height', value, '');
+  }
+
+  /** Gets the value of "min-logical-height" */
+  String get minLogicalHeight => getPropertyValue('min-logical-height');
+
+  /** Sets the value of "min-logical-height" */
+  set minLogicalHeight(String value) {
+    setProperty('min-logical-height', value, '');
+  }
+
+  /** Gets the value of "min-logical-width" */
+  String get minLogicalWidth => getPropertyValue('min-logical-width');
+
+  /** Sets the value of "min-logical-width" */
+  set minLogicalWidth(String value) {
+    setProperty('min-logical-width', value, '');
+  }
+
+  /** Gets the value of "min-width" */
+  String get minWidth => getPropertyValue('min-width');
+
+  /** Sets the value of "min-width" */
+  set minWidth(String value) {
+    setProperty('min-width', value, '');
+  }
+
+  /** Gets the value of "min-zoom" */
+  String get minZoom => getPropertyValue('min-zoom');
+
+  /** Sets the value of "min-zoom" */
+  set minZoom(String value) {
+    setProperty('min-zoom', value, '');
+  }
+
+  /** Gets the value of "mix-blend-mode" */
+  String get mixBlendMode => getPropertyValue('mix-blend-mode');
+
+  /** Sets the value of "mix-blend-mode" */
+  set mixBlendMode(String value) {
+    setProperty('mix-blend-mode', value, '');
+  }
+
+  /** Gets the value of "object-fit" */
+  String get objectFit => getPropertyValue('object-fit');
+
+  /** Sets the value of "object-fit" */
+  set objectFit(String value) {
+    setProperty('object-fit', value, '');
+  }
+
+  /** Gets the value of "object-position" */
+  String get objectPosition => getPropertyValue('object-position');
+
+  /** Sets the value of "object-position" */
+  set objectPosition(String value) {
+    setProperty('object-position', value, '');
+  }
+
+  /** Gets the value of "opacity" */
+  String get opacity => getPropertyValue('opacity');
+
+  /** Sets the value of "opacity" */
+  set opacity(String value) {
+    setProperty('opacity', value, '');
+  }
+
+  /** Gets the value of "order" */
+  String get order => getPropertyValue('order');
+
+  /** Sets the value of "order" */
+  set order(String value) {
+    setProperty('order', value, '');
+  }
+
+  /** Gets the value of "orientation" */
+  String get orientation => getPropertyValue('orientation');
+
+  /** Sets the value of "orientation" */
+  set orientation(String value) {
+    setProperty('orientation', value, '');
+  }
+
+  /** Gets the value of "orphans" */
+  String get orphans => getPropertyValue('orphans');
+
+  /** Sets the value of "orphans" */
+  set orphans(String value) {
+    setProperty('orphans', value, '');
+  }
+
+  /** Gets the value of "outline" */
+  String get outline => getPropertyValue('outline');
+
+  /** Sets the value of "outline" */
+  set outline(String value) {
+    setProperty('outline', value, '');
+  }
+
+  /** Gets the value of "outline-color" */
+  String get outlineColor => getPropertyValue('outline-color');
+
+  /** Sets the value of "outline-color" */
+  set outlineColor(String value) {
+    setProperty('outline-color', value, '');
+  }
+
+  /** Gets the value of "outline-offset" */
+  String get outlineOffset => getPropertyValue('outline-offset');
+
+  /** Sets the value of "outline-offset" */
+  set outlineOffset(String value) {
+    setProperty('outline-offset', value, '');
+  }
+
+  /** Gets the value of "outline-style" */
+  String get outlineStyle => getPropertyValue('outline-style');
+
+  /** Sets the value of "outline-style" */
+  set outlineStyle(String value) {
+    setProperty('outline-style', value, '');
+  }
+
+  /** Gets the value of "outline-width" */
+  String get outlineWidth => getPropertyValue('outline-width');
+
+  /** Sets the value of "outline-width" */
+  set outlineWidth(String value) {
+    setProperty('outline-width', value, '');
+  }
+
+  /** Gets the value of "overflow" */
+  String get overflow => getPropertyValue('overflow');
+
+  /** Sets the value of "overflow" */
+  set overflow(String value) {
+    setProperty('overflow', value, '');
+  }
+
+  /** Gets the value of "overflow-wrap" */
+  String get overflowWrap => getPropertyValue('overflow-wrap');
+
+  /** Sets the value of "overflow-wrap" */
+  set overflowWrap(String value) {
+    setProperty('overflow-wrap', value, '');
+  }
+
+  /** Gets the value of "overflow-x" */
+  String get overflowX => getPropertyValue('overflow-x');
+
+  /** Sets the value of "overflow-x" */
+  set overflowX(String value) {
+    setProperty('overflow-x', value, '');
+  }
+
+  /** Gets the value of "overflow-y" */
+  String get overflowY => getPropertyValue('overflow-y');
+
+  /** Sets the value of "overflow-y" */
+  set overflowY(String value) {
+    setProperty('overflow-y', value, '');
+  }
+
+  /** Gets the value of "padding" */
+  String get padding => getPropertyValue('padding');
+
+  /** Sets the value of "padding" */
+  set padding(String value) {
+    setProperty('padding', value, '');
+  }
+
+  /** Gets the value of "padding-after" */
+  String get paddingAfter => getPropertyValue('padding-after');
+
+  /** Sets the value of "padding-after" */
+  set paddingAfter(String value) {
+    setProperty('padding-after', value, '');
+  }
+
+  /** Gets the value of "padding-before" */
+  String get paddingBefore => getPropertyValue('padding-before');
+
+  /** Sets the value of "padding-before" */
+  set paddingBefore(String value) {
+    setProperty('padding-before', value, '');
+  }
+
+  /** Gets the value of "padding-bottom" */
+  String get paddingBottom => getPropertyValue('padding-bottom');
+
+  /** Sets the value of "padding-bottom" */
+  set paddingBottom(String value) {
+    setProperty('padding-bottom', value, '');
+  }
+
+  /** Gets the value of "padding-end" */
+  String get paddingEnd => getPropertyValue('padding-end');
+
+  /** Sets the value of "padding-end" */
+  set paddingEnd(String value) {
+    setProperty('padding-end', value, '');
+  }
+
+  /** Gets the value of "padding-left" */
+  String get paddingLeft => getPropertyValue('padding-left');
+
+  /** Sets the value of "padding-left" */
+  set paddingLeft(String value) {
+    setProperty('padding-left', value, '');
+  }
+
+  /** Gets the value of "padding-right" */
+  String get paddingRight => getPropertyValue('padding-right');
+
+  /** Sets the value of "padding-right" */
+  set paddingRight(String value) {
+    setProperty('padding-right', value, '');
+  }
+
+  /** Gets the value of "padding-start" */
+  String get paddingStart => getPropertyValue('padding-start');
+
+  /** Sets the value of "padding-start" */
+  set paddingStart(String value) {
+    setProperty('padding-start', value, '');
+  }
+
+  /** Gets the value of "padding-top" */
+  String get paddingTop => getPropertyValue('padding-top');
+
+  /** Sets the value of "padding-top" */
+  set paddingTop(String value) {
+    setProperty('padding-top', value, '');
+  }
+
+  /** Gets the value of "page" */
+  String get page => getPropertyValue('page');
+
+  /** Sets the value of "page" */
+  set page(String value) {
+    setProperty('page', value, '');
+  }
+
+  /** Gets the value of "page-break-after" */
+  String get pageBreakAfter => getPropertyValue('page-break-after');
+
+  /** Sets the value of "page-break-after" */
+  set pageBreakAfter(String value) {
+    setProperty('page-break-after', value, '');
+  }
+
+  /** Gets the value of "page-break-before" */
+  String get pageBreakBefore => getPropertyValue('page-break-before');
+
+  /** Sets the value of "page-break-before" */
+  set pageBreakBefore(String value) {
+    setProperty('page-break-before', value, '');
+  }
+
+  /** Gets the value of "page-break-inside" */
+  String get pageBreakInside => getPropertyValue('page-break-inside');
+
+  /** Sets the value of "page-break-inside" */
+  set pageBreakInside(String value) {
+    setProperty('page-break-inside', value, '');
+  }
+
+  /** Gets the value of "perspective" */
+  String get perspective => getPropertyValue('perspective');
+
+  /** Sets the value of "perspective" */
+  set perspective(String value) {
+    setProperty('perspective', value, '');
+  }
+
+  /** Gets the value of "perspective-origin" */
+  String get perspectiveOrigin => getPropertyValue('perspective-origin');
+
+  /** Sets the value of "perspective-origin" */
+  set perspectiveOrigin(String value) {
+    setProperty('perspective-origin', value, '');
+  }
+
+  /** Gets the value of "perspective-origin-x" */
+  String get perspectiveOriginX => getPropertyValue('perspective-origin-x');
+
+  /** Sets the value of "perspective-origin-x" */
+  set perspectiveOriginX(String value) {
+    setProperty('perspective-origin-x', value, '');
+  }
+
+  /** Gets the value of "perspective-origin-y" */
+  String get perspectiveOriginY => getPropertyValue('perspective-origin-y');
+
+  /** Sets the value of "perspective-origin-y" */
+  set perspectiveOriginY(String value) {
+    setProperty('perspective-origin-y', value, '');
+  }
+
+  /** Gets the value of "pointer-events" */
+  String get pointerEvents => getPropertyValue('pointer-events');
+
+  /** Sets the value of "pointer-events" */
+  set pointerEvents(String value) {
+    setProperty('pointer-events', value, '');
+  }
+
+  /** Gets the value of "position" */
+  String get position => getPropertyValue('position');
+
+  /** Sets the value of "position" */
+  set position(String value) {
+    setProperty('position', value, '');
+  }
+
+  /** Gets the value of "print-color-adjust" */
+  String get printColorAdjust => getPropertyValue('print-color-adjust');
+
+  /** Sets the value of "print-color-adjust" */
+  set printColorAdjust(String value) {
+    setProperty('print-color-adjust', value, '');
+  }
+
+  /** Gets the value of "quotes" */
+  String get quotes => getPropertyValue('quotes');
+
+  /** Sets the value of "quotes" */
+  set quotes(String value) {
+    setProperty('quotes', value, '');
+  }
+
+  /** Gets the value of "resize" */
+  String get resize => getPropertyValue('resize');
+
+  /** Sets the value of "resize" */
+  set resize(String value) {
+    setProperty('resize', value, '');
+  }
+
+  /** Gets the value of "right" */
+  String get right => getPropertyValue('right');
+
+  /** Sets the value of "right" */
+  set right(String value) {
+    setProperty('right', value, '');
+  }
+
+  /** Gets the value of "rtl-ordering" */
+  String get rtlOrdering => getPropertyValue('rtl-ordering');
+
+  /** Sets the value of "rtl-ordering" */
+  set rtlOrdering(String value) {
+    setProperty('rtl-ordering', value, '');
+  }
+
+  /** Gets the value of "ruby-position" */
+  String get rubyPosition => getPropertyValue('ruby-position');
+
+  /** Sets the value of "ruby-position" */
+  set rubyPosition(String value) {
+    setProperty('ruby-position', value, '');
+  }
+
+  /** Gets the value of "scroll-behavior" */
+  String get scrollBehavior => getPropertyValue('scroll-behavior');
+
+  /** Sets the value of "scroll-behavior" */
+  set scrollBehavior(String value) {
+    setProperty('scroll-behavior', value, '');
+  }
+
+  /** Gets the value of "shape-image-threshold" */
+  String get shapeImageThreshold => getPropertyValue('shape-image-threshold');
+
+  /** Sets the value of "shape-image-threshold" */
+  set shapeImageThreshold(String value) {
+    setProperty('shape-image-threshold', value, '');
+  }
+
+  /** Gets the value of "shape-margin" */
+  String get shapeMargin => getPropertyValue('shape-margin');
+
+  /** Sets the value of "shape-margin" */
+  set shapeMargin(String value) {
+    setProperty('shape-margin', value, '');
+  }
+
+  /** Gets the value of "shape-outside" */
+  String get shapeOutside => getPropertyValue('shape-outside');
+
+  /** Sets the value of "shape-outside" */
+  set shapeOutside(String value) {
+    setProperty('shape-outside', value, '');
+  }
+
+  /** Gets the value of "size" */
+  String get size => getPropertyValue('size');
+
+  /** Sets the value of "size" */
+  set size(String value) {
+    setProperty('size', value, '');
+  }
+
+  /** Gets the value of "speak" */
+  String get speak => getPropertyValue('speak');
+
+  /** Sets the value of "speak" */
+  set speak(String value) {
+    setProperty('speak', value, '');
+  }
+
+  /** Gets the value of "src" */
+  String get src => getPropertyValue('src');
+
+  /** Sets the value of "src" */
+  set src(String value) {
+    setProperty('src', value, '');
+  }
+
+  /** Gets the value of "tab-size" */
+  String get tabSize => getPropertyValue('tab-size');
+
+  /** Sets the value of "tab-size" */
+  set tabSize(String value) {
+    setProperty('tab-size', value, '');
+  }
+
+  /** Gets the value of "table-layout" */
+  String get tableLayout => getPropertyValue('table-layout');
+
+  /** Sets the value of "table-layout" */
+  set tableLayout(String value) {
+    setProperty('table-layout', value, '');
+  }
+
+  /** Gets the value of "tap-highlight-color" */
+  String get tapHighlightColor => getPropertyValue('tap-highlight-color');
+
+  /** Sets the value of "tap-highlight-color" */
+  set tapHighlightColor(String value) {
+    setProperty('tap-highlight-color', value, '');
+  }
+
+  /** Gets the value of "text-align" */
+  String get textAlign => getPropertyValue('text-align');
+
+  /** Sets the value of "text-align" */
+  set textAlign(String value) {
+    setProperty('text-align', value, '');
+  }
+
+  /** Gets the value of "text-align-last" */
+  String get textAlignLast => getPropertyValue('text-align-last');
+
+  /** Sets the value of "text-align-last" */
+  set textAlignLast(String value) {
+    setProperty('text-align-last', value, '');
+  }
+
+  /** Gets the value of "text-combine" */
+  String get textCombine => getPropertyValue('text-combine');
+
+  /** Sets the value of "text-combine" */
+  set textCombine(String value) {
+    setProperty('text-combine', value, '');
+  }
+
+  /** Gets the value of "text-decoration" */
+  String get textDecoration => getPropertyValue('text-decoration');
+
+  /** Sets the value of "text-decoration" */
+  set textDecoration(String value) {
+    setProperty('text-decoration', value, '');
+  }
+
+  /** Gets the value of "text-decoration-color" */
+  String get textDecorationColor => getPropertyValue('text-decoration-color');
+
+  /** Sets the value of "text-decoration-color" */
+  set textDecorationColor(String value) {
+    setProperty('text-decoration-color', value, '');
+  }
+
+  /** Gets the value of "text-decoration-line" */
+  String get textDecorationLine => getPropertyValue('text-decoration-line');
+
+  /** Sets the value of "text-decoration-line" */
+  set textDecorationLine(String value) {
+    setProperty('text-decoration-line', value, '');
+  }
+
+  /** Gets the value of "text-decoration-style" */
+  String get textDecorationStyle => getPropertyValue('text-decoration-style');
+
+  /** Sets the value of "text-decoration-style" */
+  set textDecorationStyle(String value) {
+    setProperty('text-decoration-style', value, '');
+  }
+
+  /** Gets the value of "text-decorations-in-effect" */
+  String get textDecorationsInEffect =>
+      getPropertyValue('text-decorations-in-effect');
+
+  /** Sets the value of "text-decorations-in-effect" */
+  set textDecorationsInEffect(String value) {
+    setProperty('text-decorations-in-effect', value, '');
+  }
+
+  /** Gets the value of "text-emphasis" */
+  String get textEmphasis => getPropertyValue('text-emphasis');
+
+  /** Sets the value of "text-emphasis" */
+  set textEmphasis(String value) {
+    setProperty('text-emphasis', value, '');
+  }
+
+  /** Gets the value of "text-emphasis-color" */
+  String get textEmphasisColor => getPropertyValue('text-emphasis-color');
+
+  /** Sets the value of "text-emphasis-color" */
+  set textEmphasisColor(String value) {
+    setProperty('text-emphasis-color', value, '');
+  }
+
+  /** Gets the value of "text-emphasis-position" */
+  String get textEmphasisPosition => getPropertyValue('text-emphasis-position');
+
+  /** Sets the value of "text-emphasis-position" */
+  set textEmphasisPosition(String value) {
+    setProperty('text-emphasis-position', value, '');
+  }
+
+  /** Gets the value of "text-emphasis-style" */
+  String get textEmphasisStyle => getPropertyValue('text-emphasis-style');
+
+  /** Sets the value of "text-emphasis-style" */
+  set textEmphasisStyle(String value) {
+    setProperty('text-emphasis-style', value, '');
+  }
+
+  /** Gets the value of "text-fill-color" */
+  String get textFillColor => getPropertyValue('text-fill-color');
+
+  /** Sets the value of "text-fill-color" */
+  set textFillColor(String value) {
+    setProperty('text-fill-color', value, '');
+  }
+
+  /** Gets the value of "text-indent" */
+  String get textIndent => getPropertyValue('text-indent');
+
+  /** Sets the value of "text-indent" */
+  set textIndent(String value) {
+    setProperty('text-indent', value, '');
+  }
+
+  /** Gets the value of "text-justify" */
+  String get textJustify => getPropertyValue('text-justify');
+
+  /** Sets the value of "text-justify" */
+  set textJustify(String value) {
+    setProperty('text-justify', value, '');
+  }
+
+  /** Gets the value of "text-line-through-color" */
+  String get textLineThroughColor =>
+      getPropertyValue('text-line-through-color');
+
+  /** Sets the value of "text-line-through-color" */
+  set textLineThroughColor(String value) {
+    setProperty('text-line-through-color', value, '');
+  }
+
+  /** Gets the value of "text-line-through-mode" */
+  String get textLineThroughMode => getPropertyValue('text-line-through-mode');
+
+  /** Sets the value of "text-line-through-mode" */
+  set textLineThroughMode(String value) {
+    setProperty('text-line-through-mode', value, '');
+  }
+
+  /** Gets the value of "text-line-through-style" */
+  String get textLineThroughStyle =>
+      getPropertyValue('text-line-through-style');
+
+  /** Sets the value of "text-line-through-style" */
+  set textLineThroughStyle(String value) {
+    setProperty('text-line-through-style', value, '');
+  }
+
+  /** Gets the value of "text-line-through-width" */
+  String get textLineThroughWidth =>
+      getPropertyValue('text-line-through-width');
+
+  /** Sets the value of "text-line-through-width" */
+  set textLineThroughWidth(String value) {
+    setProperty('text-line-through-width', value, '');
+  }
+
+  /** Gets the value of "text-orientation" */
+  String get textOrientation => getPropertyValue('text-orientation');
+
+  /** Sets the value of "text-orientation" */
+  set textOrientation(String value) {
+    setProperty('text-orientation', value, '');
+  }
+
+  /** Gets the value of "text-overflow" */
+  String get textOverflow => getPropertyValue('text-overflow');
+
+  /** Sets the value of "text-overflow" */
+  set textOverflow(String value) {
+    setProperty('text-overflow', value, '');
+  }
+
+  /** Gets the value of "text-overline-color" */
+  String get textOverlineColor => getPropertyValue('text-overline-color');
+
+  /** Sets the value of "text-overline-color" */
+  set textOverlineColor(String value) {
+    setProperty('text-overline-color', value, '');
+  }
+
+  /** Gets the value of "text-overline-mode" */
+  String get textOverlineMode => getPropertyValue('text-overline-mode');
+
+  /** Sets the value of "text-overline-mode" */
+  set textOverlineMode(String value) {
+    setProperty('text-overline-mode', value, '');
+  }
+
+  /** Gets the value of "text-overline-style" */
+  String get textOverlineStyle => getPropertyValue('text-overline-style');
+
+  /** Sets the value of "text-overline-style" */
+  set textOverlineStyle(String value) {
+    setProperty('text-overline-style', value, '');
+  }
+
+  /** Gets the value of "text-overline-width" */
+  String get textOverlineWidth => getPropertyValue('text-overline-width');
+
+  /** Sets the value of "text-overline-width" */
+  set textOverlineWidth(String value) {
+    setProperty('text-overline-width', value, '');
+  }
+
+  /** Gets the value of "text-rendering" */
+  String get textRendering => getPropertyValue('text-rendering');
+
+  /** Sets the value of "text-rendering" */
+  set textRendering(String value) {
+    setProperty('text-rendering', value, '');
+  }
+
+  /** Gets the value of "text-security" */
+  String get textSecurity => getPropertyValue('text-security');
+
+  /** Sets the value of "text-security" */
+  set textSecurity(String value) {
+    setProperty('text-security', value, '');
+  }
+
+  /** Gets the value of "text-shadow" */
+  String get textShadow => getPropertyValue('text-shadow');
+
+  /** Sets the value of "text-shadow" */
+  set textShadow(String value) {
+    setProperty('text-shadow', value, '');
+  }
+
+  /** Gets the value of "text-stroke" */
+  String get textStroke => getPropertyValue('text-stroke');
+
+  /** Sets the value of "text-stroke" */
+  set textStroke(String value) {
+    setProperty('text-stroke', value, '');
+  }
+
+  /** Gets the value of "text-stroke-color" */
+  String get textStrokeColor => getPropertyValue('text-stroke-color');
+
+  /** Sets the value of "text-stroke-color" */
+  set textStrokeColor(String value) {
+    setProperty('text-stroke-color', value, '');
+  }
+
+  /** Gets the value of "text-stroke-width" */
+  String get textStrokeWidth => getPropertyValue('text-stroke-width');
+
+  /** Sets the value of "text-stroke-width" */
+  set textStrokeWidth(String value) {
+    setProperty('text-stroke-width', value, '');
+  }
+
+  /** Gets the value of "text-transform" */
+  String get textTransform => getPropertyValue('text-transform');
+
+  /** Sets the value of "text-transform" */
+  set textTransform(String value) {
+    setProperty('text-transform', value, '');
+  }
+
+  /** Gets the value of "text-underline-color" */
+  String get textUnderlineColor => getPropertyValue('text-underline-color');
+
+  /** Sets the value of "text-underline-color" */
+  set textUnderlineColor(String value) {
+    setProperty('text-underline-color', value, '');
+  }
+
+  /** Gets the value of "text-underline-mode" */
+  String get textUnderlineMode => getPropertyValue('text-underline-mode');
+
+  /** Sets the value of "text-underline-mode" */
+  set textUnderlineMode(String value) {
+    setProperty('text-underline-mode', value, '');
+  }
+
+  /** Gets the value of "text-underline-position" */
+  String get textUnderlinePosition =>
+      getPropertyValue('text-underline-position');
+
+  /** Sets the value of "text-underline-position" */
+  set textUnderlinePosition(String value) {
+    setProperty('text-underline-position', value, '');
+  }
+
+  /** Gets the value of "text-underline-style" */
+  String get textUnderlineStyle => getPropertyValue('text-underline-style');
+
+  /** Sets the value of "text-underline-style" */
+  set textUnderlineStyle(String value) {
+    setProperty('text-underline-style', value, '');
+  }
+
+  /** Gets the value of "text-underline-width" */
+  String get textUnderlineWidth => getPropertyValue('text-underline-width');
+
+  /** Sets the value of "text-underline-width" */
+  set textUnderlineWidth(String value) {
+    setProperty('text-underline-width', value, '');
+  }
+
+  /** Gets the value of "top" */
+  String get top => getPropertyValue('top');
+
+  /** Sets the value of "top" */
+  set top(String value) {
+    setProperty('top', value, '');
+  }
+
+  /** Gets the value of "touch-action" */
+  String get touchAction => getPropertyValue('touch-action');
+
+  /** Sets the value of "touch-action" */
+  set touchAction(String value) {
+    setProperty('touch-action', value, '');
+  }
+
+  /** Gets the value of "touch-action-delay" */
+  String get touchActionDelay => getPropertyValue('touch-action-delay');
+
+  /** Sets the value of "touch-action-delay" */
+  set touchActionDelay(String value) {
+    setProperty('touch-action-delay', value, '');
+  }
+
+  /** Gets the value of "transform" */
+  String get transform => getPropertyValue('transform');
+
+  /** Sets the value of "transform" */
+  set transform(String value) {
+    setProperty('transform', value, '');
+  }
+
+  /** Gets the value of "transform-origin" */
+  String get transformOrigin => getPropertyValue('transform-origin');
+
+  /** Sets the value of "transform-origin" */
+  set transformOrigin(String value) {
+    setProperty('transform-origin', value, '');
+  }
+
+  /** Gets the value of "transform-origin-x" */
+  String get transformOriginX => getPropertyValue('transform-origin-x');
+
+  /** Sets the value of "transform-origin-x" */
+  set transformOriginX(String value) {
+    setProperty('transform-origin-x', value, '');
+  }
+
+  /** Gets the value of "transform-origin-y" */
+  String get transformOriginY => getPropertyValue('transform-origin-y');
+
+  /** Sets the value of "transform-origin-y" */
+  set transformOriginY(String value) {
+    setProperty('transform-origin-y', value, '');
+  }
+
+  /** Gets the value of "transform-origin-z" */
+  String get transformOriginZ => getPropertyValue('transform-origin-z');
+
+  /** Sets the value of "transform-origin-z" */
+  set transformOriginZ(String value) {
+    setProperty('transform-origin-z', value, '');
+  }
+
+  /** Gets the value of "transform-style" */
+  String get transformStyle => getPropertyValue('transform-style');
+
+  /** Sets the value of "transform-style" */
+  set transformStyle(String value) {
+    setProperty('transform-style', value, '');
+  }
+
+  /** Gets the value of "transition" */ @SupportedBrowser(
+      SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  String get transition => getPropertyValue('transition');
+
+  /** Sets the value of "transition" */ @SupportedBrowser(
+      SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  set transition(String value) {
+    setProperty('transition', value, '');
+  }
+
+  /** Gets the value of "transition-delay" */
+  String get transitionDelay => getPropertyValue('transition-delay');
+
+  /** Sets the value of "transition-delay" */
+  set transitionDelay(String value) {
+    setProperty('transition-delay', value, '');
+  }
+
+  /** Gets the value of "transition-duration" */
+  String get transitionDuration => getPropertyValue('transition-duration');
+
+  /** Sets the value of "transition-duration" */
+  set transitionDuration(String value) {
+    setProperty('transition-duration', value, '');
+  }
+
+  /** Gets the value of "transition-property" */
+  String get transitionProperty => getPropertyValue('transition-property');
+
+  /** Sets the value of "transition-property" */
+  set transitionProperty(String value) {
+    setProperty('transition-property', value, '');
+  }
+
+  /** Gets the value of "transition-timing-function" */
+  String get transitionTimingFunction =>
+      getPropertyValue('transition-timing-function');
+
+  /** Sets the value of "transition-timing-function" */
+  set transitionTimingFunction(String value) {
+    setProperty('transition-timing-function', value, '');
+  }
+
+  /** Gets the value of "unicode-bidi" */
+  String get unicodeBidi => getPropertyValue('unicode-bidi');
+
+  /** Sets the value of "unicode-bidi" */
+  set unicodeBidi(String value) {
+    setProperty('unicode-bidi', value, '');
+  }
+
+  /** Gets the value of "unicode-range" */
+  String get unicodeRange => getPropertyValue('unicode-range');
+
+  /** Sets the value of "unicode-range" */
+  set unicodeRange(String value) {
+    setProperty('unicode-range', value, '');
+  }
+
+  /** Gets the value of "user-drag" */
+  String get userDrag => getPropertyValue('user-drag');
+
+  /** Sets the value of "user-drag" */
+  set userDrag(String value) {
+    setProperty('user-drag', value, '');
+  }
+
+  /** Gets the value of "user-modify" */
+  String get userModify => getPropertyValue('user-modify');
+
+  /** Sets the value of "user-modify" */
+  set userModify(String value) {
+    setProperty('user-modify', value, '');
+  }
+
+  /** Gets the value of "user-select" */
+  String get userSelect => getPropertyValue('user-select');
+
+  /** Sets the value of "user-select" */
+  set userSelect(String value) {
+    setProperty('user-select', value, '');
+  }
+
+  /** Gets the value of "user-zoom" */
+  String get userZoom => getPropertyValue('user-zoom');
+
+  /** Sets the value of "user-zoom" */
+  set userZoom(String value) {
+    setProperty('user-zoom', value, '');
+  }
+
+  /** Gets the value of "vertical-align" */
+  String get verticalAlign => getPropertyValue('vertical-align');
+
+  /** Sets the value of "vertical-align" */
+  set verticalAlign(String value) {
+    setProperty('vertical-align', value, '');
+  }
+
+  /** Gets the value of "visibility" */
+  String get visibility => getPropertyValue('visibility');
+
+  /** Sets the value of "visibility" */
+  set visibility(String value) {
+    setProperty('visibility', value, '');
+  }
+
+  /** Gets the value of "white-space" */
+  String get whiteSpace => getPropertyValue('white-space');
+
+  /** Sets the value of "white-space" */
+  set whiteSpace(String value) {
+    setProperty('white-space', value, '');
+  }
+
+  /** Gets the value of "widows" */
+  String get widows => getPropertyValue('widows');
+
+  /** Sets the value of "widows" */
+  set widows(String value) {
+    setProperty('widows', value, '');
+  }
+
+  /** Gets the value of "width" */
+  String get width => getPropertyValue('width');
+
+  /** Sets the value of "width" */
+  set width(String value) {
+    setProperty('width', value, '');
+  }
+
+  /** Gets the value of "will-change" */
+  String get willChange => getPropertyValue('will-change');
+
+  /** Sets the value of "will-change" */
+  set willChange(String value) {
+    setProperty('will-change', value, '');
+  }
+
+  /** Gets the value of "word-break" */
+  String get wordBreak => getPropertyValue('word-break');
+
+  /** Sets the value of "word-break" */
+  set wordBreak(String value) {
+    setProperty('word-break', value, '');
+  }
+
+  /** Gets the value of "word-spacing" */
+  String get wordSpacing => getPropertyValue('word-spacing');
+
+  /** Sets the value of "word-spacing" */
+  set wordSpacing(String value) {
+    setProperty('word-spacing', value, '');
+  }
+
+  /** Gets the value of "word-wrap" */
+  String get wordWrap => getPropertyValue('word-wrap');
+
+  /** Sets the value of "word-wrap" */
+  set wordWrap(String value) {
+    setProperty('word-wrap', value, '');
+  }
+
+  /** Gets the value of "wrap-flow" */
+  String get wrapFlow => getPropertyValue('wrap-flow');
+
+  /** Sets the value of "wrap-flow" */
+  set wrapFlow(String value) {
+    setProperty('wrap-flow', value, '');
+  }
+
+  /** Gets the value of "wrap-through" */
+  String get wrapThrough => getPropertyValue('wrap-through');
+
+  /** Sets the value of "wrap-through" */
+  set wrapThrough(String value) {
+    setProperty('wrap-through', value, '');
+  }
+
+  /** Gets the value of "writing-mode" */
+  String get writingMode => getPropertyValue('writing-mode');
+
+  /** Sets the value of "writing-mode" */
+  set writingMode(String value) {
+    setProperty('writing-mode', value, '');
+  }
+
+  /** Gets the value of "z-index" */
+  String get zIndex => getPropertyValue('z-index');
+
+  /** Sets the value of "z-index" */
+  set zIndex(String value) {
+    setProperty('z-index', value, '');
+  }
+
+  /** Gets the value of "zoom" */
+  String get zoom => getPropertyValue('zoom');
+
+  /** Sets the value of "zoom" */
+  set zoom(String value) {
+    setProperty('zoom', value, '');
+  }
+}
+// Copyright (c) 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.
+
+@Native("CSSStyleRule")
+class CssStyleRule extends CssRule {
+  // To suppress missing implicit constructor warnings.
+  factory CssStyleRule._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  String selectorText;
+
+  final CssStyleDeclaration style;
+}
+// Copyright (c) 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.
+
+@Native("CSSStyleSheet")
+class CssStyleSheet extends StyleSheet {
+  // To suppress missing implicit constructor warnings.
+  factory CssStyleSheet._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @Returns('_CssRuleList|Null')
+  @Creates('_CssRuleList')
+  final List<CssRule> cssRules;
+
+  final CssRule ownerRule;
+
+  @Returns('_CssRuleList|Null')
+  @Creates('_CssRuleList')
+  final List<CssRule> rules;
+
+  int addRule(String selector, String style, [int index]) native;
+
+  void deleteRule(int index) native;
+
+  int insertRule(String rule, [int index]) native;
+
+  void removeRule(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("CSSStyleValue")
+class CssStyleValue extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CssStyleValue._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static Object parse(String property, String cssText) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("CSSSupportsRule")
+class CssSupportsRule extends CssConditionRule {
+  // To suppress missing implicit constructor warnings.
+  factory CssSupportsRule._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("CSSTransformComponent")
+class CssTransformComponent extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CssTransformComponent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  bool is2D;
+}
+// Copyright (c) 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.
+
+@Native("CSSTransformValue")
+class CssTransformValue extends CssStyleValue {
+  // To suppress missing implicit constructor warnings.
+  factory CssTransformValue._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory CssTransformValue([List<CssTransformComponent> transformComponents]) {
+    if (transformComponents == null) {
+      return CssTransformValue._create_1();
+    }
+    if ((transformComponents is List<CssTransformComponent>)) {
+      return CssTransformValue._create_2(transformComponents);
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+  static CssTransformValue _create_1() =>
+      JS('CssTransformValue', 'new CSSTransformValue()');
+  static CssTransformValue _create_2(transformComponents) =>
+      JS('CssTransformValue', 'new CSSTransformValue(#)', transformComponents);
+
+  final bool is2D;
+
+  final int length;
+
+  CssTransformComponent componentAtIndex(int index) native;
+
+  DomMatrix toMatrix() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("CSSTranslation")
+class CssTranslation extends CssTransformComponent {
+  // To suppress missing implicit constructor warnings.
+  factory CssTranslation._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory CssTranslation(CssNumericValue x, CssNumericValue y,
+      [CssNumericValue z]) {
+    if ((y is CssNumericValue) && (x is CssNumericValue) && z == null) {
+      return CssTranslation._create_1(x, y);
+    }
+    if ((z is CssNumericValue) &&
+        (y is CssNumericValue) &&
+        (x is CssNumericValue)) {
+      return CssTranslation._create_2(x, y, z);
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+  static CssTranslation _create_1(x, y) =>
+      JS('CssTranslation', 'new CSSTranslation(#,#)', x, y);
+  static CssTranslation _create_2(x, y, z) =>
+      JS('CssTranslation', 'new CSSTranslation(#,#,#)', x, y, z);
+
+  CssNumericValue x;
+
+  CssNumericValue y;
+
+  CssNumericValue z;
+}
+// Copyright (c) 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.
+
+@Native("CSSUnitValue")
+class CssUnitValue extends CssNumericValue {
+  // To suppress missing implicit constructor warnings.
+  factory CssUnitValue._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory CssUnitValue(num value, String unit) {
+    return CssUnitValue._create_1(value, unit);
+  }
+  static CssUnitValue _create_1(value, unit) =>
+      JS('CssUnitValue', 'new CSSUnitValue(#,#)', value, unit);
+
+  final String type;
+
+  String unit;
+
+  num value;
+}
+// Copyright (c) 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.
+
+@Native("CSSUnparsedValue")
+class CssUnparsedValue extends CssStyleValue {
+  // To suppress missing implicit constructor warnings.
+  factory CssUnparsedValue._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int length;
+
+  Object fragmentAtIndex(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("CSSVariableReferenceValue")
+class CssVariableReferenceValue extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CssVariableReferenceValue._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final CssUnparsedValue fallback;
+
+  final String variable;
+}
+// Copyright (c) 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.
+
+@Native("CSSViewportRule")
+class CssViewportRule extends CssRule {
+  // To suppress missing implicit constructor warnings.
+  factory CssViewportRule._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final CssStyleDeclaration style;
+}
+// Copyright (c) 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.
+
+@Native("CSSURLImageValue")
+class CssurlImageValue extends CssImageValue {
+  // To suppress missing implicit constructor warnings.
+  factory CssurlImageValue._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory CssurlImageValue(String url) {
+    return CssurlImageValue._create_1(url);
+  }
+  static CssurlImageValue _create_1(url) =>
+      JS('CssurlImageValue', 'new CSSURLImageValue(#)', url);
+
+  final String url;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-custom-element-constructor-generation
+@deprecated // experimental
+typedef void CustomElementConstructor();
+// Copyright (c) 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.
+
+@Native("CustomElementRegistry")
+class CustomElementRegistry extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CustomElementRegistry._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  void define(String name, Object constructor, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      _define_1(name, constructor, options_1);
+      return;
+    }
+    _define_2(name, constructor);
+    return;
+  }
+
+  @JSName('define')
+  void _define_1(name, constructor, options) native;
+  @JSName('define')
+  void _define_2(name, constructor) native;
+
+  Object get(String name) native;
+
+  Future whenDefined(String name) =>
+      promiseToFuture(JS("", "#.whenDefined(#)", this, name));
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@Native("CustomEvent")
+class CustomEvent extends Event {
+  @Creates('Null') // Set from Dart code; does not instantiate a native type.
+  var _dartDetail;
+
+  factory CustomEvent(String type,
+      {bool canBubble: true, bool cancelable: true, Object detail}) {
+    final CustomEvent e = document._createEvent('CustomEvent');
+
+    e._dartDetail = detail;
+
+    // Only try setting the detail if it's one of these types to avoid
+    // first-chance exceptions. Can expand this list in the future as needed.
+    if (detail is List || detail is Map || detail is String || detail is num) {
+      try {
+        detail = convertDartToNative_SerializedScriptValue(detail);
+        e._initCustomEvent(type, canBubble, cancelable, detail);
+      } catch (_) {
+        e._initCustomEvent(type, canBubble, cancelable, null);
+      }
+    } else {
+      e._initCustomEvent(type, canBubble, cancelable, null);
+    }
+
+    return e;
+  }
+
+  get detail {
+    if (_dartDetail != null) {
+      return _dartDetail;
+    }
+    return _detail;
+  }
+
+  factory CustomEvent._(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return CustomEvent._create_1(type, eventInitDict_1);
+    }
+    return CustomEvent._create_2(type);
+  }
+  static CustomEvent _create_1(type, eventInitDict) =>
+      JS('CustomEvent', 'new CustomEvent(#,#)', type, eventInitDict);
+  static CustomEvent _create_2(type) =>
+      JS('CustomEvent', 'new CustomEvent(#)', type);
+
+  dynamic get _detail =>
+      convertNativeToDart_SerializedScriptValue(this._get__detail);
+  @JSName('detail')
+  @Creates('Null')
+  final dynamic _get__detail;
+
+  @JSName('initCustomEvent')
+  void _initCustomEvent(String type,
+      [bool bubbles, bool cancelable, Object detail]) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("HTMLDListElement")
+class DListElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory DListElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DListElement() => JS(
+      'returns:DListElement;creates:DListElement;new:true',
+      '#.createElement(#)',
+      document,
+      "dl");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DListElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Native("HTMLDataElement")
+class DataElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory DataElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DataElement.created() : super.created();
+
+  String value;
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Native("HTMLDataListElement")
+class DataListElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory DataListElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DataListElement() => document.createElement("datalist");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DataListElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => Element.isTagSupported('datalist');
+
+  @Returns('HtmlCollection|Null')
+  @Creates('HtmlCollection')
+  final List<Node> options;
+}
+// Copyright (c) 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.
+
+@Native("DataTransfer")
+class DataTransfer extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DataTransfer._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DataTransfer() {
+    return DataTransfer._create_1();
+  }
+  static DataTransfer _create_1() => JS('DataTransfer', 'new DataTransfer()');
+
+  String dropEffect;
+
+  String effectAllowed;
+
+  @Returns('FileList|Null')
+  @Creates('FileList')
+  final List<File> files;
+
+  final DataTransferItemList items;
+
+  final List<String> types;
+
+  void clearData([String format]) native;
+
+  String getData(String format) native;
+
+  void setData(String format, String data) native;
+
+  void setDragImage(Element image, int x, int y) native;
+}
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("DataTransferItem")
+class DataTransferItem extends Interceptor {
+  Entry getAsEntry() {
+    Entry entry = _webkitGetAsEntry();
+
+    if (entry.isFile)
+      applyExtension('FileEntry', entry);
+    else if (entry.isDirectory)
+      applyExtension('DirectoryEntry', entry);
+    else
+      applyExtension('Entry', entry);
+
+    return entry;
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory DataTransferItem._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String kind;
+
+  final String type;
+
+  File getAsFile() native;
+
+  @JSName('webkitGetAsEntry')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  Entry _webkitGetAsEntry() native;
+}
+// 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.
+
+@Native("DataTransferItemList")
+class DataTransferItemList extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DataTransferItemList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int length;
+
+  DataTransferItem add(data_OR_file, [String type]) native;
+
+  @JSName('add')
+  DataTransferItem addData(String data, String type) native;
+
+  @JSName('add')
+  DataTransferItem addFile(File file) native;
+
+  void clear() native;
+
+  DataTransferItem item(int index) native;
+
+  void remove(int index) native;
+
+  DataTransferItem operator [](int index) {
+    return JS('DataTransferItem', '#[#]', this, index);
+  }
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void DatabaseCallback(SqlDatabase database);
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void DecodeErrorCallback(DomException error);
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void DecodeSuccessCallback(AudioBuffer decodedData);
+// Copyright (c) 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.
+
+@Native("DedicatedWorkerGlobalScope")
+class DedicatedWorkerGlobalScope extends WorkerGlobalScope {
+  // To suppress missing implicit constructor warnings.
+  factory DedicatedWorkerGlobalScope._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `message` events to event
+   * handlers that are not necessarily instances of [DedicatedWorkerGlobalScope].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MessageEvent> messageEvent =
+      const EventStreamProvider<MessageEvent>('message');
+
+  static const int PERSISTENT = 1;
+
+  static const int TEMPORARY = 0;
+
+  void close() native;
+
+  void postMessage(/*any*/ message, [List<Object> transfer]) {
+    if (transfer != null) {
+      var message_1 = convertDartToNative_SerializedScriptValue(message);
+      _postMessage_1(message_1, transfer);
+      return;
+    }
+    var message_1 = convertDartToNative_SerializedScriptValue(message);
+    _postMessage_2(message_1);
+    return;
+  }
+
+  @JSName('postMessage')
+  void _postMessage_1(message, List<Object> transfer) native;
+  @JSName('postMessage')
+  void _postMessage_2(message) native;
+
+  @JSName('webkitRequestFileSystem')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void _webkitRequestFileSystem(int type, int size,
+      [_FileSystemCallback successCallback,
+      _ErrorCallback errorCallback]) native;
+
+  @JSName('webkitRequestFileSystemSync')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  _DOMFileSystemSync requestFileSystemSync(int type, int size) native;
+
+  @JSName('webkitResolveLocalFileSystemSyncURL')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  _EntrySync resolveLocalFileSystemSyncUrl(String url) native;
+
+  @JSName('webkitResolveLocalFileSystemURL')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void _webkitResolveLocalFileSystemUrl(
+      String url, _EntryCallback successCallback,
+      [_ErrorCallback errorCallback]) native;
+
+  /// Stream of `message` events handled by this [DedicatedWorkerGlobalScope].
+  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
+
+  static DedicatedWorkerGlobalScope get instance {
+    return _workerSelf as DedicatedWorkerGlobalScope;
+  }
+}
+
+// Copyright (c) 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.
+
+@Native("DeprecatedStorageInfo")
+class DeprecatedStorageInfo extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DeprecatedStorageInfo._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int PERSISTENT = 1;
+
+  static const int TEMPORARY = 0;
+
+  void queryUsageAndQuota(int storageType,
+      [StorageUsageCallback usageCallback,
+      StorageErrorCallback errorCallback]) native;
+
+  void requestQuota(int storageType, int newQuotaInBytes,
+      [StorageQuotaCallback quotaCallback,
+      StorageErrorCallback errorCallback]) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("DeprecatedStorageQuota")
+class DeprecatedStorageQuota extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DeprecatedStorageQuota._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  void queryUsageAndQuota(StorageUsageCallback usageCallback,
+      [StorageErrorCallback errorCallback]) native;
+
+  void requestQuota(int newQuotaInBytes,
+      [StorageQuotaCallback quotaCallback,
+      StorageErrorCallback errorCallback]) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("DeprecationReport")
+class DeprecationReport extends ReportBody {
+  // To suppress missing implicit constructor warnings.
+  factory DeprecationReport._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int lineNumber;
+
+  final String message;
+
+  final String sourceFile;
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Native("HTMLDetailsElement")
+class DetailsElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory DetailsElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DetailsElement() => document.createElement("details");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DetailsElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => Element.isTagSupported('details');
+
+  bool open;
+}
+// Copyright (c) 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.
+
+@Native("DetectedBarcode")
+class DetectedBarcode extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DetectedBarcode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DetectedBarcode() {
+    return DetectedBarcode._create_1();
+  }
+  static DetectedBarcode _create_1() =>
+      JS('DetectedBarcode', 'new DetectedBarcode()');
+
+  final Rectangle boundingBox;
+
+  final List cornerPoints;
+
+  final String rawValue;
+}
+// Copyright (c) 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.
+
+@Native("DetectedFace")
+class DetectedFace extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DetectedFace._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DetectedFace() {
+    return DetectedFace._create_1();
+  }
+  static DetectedFace _create_1() => JS('DetectedFace', 'new DetectedFace()');
+
+  final Rectangle boundingBox;
+
+  final List landmarks;
+}
+// Copyright (c) 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.
+
+@Native("DetectedText")
+class DetectedText extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DetectedText._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DetectedText() {
+    return DetectedText._create_1();
+  }
+  static DetectedText _create_1() => JS('DetectedText', 'new DetectedText()');
+
+  final Rectangle boundingBox;
+
+  final List cornerPoints;
+
+  final String rawValue;
+}
+// Copyright (c) 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.
+
+@Native("DeviceAcceleration")
+class DeviceAcceleration extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DeviceAcceleration._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num x;
+
+  final num y;
+
+  final num z;
+}
+// Copyright (c) 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.
+
+@Native("DeviceMotionEvent")
+class DeviceMotionEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory DeviceMotionEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DeviceMotionEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return DeviceMotionEvent._create_1(type, eventInitDict_1);
+    }
+    return DeviceMotionEvent._create_2(type);
+  }
+  static DeviceMotionEvent _create_1(type, eventInitDict) => JS(
+      'DeviceMotionEvent', 'new DeviceMotionEvent(#,#)', type, eventInitDict);
+  static DeviceMotionEvent _create_2(type) =>
+      JS('DeviceMotionEvent', 'new DeviceMotionEvent(#)', type);
+
+  final DeviceAcceleration acceleration;
+
+  final DeviceAcceleration accelerationIncludingGravity;
+
+  final num interval;
+
+  final DeviceRotationRate rotationRate;
+}
+// Copyright (c) 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.
+
+@Native("DeviceOrientationEvent")
+class DeviceOrientationEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory DeviceOrientationEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DeviceOrientationEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return DeviceOrientationEvent._create_1(type, eventInitDict_1);
+    }
+    return DeviceOrientationEvent._create_2(type);
+  }
+  static DeviceOrientationEvent _create_1(type, eventInitDict) => JS(
+      'DeviceOrientationEvent',
+      'new DeviceOrientationEvent(#,#)',
+      type,
+      eventInitDict);
+  static DeviceOrientationEvent _create_2(type) =>
+      JS('DeviceOrientationEvent', 'new DeviceOrientationEvent(#)', type);
+
+  final bool absolute;
+
+  final num alpha;
+
+  final num beta;
+
+  final num gamma;
+}
+// Copyright (c) 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.
+
+@Native("DeviceRotationRate")
+class DeviceRotationRate extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DeviceRotationRate._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num alpha;
+
+  final num beta;
+
+  final num gamma;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("HTMLDialogElement")
+class DialogElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory DialogElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DialogElement.created() : super.created();
+
+  bool open;
+
+  String returnValue;
+
+  void close([String returnValue]) native;
+
+  void show() native;
+
+  void showModal() native;
+}
+// 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.
+
+@Native("DirectoryEntry")
+class DirectoryEntry extends Entry {
+  /**
+   * Create a new directory with the specified `path`. If `exclusive` is true,
+   * the returned Future will complete with an error if a directory already
+   * exists with the specified `path`.
+   */
+  Future<Entry> createDirectory(String path, {bool exclusive: false}) {
+    return _getDirectory(path,
+        options: {'create': true, 'exclusive': exclusive});
+  }
+
+  DirectoryReader createReader() {
+    DirectoryReader reader = _createReader();
+    applyExtension('DirectoryReader', reader);
+    return reader;
+  }
+
+  /**
+   * Retrieve an already existing directory entry. The returned future will
+   * result in an error if a directory at `path` does not exist or if the item
+   * at `path` is not a directory.
+   */
+  Future<Entry> getDirectory(String path) {
+    return _getDirectory(path);
+  }
+
+  /**
+   * Create a new file with the specified `path`. If `exclusive` is true,
+   * the returned Future will complete with an error if a file already
+   * exists at the specified `path`.
+   */
+  Future<Entry> createFile(String path, {bool exclusive: false}) {
+    return _getFile(path, options: {'create': true, 'exclusive': exclusive});
+  }
+
+  /**
+   * Retrieve an already existing file entry. The returned future will
+   * result in an error if a file at `path` does not exist or if the item at
+   * `path` is not a file.
+   */
+  Future<Entry> getFile(String path) {
+    return _getFile(path);
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory DirectoryEntry._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('createReader')
+  DirectoryReader _createReader() native;
+
+  void __getDirectory(String path,
+      [Map options,
+      _EntryCallback successCallback,
+      _ErrorCallback errorCallback]) {
+    if (errorCallback != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      __getDirectory_1(path, options_1, successCallback, errorCallback);
+      return;
+    }
+    if (successCallback != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      __getDirectory_2(path, options_1, successCallback);
+      return;
+    }
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      __getDirectory_3(path, options_1);
+      return;
+    }
+    __getDirectory_4(path);
+    return;
+  }
+
+  @JSName('getDirectory')
+  void __getDirectory_1(path, options, _EntryCallback successCallback,
+      _ErrorCallback errorCallback) native;
+  @JSName('getDirectory')
+  void __getDirectory_2(path, options, _EntryCallback successCallback) native;
+  @JSName('getDirectory')
+  void __getDirectory_3(path, options) native;
+  @JSName('getDirectory')
+  void __getDirectory_4(path) native;
+
+  @JSName('getDirectory')
+  Future<Entry> _getDirectory(String path, {Map options}) {
+    var completer = new Completer<Entry>();
+    __getDirectory(path, options, (value) {
+      completer.complete(value);
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+
+  void __getFile(String path,
+      [Map options,
+      _EntryCallback successCallback,
+      _ErrorCallback errorCallback]) {
+    if (errorCallback != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      __getFile_1(path, options_1, successCallback, errorCallback);
+      return;
+    }
+    if (successCallback != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      __getFile_2(path, options_1, successCallback);
+      return;
+    }
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      __getFile_3(path, options_1);
+      return;
+    }
+    __getFile_4(path);
+    return;
+  }
+
+  @JSName('getFile')
+  void __getFile_1(path, options, _EntryCallback successCallback,
+      _ErrorCallback errorCallback) native;
+  @JSName('getFile')
+  void __getFile_2(path, options, _EntryCallback successCallback) native;
+  @JSName('getFile')
+  void __getFile_3(path, options) native;
+  @JSName('getFile')
+  void __getFile_4(path) native;
+
+  @JSName('getFile')
+  Future<Entry> _getFile(String path, {Map options}) {
+    var completer = new Completer<Entry>();
+    __getFile(path, options, (value) {
+      applyExtension('FileEntry', value);
+      completer.complete(value);
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+
+  @JSName('removeRecursively')
+  void _removeRecursively(VoidCallback successCallback,
+      [_ErrorCallback errorCallback]) native;
+
+  @JSName('removeRecursively')
+  Future removeRecursively() {
+    var completer = new Completer();
+    _removeRecursively(() {
+      completer.complete();
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+}
+// 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.
+
+@Native("DirectoryReader")
+class DirectoryReader extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DirectoryReader._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('readEntries')
+  void _readEntries(_EntriesCallback successCallback,
+      [_ErrorCallback errorCallback]) native;
+
+  Future<List<Entry>> readEntries() {
+    var completer = new Completer<List<Entry>>();
+    _readEntries((values) {
+      values.forEach((value) {
+        applyExtension('Entry', value);
+        Entry entry = value as Entry;
+        if (entry.isFile)
+          applyExtension('FileEntry', entry);
+        else if (entry.isDirectory) applyExtension('DirectoryEntry', entry);
+      });
+      completer.complete(new List<Entry>.from(values));
+    }, (error) {
+      completer.completeError(error);
+    });
+
+    return completer.future;
+  }
+}
+// Copyright (c) 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.
+
+/**
+ * A generic container for content on an HTML page;
+ * corresponds to the &lt;div&gt; tag.
+ *
+ * The [DivElement] is a generic container and does not have any semantic
+ * significance. It is functionally similar to [SpanElement].
+ *
+ * The [DivElement] is a block-level element, as opposed to [SpanElement],
+ * which is an inline-level element.
+ *
+ * Example usage:
+ *
+ *     DivElement div = new DivElement();
+ *     div.text = 'Here's my new DivElem
+ *     document.body.elements.add(elem);
+ *
+ * See also:
+ *
+ * * [HTML `<div>` element](http://www.w3.org/TR/html-markup/div.html) from W3C.
+ * * [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.
+ * * [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.
+ */
+@Native("HTMLDivElement")
+class DivElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory DivElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DivElement() => JS('returns:DivElement;creates:DivElement;new:true',
+      '#.createElement(#)', document, "div");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DivElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+/**
+ * The base class for all documents.
+ *
+ * Each web page loaded in the browser has its own [Document] object, which is
+ * typically an [HtmlDocument].
+ *
+ * If you aren't comfortable with DOM concepts, see the Dart tutorial
+ * [Target 2: Connect Dart & HTML](http://www.dartlang.org/docs/tutorials/connect-dart-html/).
+ */
+@Native("Document")
+class Document extends Node {
+  // To suppress missing implicit constructor warnings.
+  factory Document._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> pointerLockChangeEvent =
+      const EventStreamProvider<Event>('pointerlockchange');
+
+  static const EventStreamProvider<Event> pointerLockErrorEvent =
+      const EventStreamProvider<Event>('pointerlockerror');
+
+  /**
+   * Static factory designed to expose `readystatechange` events to event
+   * handlers that are not necessarily instances of [Document].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> readyStateChangeEvent =
+      const EventStreamProvider<Event>('readystatechange');
+
+  /**
+   * Static factory designed to expose `securitypolicyviolation` events to event
+   * handlers that are not necessarily instances of [Document].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<SecurityPolicyViolationEvent>
+      securityPolicyViolationEvent =
+      const EventStreamProvider<SecurityPolicyViolationEvent>(
+          'securitypolicyviolation');
+
+  /**
+   * Static factory designed to expose `selectionchange` events to event
+   * handlers that are not necessarily instances of [Document].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> selectionChangeEvent =
+      const EventStreamProvider<Event>('selectionchange');
+
+  factory Document() {
+    return Document._create_1();
+  }
+  static Document _create_1() => JS('Document', 'new Document()');
+
+  final String addressSpace;
+
+  @JSName('body')
+  HtmlElement _body;
+
+  final String contentType;
+
+  String cookie;
+
+  final ScriptElement currentScript;
+
+  WindowBase get window => _convertNativeToDart_Window(this._get_window);
+  @JSName('defaultView')
+  @Creates('Window|=Object')
+  @Returns('Window|=Object')
+  @Creates('Window|=Object|Null')
+  @Returns('Window|=Object|Null')
+  final dynamic _get_window;
+
+  final Element documentElement;
+
+  final String domain;
+
+  final bool fullscreenEnabled;
+
+  @JSName('head')
+  final HeadElement _head;
+
+  final bool hidden;
+
+  final DomImplementation implementation;
+
+  @JSName('lastModified')
+  final String _lastModified;
+
+  final String origin;
+
+  @JSName('preferredStylesheetSet')
+  final String _preferredStylesheetSet;
+
+  final String readyState;
+
+  @JSName('referrer')
+  final String _referrer;
+
+  final SvgSvgElement rootElement;
+
+  Element rootScroller;
+
+  final Element scrollingElement;
+
+  @JSName('selectedStylesheetSet')
+  String _selectedStylesheetSet;
+
+  final String suborigin;
+
+  final DocumentTimeline timeline;
+
+  @JSName('title')
+  String _title;
+
+  @JSName('visibilityState')
+  final String _visibilityState;
+
+  @JSName('webkitFullscreenElement')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  final Element _webkitFullscreenElement;
+
+  @JSName('webkitFullscreenEnabled')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  final bool _webkitFullscreenEnabled;
+
+  @JSName('webkitHidden')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  final bool _webkitHidden;
+
+  @JSName('webkitVisibilityState')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  final String _webkitVisibilityState;
+
+  Node adoptNode(Node node) native;
+
+  @JSName('caretRangeFromPoint')
+  Range _caretRangeFromPoint(int x, int y) native;
+
+  DocumentFragment createDocumentFragment() native;
+
+  @JSName('createElement')
+  Element _createElement(String localName_OR_tagName,
+      [options_OR_typeExtension]) native;
+
+  @JSName('createElementNS')
+  Element _createElementNS(String namespaceURI, String qualifiedName,
+      [options_OR_typeExtension]) native;
+
+  @JSName('createEvent')
+  Event _createEvent(String eventType) native;
+
+  Range createRange() native;
+
+  @JSName('createTextNode')
+  Text _createTextNode(String data) native;
+
+  Touch _createTouch(Window view, EventTarget target, int identifier, num pageX,
+      num pageY, num screenX, num screenY,
+      [num radiusX, num radiusY, num rotationAngle, num force]) {
+    if (force != null) {
+      var target_1 = _convertDartToNative_EventTarget(target);
+      return _createTouch_1(view, target_1, identifier, pageX, pageY, screenX,
+          screenY, radiusX, radiusY, rotationAngle, force);
+    }
+    if (rotationAngle != null) {
+      var target_1 = _convertDartToNative_EventTarget(target);
+      return _createTouch_2(view, target_1, identifier, pageX, pageY, screenX,
+          screenY, radiusX, radiusY, rotationAngle);
+    }
+    if (radiusY != null) {
+      var target_1 = _convertDartToNative_EventTarget(target);
+      return _createTouch_3(view, target_1, identifier, pageX, pageY, screenX,
+          screenY, radiusX, radiusY);
+    }
+    if (radiusX != null) {
+      var target_1 = _convertDartToNative_EventTarget(target);
+      return _createTouch_4(
+          view, target_1, identifier, pageX, pageY, screenX, screenY, radiusX);
+    }
+    var target_1 = _convertDartToNative_EventTarget(target);
+    return _createTouch_5(
+        view, target_1, identifier, pageX, pageY, screenX, screenY);
+  }
+
+  @JSName('createTouch')
+  Touch _createTouch_1(Window view, target, identifier, pageX, pageY, screenX,
+      screenY, radiusX, radiusY, rotationAngle, force) native;
+  @JSName('createTouch')
+  Touch _createTouch_2(Window view, target, identifier, pageX, pageY, screenX,
+      screenY, radiusX, radiusY, rotationAngle) native;
+  @JSName('createTouch')
+  Touch _createTouch_3(Window view, target, identifier, pageX, pageY, screenX,
+      screenY, radiusX, radiusY) native;
+  @JSName('createTouch')
+  Touch _createTouch_4(Window view, target, identifier, pageX, pageY, screenX,
+      screenY, radiusX) native;
+  @JSName('createTouch')
+  Touch _createTouch_5(
+      Window view, target, identifier, pageX, pageY, screenX, screenY) native;
+
+  @JSName('createTouchList')
+  TouchList _createTouchList(Touch touches) native;
+
+  bool execCommand(String commandId, [bool showUI, String value]) native;
+
+  void exitFullscreen() native;
+
+  void exitPointerLock() native;
+
+  List<Animation> getAnimations() native;
+
+  @Creates('NodeList|HtmlCollection')
+  @Returns('NodeList|HtmlCollection')
+  List<Node> getElementsByClassName(String classNames) native;
+
+  @Creates('NodeList|HtmlCollection')
+  @Returns('NodeList|HtmlCollection')
+  List<Node> getElementsByName(String elementName) native;
+
+  @Creates('NodeList|HtmlCollection')
+  @Returns('NodeList|HtmlCollection')
+  List<Node> getElementsByTagName(String localName) native;
+
+  Node importNode(Node node, [bool deep]) native;
+
+  bool queryCommandEnabled(String commandId) native;
+
+  bool queryCommandIndeterm(String commandId) native;
+
+  bool queryCommandState(String commandId) native;
+
+  bool queryCommandSupported(String commandId) native;
+
+  String queryCommandValue(String commandId) native;
+
+  Function registerElement2(String type, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return _registerElement2_1(type, options_1);
+    }
+    return _registerElement2_2(type);
+  }
+
+  @JSName('registerElement')
+  Function _registerElement2_1(type, options) native;
+  @JSName('registerElement')
+  Function _registerElement2_2(type) native;
+
+  @JSName('webkitExitFullscreen')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void _webkitExitFullscreen() native;
+
+  // From NonElementParentNode
+
+  Element getElementById(String elementId) native;
+
+  // From DocumentOrShadowRoot
+
+  final Element activeElement;
+
+  final Element fullscreenElement;
+
+  final Element pointerLockElement;
+
+  @JSName('styleSheets')
+  @Returns('_StyleSheetList|Null')
+  @Creates('_StyleSheetList')
+  final List<StyleSheet> _styleSheets;
+
+  @JSName('elementFromPoint')
+  Element _elementFromPoint(int x, int y) native;
+
+  List<Element> elementsFromPoint(int x, int y) native;
+
+  // From FontFaceSource
+
+  final FontFaceSet fonts;
+
+  // From ParentNode
+
+  @JSName('childElementCount')
+  final int _childElementCount;
+
+  @JSName('children')
+  @Returns('HtmlCollection|Null')
+  @Creates('HtmlCollection')
+  final List<Node> _children;
+
+  @JSName('firstElementChild')
+  final Element _firstElementChild;
+
+  @JSName('lastElementChild')
+  final Element _lastElementChild;
+
+  /**
+   * Finds the first descendant element of this document that matches the
+   * specified group of selectors.
+   *
+   * Unless your webpage contains multiple documents, the top-level
+   * [querySelector]
+   * method behaves the same as this method, so you should use it instead to
+   * save typing a few characters.
+   *
+   * [selectors] should be a string using CSS selector syntax.
+   *
+   *     var element1 = document.querySelector('.className');
+   *     var element2 = document.querySelector('#id');
+   *
+   * For details about CSS selector syntax, see the
+   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
+   */
+  Element querySelector(String selectors) native;
+
+  @JSName('querySelectorAll')
+  @Creates('NodeList')
+  @Returns('NodeList')
+  List<Node> _querySelectorAll(String selectors) native;
+
+  /// Stream of `abort` events handled by this [Document].
+  Stream<Event> get onAbort => Element.abortEvent.forTarget(this);
+
+  /// Stream of `beforecopy` events handled by this [Document].
+  Stream<Event> get onBeforeCopy => Element.beforeCopyEvent.forTarget(this);
+
+  /// Stream of `beforecut` events handled by this [Document].
+  Stream<Event> get onBeforeCut => Element.beforeCutEvent.forTarget(this);
+
+  /// Stream of `beforepaste` events handled by this [Document].
+  Stream<Event> get onBeforePaste => Element.beforePasteEvent.forTarget(this);
+
+  /// Stream of `blur` events handled by this [Document].
+  Stream<Event> get onBlur => Element.blurEvent.forTarget(this);
+
+  Stream<Event> get onCanPlay => Element.canPlayEvent.forTarget(this);
+
+  Stream<Event> get onCanPlayThrough =>
+      Element.canPlayThroughEvent.forTarget(this);
+
+  /// Stream of `change` events handled by this [Document].
+  Stream<Event> get onChange => Element.changeEvent.forTarget(this);
+
+  /// Stream of `click` events handled by this [Document].
+  Stream<MouseEvent> get onClick => Element.clickEvent.forTarget(this);
+
+  /// Stream of `contextmenu` events handled by this [Document].
+  Stream<MouseEvent> get onContextMenu =>
+      Element.contextMenuEvent.forTarget(this);
+
+  /// Stream of `copy` events handled by this [Document].
+  Stream<ClipboardEvent> get onCopy => Element.copyEvent.forTarget(this);
+
+  /// Stream of `cut` events handled by this [Document].
+  Stream<ClipboardEvent> get onCut => Element.cutEvent.forTarget(this);
+
+  /// Stream of `doubleclick` events handled by this [Document].
+  @DomName('Document.ondblclick')
+  Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);
+
+  /// Stream of `drag` events handled by this [Document].
+  Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);
+
+  /// Stream of `dragend` events handled by this [Document].
+  Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);
+
+  /// Stream of `dragenter` events handled by this [Document].
+  Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);
+
+  /// Stream of `dragleave` events handled by this [Document].
+  Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);
+
+  /// Stream of `dragover` events handled by this [Document].
+  Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);
+
+  /// Stream of `dragstart` events handled by this [Document].
+  Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);
+
+  /// Stream of `drop` events handled by this [Document].
+  Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);
+
+  Stream<Event> get onDurationChange =>
+      Element.durationChangeEvent.forTarget(this);
+
+  Stream<Event> get onEmptied => Element.emptiedEvent.forTarget(this);
+
+  Stream<Event> get onEnded => Element.endedEvent.forTarget(this);
+
+  /// Stream of `error` events handled by this [Document].
+  Stream<Event> get onError => Element.errorEvent.forTarget(this);
+
+  /// Stream of `focus` events handled by this [Document].
+  Stream<Event> get onFocus => Element.focusEvent.forTarget(this);
+
+  /// Stream of `input` events handled by this [Document].
+  Stream<Event> get onInput => Element.inputEvent.forTarget(this);
+
+  /// Stream of `invalid` events handled by this [Document].
+  Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);
+
+  /// Stream of `keydown` events handled by this [Document].
+  Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);
+
+  /// Stream of `keypress` events handled by this [Document].
+  Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);
+
+  /// Stream of `keyup` events handled by this [Document].
+  Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);
+
+  /// Stream of `load` events handled by this [Document].
+  Stream<Event> get onLoad => Element.loadEvent.forTarget(this);
+
+  Stream<Event> get onLoadedData => Element.loadedDataEvent.forTarget(this);
+
+  Stream<Event> get onLoadedMetadata =>
+      Element.loadedMetadataEvent.forTarget(this);
+
+  /// Stream of `mousedown` events handled by this [Document].
+  Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);
+
+  /// Stream of `mouseenter` events handled by this [Document].
+  Stream<MouseEvent> get onMouseEnter =>
+      Element.mouseEnterEvent.forTarget(this);
+
+  /// Stream of `mouseleave` events handled by this [Document].
+  Stream<MouseEvent> get onMouseLeave =>
+      Element.mouseLeaveEvent.forTarget(this);
+
+  /// Stream of `mousemove` events handled by this [Document].
+  Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);
+
+  /// Stream of `mouseout` events handled by this [Document].
+  Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);
+
+  /// Stream of `mouseover` events handled by this [Document].
+  Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);
+
+  /// Stream of `mouseup` events handled by this [Document].
+  Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);
+
+  /// Stream of `mousewheel` events handled by this [Document].
+  Stream<WheelEvent> get onMouseWheel =>
+      Element.mouseWheelEvent.forTarget(this);
+
+  /// Stream of `paste` events handled by this [Document].
+  Stream<ClipboardEvent> get onPaste => Element.pasteEvent.forTarget(this);
+
+  Stream<Event> get onPause => Element.pauseEvent.forTarget(this);
+
+  Stream<Event> get onPlay => Element.playEvent.forTarget(this);
+
+  Stream<Event> get onPlaying => Element.playingEvent.forTarget(this);
+
+  Stream<Event> get onPointerLockChange =>
+      pointerLockChangeEvent.forTarget(this);
+
+  Stream<Event> get onPointerLockError => pointerLockErrorEvent.forTarget(this);
+
+  Stream<Event> get onRateChange => Element.rateChangeEvent.forTarget(this);
+
+  /// Stream of `readystatechange` events handled by this [Document].
+  Stream<Event> get onReadyStateChange => readyStateChangeEvent.forTarget(this);
+
+  /// Stream of `reset` events handled by this [Document].
+  Stream<Event> get onReset => Element.resetEvent.forTarget(this);
+
+  Stream<Event> get onResize => Element.resizeEvent.forTarget(this);
+
+  /// Stream of `scroll` events handled by this [Document].
+  Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);
+
+  /// Stream of `search` events handled by this [Document].
+  Stream<Event> get onSearch => Element.searchEvent.forTarget(this);
+
+  /// Stream of `securitypolicyviolation` events handled by this [Document].
+  Stream<SecurityPolicyViolationEvent> get onSecurityPolicyViolation =>
+      securityPolicyViolationEvent.forTarget(this);
+
+  Stream<Event> get onSeeked => Element.seekedEvent.forTarget(this);
+
+  Stream<Event> get onSeeking => Element.seekingEvent.forTarget(this);
+
+  /// Stream of `select` events handled by this [Document].
+  Stream<Event> get onSelect => Element.selectEvent.forTarget(this);
+
+  /// Stream of `selectionchange` events handled by this [Document].
+  Stream<Event> get onSelectionChange => selectionChangeEvent.forTarget(this);
+
+  /// Stream of `selectstart` events handled by this [Document].
+  Stream<Event> get onSelectStart => Element.selectStartEvent.forTarget(this);
+
+  Stream<Event> get onStalled => Element.stalledEvent.forTarget(this);
+
+  /// Stream of `submit` events handled by this [Document].
+  Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);
+
+  Stream<Event> get onSuspend => Element.suspendEvent.forTarget(this);
+
+  Stream<Event> get onTimeUpdate => Element.timeUpdateEvent.forTarget(this);
+
+  /// Stream of `touchcancel` events handled by this [Document].
+  Stream<TouchEvent> get onTouchCancel =>
+      Element.touchCancelEvent.forTarget(this);
+
+  /// Stream of `touchend` events handled by this [Document].
+  Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);
+
+  /// Stream of `touchmove` events handled by this [Document].
+  Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);
+
+  /// Stream of `touchstart` events handled by this [Document].
+  Stream<TouchEvent> get onTouchStart =>
+      Element.touchStartEvent.forTarget(this);
+
+  Stream<Event> get onVolumeChange => Element.volumeChangeEvent.forTarget(this);
+
+  Stream<Event> get onWaiting => Element.waitingEvent.forTarget(this);
+
+  /// Stream of `fullscreenchange` events handled by this [Document].
+  Stream<Event> get onFullscreenChange =>
+      Element.fullscreenChangeEvent.forTarget(this);
+
+  /// Stream of `fullscreenerror` events handled by this [Document].
+  Stream<Event> get onFullscreenError =>
+      Element.fullscreenErrorEvent.forTarget(this);
+
+  /**
+   * Finds all descendant elements of this document that match the specified
+   * group of selectors.
+   *
+   * Unless your webpage contains multiple documents, the top-level
+   * [querySelectorAll]
+   * method behaves the same as this method, so you should use it instead to
+   * save typing a few characters.
+   *
+   * [selectors] should be a string using CSS selector syntax.
+   *
+   *     var items = document.querySelectorAll('.itemClassName');
+   *
+   * For details about CSS selector syntax, see the
+   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
+   */
+  ElementList<T> querySelectorAll<T extends Element>(String selectors) =>
+      new _FrozenElementList<T>._wrap(_querySelectorAll(selectors));
+
+  /// Checks if [registerElement] is supported on the current platform.
+  bool get supportsRegisterElement {
+    return JS('bool', '("registerElement" in #)', this);
+  }
+
+  /// *Deprecated*: use [supportsRegisterElement] instead.
+  @deprecated
+  bool get supportsRegister => supportsRegisterElement;
+
+  void registerElement(String tag, Type customElementClass,
+      {String extendsTag}) {
+    registerElement2(
+        tag, {'prototype': customElementClass, 'extends': extendsTag});
+  }
+
+  @pragma('dart2js:tryInline') // Almost all call sites have one argument.
+  Element createElement(String tagName, [String typeExtension]) {
+    return (typeExtension == null)
+        ? _createElement_2(tagName)
+        : _createElement(tagName, typeExtension);
+  }
+
+  // The two-argument version of this is automatically generated, but we need to
+  // omit the typeExtension if it's null on Firefox or we get an is="null" attribute.
+  _createElement_2(String tagName) =>
+      JS('Element', '#.createElement(#)', this, tagName);
+
+  // The three-argument version of this is automatically generated, but we need to
+  // omit the typeExtension if it's null on Firefox or we get an is="null" attribute.
+  _createElementNS_2(String namespaceURI, String qualifiedName) => JS(
+      'Element', '#.createElementNS(#, #)', this, namespaceURI, qualifiedName);
+
+  Element createElementNS(String namespaceURI, String qualifiedName,
+      [String typeExtension]) {
+    return (typeExtension == null)
+        ? _createElementNS_2(namespaceURI, qualifiedName)
+        : _createElementNS(namespaceURI, qualifiedName, typeExtension);
+  }
+
+  NodeIterator _createNodeIterator(Node root,
+          [int whatToShow, NodeFilter filter]) =>
+      JS('NodeIterator', '#.createNodeIterator(#, #, #, false)', this, root,
+          whatToShow, filter);
+
+  TreeWalker _createTreeWalker(Node root,
+          [int whatToShow, NodeFilter filter]) =>
+      JS('TreeWalker', '#.createTreeWalker(#, #, #, false)', this, root,
+          whatToShow, filter);
+
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  String get visibilityState => JS(
+      'String',
+      '(#.visibilityState || #.mozVisibilityState || #.msVisibilityState ||'
+          '#.webkitVisibilityState)',
+      this,
+      this,
+      this,
+      this);
+}
+// 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.
+
+@Native("DocumentFragment")
+class DocumentFragment extends Node
+    implements NonElementParentNode, ParentNode {
+  factory DocumentFragment() => document.createDocumentFragment();
+
+  factory DocumentFragment.html(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    return document.body.createFragment(html,
+        validator: validator, treeSanitizer: treeSanitizer);
+  }
+
+  factory DocumentFragment.svg(String svgContent,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    return new svg.SvgSvgElement().createFragment(svgContent,
+        validator: validator, treeSanitizer: treeSanitizer);
+  }
+
+  HtmlCollection get _children =>
+      throw new UnimplementedError('Use _docChildren instead');
+
+  // Native field is used only by Dart code so does not lead to instantiation
+  // of native classes
+  @Creates('Null')
+  List<Element> _docChildren;
+
+  List<Element> get children {
+    if (_docChildren == null) {
+      _docChildren = new FilteredElementList(this);
+    }
+    return _docChildren;
+  }
+
+  set children(List<Element> value) {
+    // Copy list first since we don't want liveness during iteration.
+    var copy = value.toList();
+    var children = this.children;
+    children.clear();
+    children.addAll(copy);
+  }
+
+  /**
+   * Finds all descendant elements of this document fragment that match the
+   * specified group of selectors.
+   *
+   * [selectors] should be a string using CSS selector syntax.
+   *
+   *     var items = document.querySelectorAll('.itemClassName');
+   *
+   * For details about CSS selector syntax, see the
+   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
+   */
+  ElementList<T> querySelectorAll<T extends Element>(String selectors) =>
+      new _FrozenElementList<T>._wrap(_querySelectorAll(selectors));
+
+  String get innerHtml {
+    final e = new DivElement();
+    e.append(this.clone(true));
+    return e.innerHtml;
+  }
+
+  set innerHtml(String value) {
+    this.setInnerHtml(value);
+  }
+
+  void setInnerHtml(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    this.nodes.clear();
+    append(document.body.createFragment(html,
+        validator: validator, treeSanitizer: treeSanitizer));
+  }
+
+  /**
+   * Adds the specified text as a text node after the last child of this
+   * document fragment.
+   */
+  void appendText(String text) {
+    this.append(new Text(text));
+  }
+
+  /**
+   * Parses the specified text as HTML and adds the resulting node after the
+   * last child of this document fragment.
+   */
+  void appendHtml(String text,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    this.append(new DocumentFragment.html(text,
+        validator: validator, treeSanitizer: treeSanitizer));
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory DocumentFragment._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  // From NonElementParentNode
+
+  Element getElementById(String elementId) native;
+
+  // From ParentNode
+
+  @JSName('childElementCount')
+  final int _childElementCount;
+
+  @JSName('firstElementChild')
+  final Element _firstElementChild;
+
+  @JSName('lastElementChild')
+  final Element _lastElementChild;
+
+  /**
+   * Finds the first descendant element of this document fragment that matches
+   * the specified group of selectors.
+   *
+   * [selectors] should be a string using CSS selector syntax.
+   *
+   *     var element1 = fragment.querySelector('.className');
+   *     var element2 = fragment.querySelector('#id');
+   *
+   * For details about CSS selector syntax, see the
+   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
+   */
+  Element querySelector(String selectors) native;
+
+  @JSName('querySelectorAll')
+  @Creates('NodeList')
+  @Returns('NodeList')
+  List<Node> _querySelectorAll(String selectors) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("DocumentOrShadowRoot")
+class DocumentOrShadowRoot extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DocumentOrShadowRoot._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final Element activeElement;
+
+  final Element fullscreenElement;
+
+  final Element pointerLockElement;
+
+  @Returns('_StyleSheetList|Null')
+  @Creates('_StyleSheetList')
+  final List<StyleSheet> styleSheets;
+
+  Element elementFromPoint(int x, int y) native;
+
+  List<Element> elementsFromPoint(int x, int y) native;
+
+  Selection getSelection() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("DocumentTimeline")
+class DocumentTimeline extends AnimationTimeline {
+  // To suppress missing implicit constructor warnings.
+  factory DocumentTimeline._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DocumentTimeline([Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return DocumentTimeline._create_1(options_1);
+    }
+    return DocumentTimeline._create_2();
+  }
+  static DocumentTimeline _create_1(options) =>
+      JS('DocumentTimeline', 'new DocumentTimeline(#)', options);
+  static DocumentTimeline _create_2() =>
+      JS('DocumentTimeline', 'new DocumentTimeline()');
+}
+// Copyright (c) 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.
+
+@Native("DOMError")
+class DomError extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DomError._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DomError(String name, [String message]) {
+    if (message != null) {
+      return DomError._create_1(name, message);
+    }
+    return DomError._create_2(name);
+  }
+  static DomError _create_1(name, message) =>
+      JS('DomError', 'new DOMError(#,#)', name, message);
+  static DomError _create_2(name) => JS('DomError', 'new DOMError(#)', name);
+
+  final String message;
+
+  final String name;
+}
+// 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.
+
+@Unstable()
+@Native("DOMException")
+class DomException extends Interceptor {
+  static const String INDEX_SIZE = 'IndexSizeError';
+  static const String HIERARCHY_REQUEST = 'HierarchyRequestError';
+  static const String WRONG_DOCUMENT = 'WrongDocumentError';
+  static const String INVALID_CHARACTER = 'InvalidCharacterError';
+  static const String NO_MODIFICATION_ALLOWED = 'NoModificationAllowedError';
+  static const String NOT_FOUND = 'NotFoundError';
+  static const String NOT_SUPPORTED = 'NotSupportedError';
+  static const String INVALID_STATE = 'InvalidStateError';
+  static const String SYNTAX = 'SyntaxError';
+  static const String INVALID_MODIFICATION = 'InvalidModificationError';
+  static const String NAMESPACE = 'NamespaceError';
+  static const String INVALID_ACCESS = 'InvalidAccessError';
+  static const String TYPE_MISMATCH = 'TypeMismatchError';
+  static const String SECURITY = 'SecurityError';
+  static const String NETWORK = 'NetworkError';
+  static const String ABORT = 'AbortError';
+  static const String URL_MISMATCH = 'URLMismatchError';
+  static const String QUOTA_EXCEEDED = 'QuotaExceededError';
+  static const String TIMEOUT = 'TimeoutError';
+  static const String INVALID_NODE_TYPE = 'InvalidNodeTypeError';
+  static const String DATA_CLONE = 'DataCloneError';
+  static const String ENCODING = 'EncodingError';
+  static const String NOT_READABLE = 'NotReadableError';
+  static const String UNKNOWN = 'UnknownError';
+  static const String CONSTRAINT = 'ConstraintError';
+  static const String TRANSACTION_INACTIVE = 'TransactionInactiveError';
+  static const String READ_ONLY = 'ReadOnlyError';
+  static const String VERSION = 'VersionError';
+  static const String OPERATION = 'OperationError';
+  static const String NOT_ALLOWED = 'NotAllowedError';
+  // Is TypeError class derived from DomException but name is 'TypeError'
+  static const String TYPE_ERROR = 'TypeError';
+
+  String get name {
+    var errorName = JS('String', '#.name', this);
+    // Although Safari nightly has updated the name to SecurityError, Safari 5
+    // and 6 still return SECURITY_ERR.
+    if (Device.isWebKit && errorName == 'SECURITY_ERR') return 'SecurityError';
+    // Chrome release still uses old string, remove this line when Chrome stable
+    // also prints out SyntaxError.
+    if (Device.isWebKit && errorName == 'SYNTAX_ERR') return 'SyntaxError';
+    return errorName;
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory DomException._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String message;
+
+  String toString() => JS('String', 'String(#)', this);
+}
+// Copyright (c) 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.
+
+@Native("DOMImplementation")
+class DomImplementation extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DomImplementation._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  XmlDocument createDocument(
+      String namespaceURI, String qualifiedName, _DocumentType doctype) native;
+
+  _DocumentType createDocumentType(
+      String qualifiedName, String publicId, String systemId) native;
+
+  @JSName('createHTMLDocument')
+  HtmlDocument createHtmlDocument([String title]) native;
+
+  bool hasFeature() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("Iterator")
+class DomIterator extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DomIterator._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Object next([Object value]) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("DOMMatrix")
+class DomMatrix extends DomMatrixReadOnly {
+  // To suppress missing implicit constructor warnings.
+  factory DomMatrix._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DomMatrix([Object init]) {
+    if (init != null) {
+      return DomMatrix._create_1(init);
+    }
+    return DomMatrix._create_2();
+  }
+  static DomMatrix _create_1(init) => JS('DomMatrix', 'new DOMMatrix(#)', init);
+  static DomMatrix _create_2() => JS('DomMatrix', 'new DOMMatrix()');
+
+  // Shadowing definition.
+  num get a => JS("num", "#.a", this);
+
+  set a(num value) {
+    JS("void", "#.a = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get b => JS("num", "#.b", this);
+
+  set b(num value) {
+    JS("void", "#.b = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get c => JS("num", "#.c", this);
+
+  set c(num value) {
+    JS("void", "#.c = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get d => JS("num", "#.d", this);
+
+  set d(num value) {
+    JS("void", "#.d = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get e => JS("num", "#.e", this);
+
+  set e(num value) {
+    JS("void", "#.e = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get f => JS("num", "#.f", this);
+
+  set f(num value) {
+    JS("void", "#.f = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get m11 => JS("num", "#.m11", this);
+
+  set m11(num value) {
+    JS("void", "#.m11 = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get m12 => JS("num", "#.m12", this);
+
+  set m12(num value) {
+    JS("void", "#.m12 = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get m13 => JS("num", "#.m13", this);
+
+  set m13(num value) {
+    JS("void", "#.m13 = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get m14 => JS("num", "#.m14", this);
+
+  set m14(num value) {
+    JS("void", "#.m14 = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get m21 => JS("num", "#.m21", this);
+
+  set m21(num value) {
+    JS("void", "#.m21 = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get m22 => JS("num", "#.m22", this);
+
+  set m22(num value) {
+    JS("void", "#.m22 = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get m23 => JS("num", "#.m23", this);
+
+  set m23(num value) {
+    JS("void", "#.m23 = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get m24 => JS("num", "#.m24", this);
+
+  set m24(num value) {
+    JS("void", "#.m24 = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get m31 => JS("num", "#.m31", this);
+
+  set m31(num value) {
+    JS("void", "#.m31 = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get m32 => JS("num", "#.m32", this);
+
+  set m32(num value) {
+    JS("void", "#.m32 = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get m33 => JS("num", "#.m33", this);
+
+  set m33(num value) {
+    JS("void", "#.m33 = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get m34 => JS("num", "#.m34", this);
+
+  set m34(num value) {
+    JS("void", "#.m34 = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get m41 => JS("num", "#.m41", this);
+
+  set m41(num value) {
+    JS("void", "#.m41 = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get m42 => JS("num", "#.m42", this);
+
+  set m42(num value) {
+    JS("void", "#.m42 = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get m43 => JS("num", "#.m43", this);
+
+  set m43(num value) {
+    JS("void", "#.m43 = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get m44 => JS("num", "#.m44", this);
+
+  set m44(num value) {
+    JS("void", "#.m44 = #", this, value);
+  }
+
+  static DomMatrix fromFloat32Array(Float32List array32) native;
+
+  static DomMatrix fromFloat64Array(Float64List array64) native;
+
+  static DomMatrix fromMatrix([Map other]) {
+    if (other != null) {
+      var other_1 = convertDartToNative_Dictionary(other);
+      return _fromMatrix_1(other_1);
+    }
+    return _fromMatrix_2();
+  }
+
+  @JSName('fromMatrix')
+  static DomMatrix _fromMatrix_1(other) native;
+  @JSName('fromMatrix')
+  static DomMatrix _fromMatrix_2() native;
+
+  DomMatrix invertSelf() native;
+
+  DomMatrix multiplySelf([Map other]) {
+    if (other != null) {
+      var other_1 = convertDartToNative_Dictionary(other);
+      return _multiplySelf_1(other_1);
+    }
+    return _multiplySelf_2();
+  }
+
+  @JSName('multiplySelf')
+  DomMatrix _multiplySelf_1(other) native;
+  @JSName('multiplySelf')
+  DomMatrix _multiplySelf_2() native;
+
+  DomMatrix preMultiplySelf([Map other]) {
+    if (other != null) {
+      var other_1 = convertDartToNative_Dictionary(other);
+      return _preMultiplySelf_1(other_1);
+    }
+    return _preMultiplySelf_2();
+  }
+
+  @JSName('preMultiplySelf')
+  DomMatrix _preMultiplySelf_1(other) native;
+  @JSName('preMultiplySelf')
+  DomMatrix _preMultiplySelf_2() native;
+
+  DomMatrix rotateAxisAngleSelf([num x, num y, num z, num angle]) native;
+
+  DomMatrix rotateFromVectorSelf([num x, num y]) native;
+
+  DomMatrix rotateSelf([num rotX, num rotY, num rotZ]) native;
+
+  DomMatrix scale3dSelf([num scale, num originX, num originY, num originZ])
+      native;
+
+  DomMatrix scaleSelf(
+      [num scaleX,
+      num scaleY,
+      num scaleZ,
+      num originX,
+      num originY,
+      num originZ]) native;
+
+  DomMatrix setMatrixValue(String transformList) native;
+
+  DomMatrix skewXSelf([num sx]) native;
+
+  DomMatrix skewYSelf([num sy]) native;
+
+  DomMatrix translateSelf([num tx, num ty, num tz]) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("DOMMatrixReadOnly")
+class DomMatrixReadOnly extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DomMatrixReadOnly._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DomMatrixReadOnly([Object init]) {
+    if (init != null) {
+      return DomMatrixReadOnly._create_1(init);
+    }
+    return DomMatrixReadOnly._create_2();
+  }
+  static DomMatrixReadOnly _create_1(init) =>
+      JS('DomMatrixReadOnly', 'new DOMMatrixReadOnly(#)', init);
+  static DomMatrixReadOnly _create_2() =>
+      JS('DomMatrixReadOnly', 'new DOMMatrixReadOnly()');
+
+  num get a => JS("num", "#.a", this);
+
+  num get b => JS("num", "#.b", this);
+
+  num get c => JS("num", "#.c", this);
+
+  num get d => JS("num", "#.d", this);
+
+  num get e => JS("num", "#.e", this);
+
+  num get f => JS("num", "#.f", this);
+
+  bool get is2D => JS("bool", "#.is2D", this);
+
+  bool get isIdentity => JS("bool", "#.isIdentity", this);
+
+  num get m11 => JS("num", "#.m11", this);
+
+  num get m12 => JS("num", "#.m12", this);
+
+  num get m13 => JS("num", "#.m13", this);
+
+  num get m14 => JS("num", "#.m14", this);
+
+  num get m21 => JS("num", "#.m21", this);
+
+  num get m22 => JS("num", "#.m22", this);
+
+  num get m23 => JS("num", "#.m23", this);
+
+  num get m24 => JS("num", "#.m24", this);
+
+  num get m31 => JS("num", "#.m31", this);
+
+  num get m32 => JS("num", "#.m32", this);
+
+  num get m33 => JS("num", "#.m33", this);
+
+  num get m34 => JS("num", "#.m34", this);
+
+  num get m41 => JS("num", "#.m41", this);
+
+  num get m42 => JS("num", "#.m42", this);
+
+  num get m43 => JS("num", "#.m43", this);
+
+  num get m44 => JS("num", "#.m44", this);
+
+  DomMatrix flipX() native;
+
+  DomMatrix flipY() native;
+
+  static DomMatrixReadOnly fromFloat32Array(Float32List array32) native;
+
+  static DomMatrixReadOnly fromFloat64Array(Float64List array64) native;
+
+  static DomMatrixReadOnly fromMatrix([Map other]) {
+    if (other != null) {
+      var other_1 = convertDartToNative_Dictionary(other);
+      return _fromMatrix_1(other_1);
+    }
+    return _fromMatrix_2();
+  }
+
+  @JSName('fromMatrix')
+  static DomMatrixReadOnly _fromMatrix_1(other) native;
+  @JSName('fromMatrix')
+  static DomMatrixReadOnly _fromMatrix_2() native;
+
+  DomMatrix inverse() native;
+
+  DomMatrix multiply([Map other]) {
+    if (other != null) {
+      var other_1 = convertDartToNative_Dictionary(other);
+      return _multiply_1(other_1);
+    }
+    return _multiply_2();
+  }
+
+  @JSName('multiply')
+  DomMatrix _multiply_1(other) native;
+  @JSName('multiply')
+  DomMatrix _multiply_2() native;
+
+  DomMatrix rotate([num rotX, num rotY, num rotZ]) native;
+
+  DomMatrix rotateAxisAngle([num x, num y, num z, num angle]) native;
+
+  DomMatrix rotateFromVector([num x, num y]) native;
+
+  DomMatrix scale(
+      [num scaleX,
+      num scaleY,
+      num scaleZ,
+      num originX,
+      num originY,
+      num originZ]) native;
+
+  DomMatrix scale3d([num scale, num originX, num originY, num originZ]) native;
+
+  DomMatrix skewX([num sx]) native;
+
+  DomMatrix skewY([num sy]) native;
+
+  Float32List toFloat32Array() native;
+
+  Float64List toFloat64Array() native;
+
+  DomPoint transformPoint([Map point]) {
+    if (point != null) {
+      var point_1 = convertDartToNative_Dictionary(point);
+      return _transformPoint_1(point_1);
+    }
+    return _transformPoint_2();
+  }
+
+  @JSName('transformPoint')
+  DomPoint _transformPoint_1(point) native;
+  @JSName('transformPoint')
+  DomPoint _transformPoint_2() native;
+
+  DomMatrix translate([num tx, num ty, num tz]) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("DOMParser")
+class DomParser extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DomParser._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DomParser() {
+    return DomParser._create_1();
+  }
+  static DomParser _create_1() => JS('DomParser', 'new DOMParser()');
+
+  Document parseFromString(String str, String type) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("DOMPoint")
+class DomPoint extends DomPointReadOnly {
+  // To suppress missing implicit constructor warnings.
+  factory DomPoint._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DomPoint([num x, num y, num z, num w]) {
+    if (w != null) {
+      return DomPoint._create_1(x, y, z, w);
+    }
+    if (z != null) {
+      return DomPoint._create_2(x, y, z);
+    }
+    if (y != null) {
+      return DomPoint._create_3(x, y);
+    }
+    if (x != null) {
+      return DomPoint._create_4(x);
+    }
+    return DomPoint._create_5();
+  }
+  static DomPoint _create_1(x, y, z, w) =>
+      JS('DomPoint', 'new DOMPoint(#,#,#,#)', x, y, z, w);
+  static DomPoint _create_2(x, y, z) =>
+      JS('DomPoint', 'new DOMPoint(#,#,#)', x, y, z);
+  static DomPoint _create_3(x, y) => JS('DomPoint', 'new DOMPoint(#,#)', x, y);
+  static DomPoint _create_4(x) => JS('DomPoint', 'new DOMPoint(#)', x);
+  static DomPoint _create_5() => JS('DomPoint', 'new DOMPoint()');
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      JS('bool', '!!(window.DOMPoint) || !!(window.WebKitPoint)');
+
+  // Shadowing definition.
+  num get w => JS("num", "#.w", this);
+
+  set w(num value) {
+    JS("void", "#.w = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get x => JS("num", "#.x", this);
+
+  set x(num value) {
+    JS("void", "#.x = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get y => JS("num", "#.y", this);
+
+  set y(num value) {
+    JS("void", "#.y = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get z => JS("num", "#.z", this);
+
+  set z(num value) {
+    JS("void", "#.z = #", this, value);
+  }
+
+  static DomPoint fromPoint([Map other]) {
+    if (other != null) {
+      var other_1 = convertDartToNative_Dictionary(other);
+      return _fromPoint_1(other_1);
+    }
+    return _fromPoint_2();
+  }
+
+  @JSName('fromPoint')
+  static DomPoint _fromPoint_1(other) native;
+  @JSName('fromPoint')
+  static DomPoint _fromPoint_2() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("DOMPointReadOnly")
+class DomPointReadOnly extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DomPointReadOnly._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DomPointReadOnly([num x, num y, num z, num w]) {
+    if (w != null) {
+      return DomPointReadOnly._create_1(x, y, z, w);
+    }
+    if (z != null) {
+      return DomPointReadOnly._create_2(x, y, z);
+    }
+    if (y != null) {
+      return DomPointReadOnly._create_3(x, y);
+    }
+    if (x != null) {
+      return DomPointReadOnly._create_4(x);
+    }
+    return DomPointReadOnly._create_5();
+  }
+  static DomPointReadOnly _create_1(x, y, z, w) =>
+      JS('DomPointReadOnly', 'new DOMPointReadOnly(#,#,#,#)', x, y, z, w);
+  static DomPointReadOnly _create_2(x, y, z) =>
+      JS('DomPointReadOnly', 'new DOMPointReadOnly(#,#,#)', x, y, z);
+  static DomPointReadOnly _create_3(x, y) =>
+      JS('DomPointReadOnly', 'new DOMPointReadOnly(#,#)', x, y);
+  static DomPointReadOnly _create_4(x) =>
+      JS('DomPointReadOnly', 'new DOMPointReadOnly(#)', x);
+  static DomPointReadOnly _create_5() =>
+      JS('DomPointReadOnly', 'new DOMPointReadOnly()');
+
+  num get w => JS("num", "#.w", this);
+
+  num get x => JS("num", "#.x", this);
+
+  num get y => JS("num", "#.y", this);
+
+  num get z => JS("num", "#.z", this);
+
+  static DomPointReadOnly fromPoint([Map other]) {
+    if (other != null) {
+      var other_1 = convertDartToNative_Dictionary(other);
+      return _fromPoint_1(other_1);
+    }
+    return _fromPoint_2();
+  }
+
+  @JSName('fromPoint')
+  static DomPointReadOnly _fromPoint_1(other) native;
+  @JSName('fromPoint')
+  static DomPointReadOnly _fromPoint_2() native;
+
+  DomPoint matrixTransform([Map matrix]) {
+    if (matrix != null) {
+      var matrix_1 = convertDartToNative_Dictionary(matrix);
+      return _matrixTransform_1(matrix_1);
+    }
+    return _matrixTransform_2();
+  }
+
+  @JSName('matrixTransform')
+  DomPoint _matrixTransform_1(matrix) native;
+  @JSName('matrixTransform')
+  DomPoint _matrixTransform_2() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("DOMQuad")
+class DomQuad extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DomQuad._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DomQuad([Map p1, Map p2, Map p3, Map p4]) {
+    if (p4 != null) {
+      var p1_1 = convertDartToNative_Dictionary(p1);
+      var p2_2 = convertDartToNative_Dictionary(p2);
+      var p3_3 = convertDartToNative_Dictionary(p3);
+      var p4_4 = convertDartToNative_Dictionary(p4);
+      return DomQuad._create_1(p1_1, p2_2, p3_3, p4_4);
+    }
+    if (p3 != null) {
+      var p1_1 = convertDartToNative_Dictionary(p1);
+      var p2_2 = convertDartToNative_Dictionary(p2);
+      var p3_3 = convertDartToNative_Dictionary(p3);
+      return DomQuad._create_2(p1_1, p2_2, p3_3);
+    }
+    if (p2 != null) {
+      var p1_1 = convertDartToNative_Dictionary(p1);
+      var p2_2 = convertDartToNative_Dictionary(p2);
+      return DomQuad._create_3(p1_1, p2_2);
+    }
+    if (p1 != null) {
+      var p1_1 = convertDartToNative_Dictionary(p1);
+      return DomQuad._create_4(p1_1);
+    }
+    return DomQuad._create_5();
+  }
+  static DomQuad _create_1(p1, p2, p3, p4) =>
+      JS('DomQuad', 'new DOMQuad(#,#,#,#)', p1, p2, p3, p4);
+  static DomQuad _create_2(p1, p2, p3) =>
+      JS('DomQuad', 'new DOMQuad(#,#,#)', p1, p2, p3);
+  static DomQuad _create_3(p1, p2) => JS('DomQuad', 'new DOMQuad(#,#)', p1, p2);
+  static DomQuad _create_4(p1) => JS('DomQuad', 'new DOMQuad(#)', p1);
+  static DomQuad _create_5() => JS('DomQuad', 'new DOMQuad()');
+
+  final DomPoint p1;
+
+  final DomPoint p2;
+
+  final DomPoint p3;
+
+  final DomPoint p4;
+
+  static DomQuad fromQuad([Map other]) {
+    if (other != null) {
+      var other_1 = convertDartToNative_Dictionary(other);
+      return _fromQuad_1(other_1);
+    }
+    return _fromQuad_2();
+  }
+
+  @JSName('fromQuad')
+  static DomQuad _fromQuad_1(other) native;
+  @JSName('fromQuad')
+  static DomQuad _fromQuad_2() native;
+
+  static DomQuad fromRect([Map other]) {
+    if (other != null) {
+      var other_1 = convertDartToNative_Dictionary(other);
+      return _fromRect_1(other_1);
+    }
+    return _fromRect_2();
+  }
+
+  @JSName('fromRect')
+  static DomQuad _fromRect_1(other) native;
+  @JSName('fromRect')
+  static DomQuad _fromRect_2() native;
+
+  Rectangle getBounds() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("ClientRectList,DOMRectList")
+class DomRectList extends Interceptor
+    with ListMixin<Rectangle>, ImmutableListMixin<Rectangle>
+    implements List<Rectangle>, JavaScriptIndexingBehavior<Rectangle> {
+  // To suppress missing implicit constructor warnings.
+  factory DomRectList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  Rectangle operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return JS("Rectangle", "#[#]", this, index);
+  }
+
+  void operator []=(int index, Rectangle value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<Rectangle> mixins.
+  // Rectangle is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  Rectangle get first {
+    if (this.length > 0) {
+      return JS('Rectangle', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  Rectangle get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('Rectangle', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  Rectangle get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('Rectangle', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  Rectangle elementAt(int index) => this[index];
+  // -- end List<Rectangle> mixins.
+
+  Rectangle item(int index) native;
+}
+// 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.
+
+@Native("DOMRectReadOnly")
+class DomRectReadOnly extends Interceptor implements Rectangle {
+  // NOTE! All code below should be common with RectangleBase.
+  String toString() {
+    return 'Rectangle ($left, $top) $width x $height';
+  }
+
+  bool operator ==(other) {
+    if (other is! Rectangle) return false;
+    return left == other.left &&
+        top == other.top &&
+        width == other.width &&
+        height == other.height;
+  }
+
+  int get hashCode => _JenkinsSmiHash.hash4(
+      left.hashCode, top.hashCode, width.hashCode, height.hashCode);
+
+  /**
+   * Computes the intersection of `this` and [other].
+   *
+   * The intersection of two axis-aligned rectangles, if any, is always another
+   * axis-aligned rectangle.
+   *
+   * Returns the intersection of this and `other`, or null if they don't
+   * intersect.
+   */
+  Rectangle intersection(Rectangle other) {
+    var x0 = max(left, other.left);
+    var x1 = min(left + width, other.left + other.width);
+
+    if (x0 <= x1) {
+      var y0 = max(top, other.top);
+      var y1 = min(top + height, other.top + other.height);
+
+      if (y0 <= y1) {
+        return new Rectangle(x0, y0, x1 - x0, y1 - y0);
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Returns true if `this` intersects [other].
+   */
+  bool intersects(Rectangle<num> other) {
+    return (left <= other.left + other.width &&
+        other.left <= left + width &&
+        top <= other.top + other.height &&
+        other.top <= top + height);
+  }
+
+  /**
+   * Returns a new rectangle which completely contains `this` and [other].
+   */
+  Rectangle boundingBox(Rectangle other) {
+    var right = max(this.left + this.width, other.left + other.width);
+    var bottom = max(this.top + this.height, other.top + other.height);
+
+    var left = min(this.left, other.left);
+    var top = min(this.top, other.top);
+
+    return new Rectangle(left, top, right - left, bottom - top);
+  }
+
+  /**
+   * Tests whether `this` entirely contains [another].
+   */
+  bool containsRectangle(Rectangle<num> another) {
+    return left <= another.left &&
+        left + width >= another.left + another.width &&
+        top <= another.top &&
+        top + height >= another.top + another.height;
+  }
+
+  /**
+   * Tests whether [another] is inside or along the edges of `this`.
+   */
+  bool containsPoint(Point<num> another) {
+    return another.x >= left &&
+        another.x <= left + width &&
+        another.y >= top &&
+        another.y <= top + height;
+  }
+
+  Point get topLeft => new Point(this.left, this.top);
+  Point get topRight => new Point(this.left + this.width, this.top);
+  Point get bottomRight =>
+      new Point(this.left + this.width, this.top + this.height);
+  Point get bottomLeft => new Point(this.left, this.top + this.height);
+
+  // To suppress missing implicit constructor warnings.
+  factory DomRectReadOnly._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DomRectReadOnly([num x, num y, num width, num height]) {
+    if (height != null) {
+      return DomRectReadOnly._create_1(x, y, width, height);
+    }
+    if (width != null) {
+      return DomRectReadOnly._create_2(x, y, width);
+    }
+    if (y != null) {
+      return DomRectReadOnly._create_3(x, y);
+    }
+    if (x != null) {
+      return DomRectReadOnly._create_4(x);
+    }
+    return DomRectReadOnly._create_5();
+  }
+  static DomRectReadOnly _create_1(x, y, width, height) => JS(
+      'DomRectReadOnly', 'new DOMRectReadOnly(#,#,#,#)', x, y, width, height);
+  static DomRectReadOnly _create_2(x, y, width) =>
+      JS('DomRectReadOnly', 'new DOMRectReadOnly(#,#,#)', x, y, width);
+  static DomRectReadOnly _create_3(x, y) =>
+      JS('DomRectReadOnly', 'new DOMRectReadOnly(#,#)', x, y);
+  static DomRectReadOnly _create_4(x) =>
+      JS('DomRectReadOnly', 'new DOMRectReadOnly(#)', x);
+  static DomRectReadOnly _create_5() =>
+      JS('DomRectReadOnly', 'new DOMRectReadOnly()');
+
+  num get bottom => JS("num", "#.bottom", this);
+
+  num get height => JS("num", "#.height", this);
+
+  num get left => JS("num", "#.left", this);
+
+  num get right => JS("num", "#.right", this);
+
+  num get top => JS("num", "#.top", this);
+
+  num get width => JS("num", "#.width", this);
+
+  num get x => JS("num", "#.x", this);
+
+  num get y => JS("num", "#.y", this);
+
+  static DomRectReadOnly fromRect([Map other]) {
+    if (other != null) {
+      var other_1 = convertDartToNative_Dictionary(other);
+      return _fromRect_1(other_1);
+    }
+    return _fromRect_2();
+  }
+
+  @JSName('fromRect')
+  static DomRectReadOnly _fromRect_1(other) native;
+  @JSName('fromRect')
+  static DomRectReadOnly _fromRect_2() native;
+}
+
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("DOMStringList")
+class DomStringList extends Interceptor
+    with ListMixin<String>, ImmutableListMixin<String>
+    implements JavaScriptIndexingBehavior<String>, List<String> {
+  // To suppress missing implicit constructor warnings.
+  factory DomStringList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  String operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return JS("String", "#[#]", this, index);
+  }
+
+  void operator []=(int index, String value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<String> mixins.
+  // String is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  String get first {
+    if (this.length > 0) {
+      return JS('String', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  String get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('String', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  String get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('String', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  String elementAt(int index) => this[index];
+  // -- end List<String> mixins.
+
+  String item(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("DOMStringMap")
+class DomStringMap extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DomStringMap._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  void __delete__(String name) native;
+
+  void __setter__(String name, String value) native;
+
+  String item(String name) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("DOMTokenList")
+class DomTokenList extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DomTokenList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int length;
+
+  String value;
+
+  void add(String tokens) native;
+
+  bool contains(String token) native;
+
+  String item(int index) native;
+
+  void remove(String tokens) native;
+
+  void replace(String token, String newToken) native;
+
+  bool supports(String token) native;
+
+  bool toggle(String token, [bool force]) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class _ChildrenElementList extends ListBase<Element>
+    implements NodeListWrapper {
+  // Raw Element.
+  final Element _element;
+  final HtmlCollection _childElements;
+
+  _ChildrenElementList._wrap(Element element)
+      : _childElements = element._children,
+        _element = element;
+
+  bool contains(Object element) => _childElements.contains(element);
+
+  bool get isEmpty {
+    return _element._firstElementChild == null;
+  }
+
+  int get length {
+    return _childElements.length;
+  }
+
+  Element operator [](int index) {
+    return _childElements[index];
+  }
+
+  void operator []=(int index, Element value) {
+    _element._replaceChild(value, _childElements[index]);
+  }
+
+  set length(int newLength) {
+    // TODO(jacobr): remove children when length is reduced.
+    throw new UnsupportedError('Cannot resize element lists');
+  }
+
+  Element add(Element value) {
+    _element.append(value);
+    return value;
+  }
+
+  Iterator<Element> get iterator => toList().iterator;
+
+  void addAll(Iterable<Element> iterable) {
+    if (iterable is _ChildNodeListLazy) {
+      iterable = new List.from(iterable);
+    }
+
+    for (Element element in iterable) {
+      _element.append(element);
+    }
+  }
+
+  void sort([int compare(Element a, Element b)]) {
+    throw new UnsupportedError('Cannot sort element lists');
+  }
+
+  void shuffle([Random random]) {
+    throw new UnsupportedError('Cannot shuffle element lists');
+  }
+
+  void removeWhere(bool test(Element element)) {
+    _filter(test, false);
+  }
+
+  void retainWhere(bool test(Element element)) {
+    _filter(test, true);
+  }
+
+  void _filter(bool test(Element element), bool retainMatching) {
+    var removed;
+    if (retainMatching) {
+      removed = _element.children.where((e) => !test(e));
+    } else {
+      removed = _element.children.where(test);
+    }
+    for (var e in removed) e.remove();
+  }
+
+  void fillRange(int start, int end, [Element fillValue]) {
+    throw new UnimplementedError();
+  }
+
+  void replaceRange(int start, int end, Iterable<Element> iterable) {
+    throw new UnimplementedError();
+  }
+
+  void removeRange(int start, int end) {
+    throw new UnimplementedError();
+  }
+
+  void setRange(int start, int end, Iterable<Element> iterable,
+      [int skipCount = 0]) {
+    throw new UnimplementedError();
+  }
+
+  bool remove(Object object) {
+    if (object is Element) {
+      Element element = object;
+      if (identical(element.parentNode, _element)) {
+        _element._removeChild(element);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  void insert(int index, Element element) {
+    if (index < 0 || index > length) {
+      throw new RangeError.range(index, 0, length);
+    }
+    if (index == length) {
+      _element.append(element);
+    } else {
+      _element.insertBefore(element, this[index]);
+    }
+  }
+
+  void setAll(int index, Iterable<Element> iterable) {
+    throw new UnimplementedError();
+  }
+
+  void clear() {
+    _element._clearChildren();
+  }
+
+  Element removeAt(int index) {
+    final result = this[index];
+    if (result != null) {
+      _element._removeChild(result);
+    }
+    return result;
+  }
+
+  Element removeLast() {
+    final result = this.last;
+    if (result != null) {
+      _element._removeChild(result);
+    }
+    return result;
+  }
+
+  Element get first {
+    Element result = _element._firstElementChild;
+    if (result == null) throw new StateError("No elements");
+    return result;
+  }
+
+  Element get last {
+    Element result = _element._lastElementChild;
+    if (result == null) throw new StateError("No elements");
+    return result;
+  }
+
+  Element get single {
+    if (length > 1) throw new StateError("More than one element");
+    return first;
+  }
+
+  List<Node> get rawList => _childElements;
+}
+
+/**
+ * An immutable list containing HTML elements. This list contains some
+ * additional methods when compared to regular lists for ease of CSS
+ * manipulation on a group of elements.
+ */
+abstract class ElementList<T extends Element> extends ListBase<T> {
+  /**
+   * The union of all CSS classes applied to the elements in this list.
+   *
+   * This set makes it easy to add, remove or toggle (add if not present, remove
+   * if present) the classes applied to a collection of elements.
+   *
+   *     htmlList.classes.add('selected');
+   *     htmlList.classes.toggle('isOnline');
+   *     htmlList.classes.remove('selected');
+   */
+  CssClassSet get classes;
+
+  /** Replace the classes with `value` for every element in this list. */
+  set classes(Iterable<String> value);
+
+  /**
+   * Access the union of all [CssStyleDeclaration]s that are associated with an
+   * [ElementList].
+   *
+   * Grouping the style objects all together provides easy editing of specific
+   * properties of a collection of elements. Setting a specific property value
+   * will set that property in all [Element]s in the [ElementList]. Getting a
+   * specific property value will return the value of the property of the first
+   * element in the [ElementList].
+   */
+  CssStyleDeclarationBase get style;
+
+  /**
+   * Access dimensions and position of the Elements in this list.
+   *
+   * Setting the height or width properties will set the height or width
+   * property for all elements in the list. This returns a rectangle with the
+   * dimensions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing
+   * property. Getting the height or width returns the height or width of the
+   * first Element in this list.
+   *
+   * Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not.
+   */
+  CssRect get contentEdge;
+
+  /**
+   * Access dimensions and position of the first Element's content + padding box
+   * in this list.
+   *
+   * This returns a rectangle with the dimensions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's `innerHeight` value for an element. This
+   * is also a rectangle equalling the dimensions of clientHeight and
+   * clientWidth.
+   */
+  CssRect get paddingEdge;
+
+  /**
+   * Access dimensions and position of the first Element's content + padding +
+   * border box in this list.
+   *
+   * This returns a rectangle with the dimensions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's `outerHeight` value for an element.
+   */
+  CssRect get borderEdge;
+
+  /**
+   * Access dimensions and position of the first Element's content + padding +
+   * border + margin box in this list.
+   *
+   * This returns a rectangle with the dimensions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's `outerHeight` value for an element.
+   */
+  CssRect get marginEdge;
+
+  /// Stream of `abort` events handled by this [Element].
+  ElementStream<Event> get onAbort;
+
+  /// Stream of `beforecopy` events handled by this [Element].
+  ElementStream<Event> get onBeforeCopy;
+
+  /// Stream of `beforecut` events handled by this [Element].
+  ElementStream<Event> get onBeforeCut;
+
+  /// Stream of `beforepaste` events handled by this [Element].
+  ElementStream<Event> get onBeforePaste;
+
+  /// Stream of `blur` events handled by this [Element].
+  ElementStream<Event> get onBlur;
+
+  ElementStream<Event> get onCanPlay;
+
+  ElementStream<Event> get onCanPlayThrough;
+
+  /// Stream of `change` events handled by this [Element].
+  ElementStream<Event> get onChange;
+
+  /// Stream of `click` events handled by this [Element].
+  ElementStream<MouseEvent> get onClick;
+
+  /// Stream of `contextmenu` events handled by this [Element].
+  ElementStream<MouseEvent> get onContextMenu;
+
+  /// Stream of `copy` events handled by this [Element].
+  ElementStream<ClipboardEvent> get onCopy;
+
+  /// Stream of `cut` events handled by this [Element].
+  ElementStream<ClipboardEvent> get onCut;
+
+  /// Stream of `doubleclick` events handled by this [Element].
+  @DomName('Element.ondblclick')
+  ElementStream<Event> get onDoubleClick;
+
+  /**
+   * A stream of `drag` events fired when this element currently being dragged.
+   *
+   * A `drag` event is added to this stream as soon as the drag begins.
+   * A `drag` event is also added to this stream at intervals while the drag
+   * operation is still ongoing.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDrag;
+
+  /**
+   * A stream of `dragend` events fired when this element completes a drag
+   * operation.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDragEnd;
+
+  /**
+   * A stream of `dragenter` events fired when a dragged object is first dragged
+   * over this element.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDragEnter;
+
+  /**
+   * A stream of `dragleave` events fired when an object being dragged over this
+   * element leaves this element's target area.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDragLeave;
+
+  /**
+   * A stream of `dragover` events fired when a dragged object is currently
+   * being dragged over this element.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDragOver;
+
+  /**
+   * A stream of `dragstart` events fired when this element starts being
+   * dragged.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDragStart;
+
+  /**
+   * A stream of `drop` events fired when a dragged object is dropped on this
+   * element.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDrop;
+
+  ElementStream<Event> get onDurationChange;
+
+  ElementStream<Event> get onEmptied;
+
+  ElementStream<Event> get onEnded;
+
+  /// Stream of `error` events handled by this [Element].
+  ElementStream<Event> get onError;
+
+  /// Stream of `focus` events handled by this [Element].
+  ElementStream<Event> get onFocus;
+
+  /// Stream of `input` events handled by this [Element].
+  ElementStream<Event> get onInput;
+
+  /// Stream of `invalid` events handled by this [Element].
+  ElementStream<Event> get onInvalid;
+
+  /// Stream of `keydown` events handled by this [Element].
+  ElementStream<KeyboardEvent> get onKeyDown;
+
+  /// Stream of `keypress` events handled by this [Element].
+  ElementStream<KeyboardEvent> get onKeyPress;
+
+  /// Stream of `keyup` events handled by this [Element].
+  ElementStream<KeyboardEvent> get onKeyUp;
+
+  /// Stream of `load` events handled by this [Element].
+  ElementStream<Event> get onLoad;
+
+  ElementStream<Event> get onLoadedData;
+
+  ElementStream<Event> get onLoadedMetadata;
+
+  /// Stream of `mousedown` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseDown;
+
+  /// Stream of `mouseenter` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseEnter;
+
+  /// Stream of `mouseleave` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseLeave;
+
+  /// Stream of `mousemove` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseMove;
+
+  /// Stream of `mouseout` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseOut;
+
+  /// Stream of `mouseover` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseOver;
+
+  /// Stream of `mouseup` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseUp;
+
+  /// Stream of `mousewheel` events handled by this [Element].
+  ElementStream<WheelEvent> get onMouseWheel;
+
+  /// Stream of `paste` events handled by this [Element].
+  ElementStream<ClipboardEvent> get onPaste;
+
+  ElementStream<Event> get onPause;
+
+  ElementStream<Event> get onPlay;
+
+  ElementStream<Event> get onPlaying;
+
+  ElementStream<Event> get onRateChange;
+
+  /// Stream of `reset` events handled by this [Element].
+  ElementStream<Event> get onReset;
+
+  ElementStream<Event> get onResize;
+
+  /// Stream of `scroll` events handled by this [Element].
+  ElementStream<Event> get onScroll;
+
+  /// Stream of `search` events handled by this [Element].
+  ElementStream<Event> get onSearch;
+
+  ElementStream<Event> get onSeeked;
+
+  ElementStream<Event> get onSeeking;
+
+  /// Stream of `select` events handled by this [Element].
+  ElementStream<Event> get onSelect;
+
+  /// Stream of `selectstart` events handled by this [Element].
+  ElementStream<Event> get onSelectStart;
+
+  ElementStream<Event> get onStalled;
+
+  /// Stream of `submit` events handled by this [Element].
+  ElementStream<Event> get onSubmit;
+
+  ElementStream<Event> get onSuspend;
+
+  ElementStream<Event> get onTimeUpdate;
+
+  /// Stream of `touchcancel` events handled by this [Element].
+  ElementStream<TouchEvent> get onTouchCancel;
+
+  /// Stream of `touchend` events handled by this [Element].
+  ElementStream<TouchEvent> get onTouchEnd;
+
+  /// Stream of `touchenter` events handled by this [Element].
+  ElementStream<TouchEvent> get onTouchEnter;
+
+  /// Stream of `touchleave` events handled by this [Element].
+  ElementStream<TouchEvent> get onTouchLeave;
+
+  /// Stream of `touchmove` events handled by this [Element].
+  ElementStream<TouchEvent> get onTouchMove;
+
+  /// Stream of `touchstart` events handled by this [Element].
+  ElementStream<TouchEvent> get onTouchStart;
+
+  /// Stream of `transitionend` events handled by this [Element].
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  ElementStream<TransitionEvent> get onTransitionEnd;
+
+  ElementStream<Event> get onVolumeChange;
+
+  ElementStream<Event> get onWaiting;
+
+  /// Stream of `fullscreenchange` events handled by this [Element].
+  ElementStream<Event> get onFullscreenChange;
+
+  /// Stream of `fullscreenerror` events handled by this [Element].
+  ElementStream<Event> get onFullscreenError;
+
+  ElementStream<WheelEvent> get onWheel;
+}
+
+// Wrapper over an immutable NodeList to make it implement ElementList.
+//
+// Clients are {`Document`, `DocumentFragment`}.`querySelectorAll` which are
+// declared to return `ElementList`.  This provides all the static analysis
+// benefit so there is no need for this class have a constrained type parameter.
+//
+class _FrozenElementList<E extends Element> extends ListBase<E>
+    implements ElementList<E>, NodeListWrapper {
+  final List<Node> _nodeList;
+
+  _FrozenElementList._wrap(this._nodeList) {
+    assert(this._nodeList.every((element) => element is E),
+        "Query expects only HTML elements of type $E but found ${this._nodeList.firstWhere((e) => e is! E)}");
+  }
+
+  int get length => _nodeList.length;
+
+  E operator [](int index) => _nodeList[index];
+
+  void operator []=(int index, E value) {
+    throw new UnsupportedError('Cannot modify list');
+  }
+
+  set length(int newLength) {
+    throw new UnsupportedError('Cannot modify list');
+  }
+
+  void sort([Comparator<E> compare]) {
+    throw new UnsupportedError('Cannot sort list');
+  }
+
+  void shuffle([Random random]) {
+    throw new UnsupportedError('Cannot shuffle list');
+  }
+
+  E get first => _nodeList.first;
+
+  E get last => _nodeList.last;
+
+  E get single => _nodeList.single;
+
+  CssClassSet get classes => new _MultiElementCssClassSet(this);
+
+  CssStyleDeclarationBase get style => new _CssStyleDeclarationSet(this);
+
+  set classes(Iterable<String> value) {
+    // TODO(sra): This might be faster for Sets:
+    //
+    //     new _MultiElementCssClassSet(this).writeClasses(value)
+    //
+    // as the code below converts the Iterable[value] to a string multiple
+    // times.  Maybe compute the string and set className here.
+    forEach((e) => e.classes = value);
+  }
+
+  CssRect get contentEdge => new _ContentCssListRect(this);
+
+  CssRect get paddingEdge => this.first.paddingEdge;
+
+  CssRect get borderEdge => this.first.borderEdge;
+
+  CssRect get marginEdge => this.first.marginEdge;
+
+  List<Node> get rawList => _nodeList;
+
+  /// Stream of `abort` events handled by this [Element].
+  ElementStream<Event> get onAbort => Element.abortEvent._forElementList(this);
+
+  /// Stream of `beforecopy` events handled by this [Element].
+  ElementStream<Event> get onBeforeCopy =>
+      Element.beforeCopyEvent._forElementList(this);
+
+  /// Stream of `beforecut` events handled by this [Element].
+  ElementStream<Event> get onBeforeCut =>
+      Element.beforeCutEvent._forElementList(this);
+
+  /// Stream of `beforepaste` events handled by this [Element].
+  ElementStream<Event> get onBeforePaste =>
+      Element.beforePasteEvent._forElementList(this);
+
+  /// Stream of `blur` events handled by this [Element].
+  ElementStream<Event> get onBlur => Element.blurEvent._forElementList(this);
+
+  ElementStream<Event> get onCanPlay =>
+      Element.canPlayEvent._forElementList(this);
+
+  ElementStream<Event> get onCanPlayThrough =>
+      Element.canPlayThroughEvent._forElementList(this);
+
+  /// Stream of `change` events handled by this [Element].
+  ElementStream<Event> get onChange =>
+      Element.changeEvent._forElementList(this);
+
+  /// Stream of `click` events handled by this [Element].
+  ElementStream<MouseEvent> get onClick =>
+      Element.clickEvent._forElementList(this);
+
+  /// Stream of `contextmenu` events handled by this [Element].
+  ElementStream<MouseEvent> get onContextMenu =>
+      Element.contextMenuEvent._forElementList(this);
+
+  /// Stream of `copy` events handled by this [Element].
+  ElementStream<ClipboardEvent> get onCopy =>
+      Element.copyEvent._forElementList(this);
+
+  /// Stream of `cut` events handled by this [Element].
+  ElementStream<ClipboardEvent> get onCut =>
+      Element.cutEvent._forElementList(this);
+
+  /// Stream of `doubleclick` events handled by this [Element].
+  @DomName('Element.ondblclick')
+  ElementStream<Event> get onDoubleClick =>
+      Element.doubleClickEvent._forElementList(this);
+
+  /**
+   * A stream of `drag` events fired when this element currently being dragged.
+   *
+   * A `drag` event is added to this stream as soon as the drag begins.
+   * A `drag` event is also added to this stream at intervals while the drag
+   * operation is still ongoing.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDrag =>
+      Element.dragEvent._forElementList(this);
+
+  /**
+   * A stream of `dragend` events fired when this element completes a drag
+   * operation.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDragEnd =>
+      Element.dragEndEvent._forElementList(this);
+
+  /**
+   * A stream of `dragenter` events fired when a dragged object is first dragged
+   * over this element.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDragEnter =>
+      Element.dragEnterEvent._forElementList(this);
+
+  /**
+   * A stream of `dragleave` events fired when an object being dragged over this
+   * element leaves this element's target area.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDragLeave =>
+      Element.dragLeaveEvent._forElementList(this);
+
+  /**
+   * A stream of `dragover` events fired when a dragged object is currently
+   * being dragged over this element.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDragOver =>
+      Element.dragOverEvent._forElementList(this);
+
+  /**
+   * A stream of `dragstart` events fired when this element starts being
+   * dragged.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDragStart =>
+      Element.dragStartEvent._forElementList(this);
+
+  /**
+   * A stream of `drop` events fired when a dragged object is dropped on this
+   * element.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDrop =>
+      Element.dropEvent._forElementList(this);
+
+  ElementStream<Event> get onDurationChange =>
+      Element.durationChangeEvent._forElementList(this);
+
+  ElementStream<Event> get onEmptied =>
+      Element.emptiedEvent._forElementList(this);
+
+  ElementStream<Event> get onEnded => Element.endedEvent._forElementList(this);
+
+  /// Stream of `error` events handled by this [Element].
+  ElementStream<Event> get onError => Element.errorEvent._forElementList(this);
+
+  /// Stream of `focus` events handled by this [Element].
+  ElementStream<Event> get onFocus => Element.focusEvent._forElementList(this);
+
+  /// Stream of `input` events handled by this [Element].
+  ElementStream<Event> get onInput => Element.inputEvent._forElementList(this);
+
+  /// Stream of `invalid` events handled by this [Element].
+  ElementStream<Event> get onInvalid =>
+      Element.invalidEvent._forElementList(this);
+
+  /// Stream of `keydown` events handled by this [Element].
+  ElementStream<KeyboardEvent> get onKeyDown =>
+      Element.keyDownEvent._forElementList(this);
+
+  /// Stream of `keypress` events handled by this [Element].
+  ElementStream<KeyboardEvent> get onKeyPress =>
+      Element.keyPressEvent._forElementList(this);
+
+  /// Stream of `keyup` events handled by this [Element].
+  ElementStream<KeyboardEvent> get onKeyUp =>
+      Element.keyUpEvent._forElementList(this);
+
+  /// Stream of `load` events handled by this [Element].
+  ElementStream<Event> get onLoad => Element.loadEvent._forElementList(this);
+
+  ElementStream<Event> get onLoadedData =>
+      Element.loadedDataEvent._forElementList(this);
+
+  ElementStream<Event> get onLoadedMetadata =>
+      Element.loadedMetadataEvent._forElementList(this);
+
+  /// Stream of `mousedown` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseDown =>
+      Element.mouseDownEvent._forElementList(this);
+
+  /// Stream of `mouseenter` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseEnter =>
+      Element.mouseEnterEvent._forElementList(this);
+
+  /// Stream of `mouseleave` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseLeave =>
+      Element.mouseLeaveEvent._forElementList(this);
+
+  /// Stream of `mousemove` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseMove =>
+      Element.mouseMoveEvent._forElementList(this);
+
+  /// Stream of `mouseout` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseOut =>
+      Element.mouseOutEvent._forElementList(this);
+
+  /// Stream of `mouseover` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseOver =>
+      Element.mouseOverEvent._forElementList(this);
+
+  /// Stream of `mouseup` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseUp =>
+      Element.mouseUpEvent._forElementList(this);
+
+  /// Stream of `mousewheel` events handled by this [Element].
+  ElementStream<WheelEvent> get onMouseWheel =>
+      Element.mouseWheelEvent._forElementList(this);
+
+  /// Stream of `paste` events handled by this [Element].
+  ElementStream<ClipboardEvent> get onPaste =>
+      Element.pasteEvent._forElementList(this);
+
+  ElementStream<Event> get onPause => Element.pauseEvent._forElementList(this);
+
+  ElementStream<Event> get onPlay => Element.playEvent._forElementList(this);
+
+  ElementStream<Event> get onPlaying =>
+      Element.playingEvent._forElementList(this);
+
+  ElementStream<Event> get onRateChange =>
+      Element.rateChangeEvent._forElementList(this);
+
+  /// Stream of `reset` events handled by this [Element].
+  ElementStream<Event> get onReset => Element.resetEvent._forElementList(this);
+
+  ElementStream<Event> get onResize =>
+      Element.resizeEvent._forElementList(this);
+
+  /// Stream of `scroll` events handled by this [Element].
+  ElementStream<Event> get onScroll =>
+      Element.scrollEvent._forElementList(this);
+
+  /// Stream of `search` events handled by this [Element].
+  ElementStream<Event> get onSearch =>
+      Element.searchEvent._forElementList(this);
+
+  ElementStream<Event> get onSeeked =>
+      Element.seekedEvent._forElementList(this);
+
+  ElementStream<Event> get onSeeking =>
+      Element.seekingEvent._forElementList(this);
+
+  /// Stream of `select` events handled by this [Element].
+  ElementStream<Event> get onSelect =>
+      Element.selectEvent._forElementList(this);
+
+  /// Stream of `selectstart` events handled by this [Element].
+  ElementStream<Event> get onSelectStart =>
+      Element.selectStartEvent._forElementList(this);
+
+  ElementStream<Event> get onStalled =>
+      Element.stalledEvent._forElementList(this);
+
+  /// Stream of `submit` events handled by this [Element].
+  ElementStream<Event> get onSubmit =>
+      Element.submitEvent._forElementList(this);
+
+  ElementStream<Event> get onSuspend =>
+      Element.suspendEvent._forElementList(this);
+
+  ElementStream<Event> get onTimeUpdate =>
+      Element.timeUpdateEvent._forElementList(this);
+
+  /// Stream of `touchcancel` events handled by this [Element].
+  ElementStream<TouchEvent> get onTouchCancel =>
+      Element.touchCancelEvent._forElementList(this);
+
+  /// Stream of `touchend` events handled by this [Element].
+  ElementStream<TouchEvent> get onTouchEnd =>
+      Element.touchEndEvent._forElementList(this);
+
+  /// Stream of `touchenter` events handled by this [Element].
+  ElementStream<TouchEvent> get onTouchEnter =>
+      Element.touchEnterEvent._forElementList(this);
+
+  /// Stream of `touchleave` events handled by this [Element].
+  ElementStream<TouchEvent> get onTouchLeave =>
+      Element.touchLeaveEvent._forElementList(this);
+
+  /// Stream of `touchmove` events handled by this [Element].
+  ElementStream<TouchEvent> get onTouchMove =>
+      Element.touchMoveEvent._forElementList(this);
+
+  /// Stream of `touchstart` events handled by this [Element].
+  ElementStream<TouchEvent> get onTouchStart =>
+      Element.touchStartEvent._forElementList(this);
+
+  /// Stream of `transitionend` events handled by this [Element].
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  ElementStream<TransitionEvent> get onTransitionEnd =>
+      Element.transitionEndEvent._forElementList(this);
+
+  ElementStream<Event> get onVolumeChange =>
+      Element.volumeChangeEvent._forElementList(this);
+
+  ElementStream<Event> get onWaiting =>
+      Element.waitingEvent._forElementList(this);
+
+  /// Stream of `fullscreenchange` events handled by this [Element].
+  ElementStream<Event> get onFullscreenChange =>
+      Element.fullscreenChangeEvent._forElementList(this);
+
+  /// Stream of `fullscreenerror` events handled by this [Element].
+  ElementStream<Event> get onFullscreenError =>
+      Element.fullscreenErrorEvent._forElementList(this);
+
+  ElementStream<WheelEvent> get onWheel =>
+      Element.wheelEvent._forElementList(this);
+}
+
+/**
+ * An abstract class, which all HTML elements extend.
+ */
+@Native("Element")
+class Element extends Node
+    implements
+        NonDocumentTypeChildNode,
+        GlobalEventHandlers,
+        ParentNode,
+        ChildNode {
+  /**
+   * Creates an HTML element from a valid fragment of HTML.
+   *
+   *     var element = new Element.html('<div class="foo">content</div>');
+   *
+   * The HTML fragment should contain only one single root element, any
+   * leading or trailing text nodes will be removed.
+   *
+   * The HTML fragment is parsed as if it occurred within the context of a
+   * `<body>` tag, this means that special elements such as `<caption>` which
+   * must be parsed within the scope of a `<table>` element will be dropped. Use
+   * [createFragment] to parse contextual HTML fragments.
+   *
+   * Unless a validator is provided this will perform the default validation
+   * and remove all scriptable elements and attributes.
+   *
+   * See also:
+   *
+   * * [NodeValidator]
+   *
+   */
+  factory Element.html(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    var fragment = document.body.createFragment(html,
+        validator: validator, treeSanitizer: treeSanitizer);
+
+    return fragment.nodes.where((e) => e is Element).single;
+  }
+
+  /**
+   * Custom element creation constructor.
+   *
+   * This constructor is used by the DOM when a custom element has been
+   * created. It can only be invoked by subclasses of Element from
+   * that classes created constructor.
+   *
+   *     class CustomElement extends Element {
+   *       factory CustomElement() => new Element.tag('x-custom');
+   *
+   *       CustomElement.created() : super.created() {
+   *          // Perform any element initialization.
+   *       }
+   *     }
+   *     document.registerElement('x-custom', CustomElement);
+   */
+  Element.created() : super._created();
+
+  /**
+   * Creates the HTML element specified by the tag name.
+   *
+   * This is similar to [Document.createElement].
+   * [tag] should be a valid HTML tag name. If [tag] is an unknown tag then
+   * this will create an [UnknownElement].
+   *
+   *     var divElement = new Element.tag('div');
+   *     print(divElement is DivElement); // 'true'
+   *     var myElement = new Element.tag('unknownTag');
+   *     print(myElement is UnknownElement); // 'true'
+   *
+   * For standard elements it is better to use the element type constructors:
+   *
+   *     var element = new DivElement();
+   *
+   * It is better to use e.g `new CanvasElement()` because the type of the
+   * expression is `CanvasElement`, whereas the type of `Element.tag` is the
+   * less specific `Element`.
+   *
+   * See also:
+   *
+   * * [isTagSupported]
+   */
+  factory Element.tag(String tag, [String typeExtention]) =>
+      _ElementFactoryProvider.createElement_tag(tag, typeExtention);
+
+  /// Creates a new `<a>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('a')`.
+  factory Element.a() => new AnchorElement();
+
+  /// Creates a new `<article>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('article')`.
+  factory Element.article() => new Element.tag('article');
+
+  /// Creates a new `<aside>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('aside')`.
+  factory Element.aside() => new Element.tag('aside');
+
+  /// Creates a new `<audio>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('audio')`.
+  factory Element.audio() => new Element.tag('audio');
+
+  /// Creates a new `<br>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('br')`.
+  factory Element.br() => new BRElement();
+
+  /// Creates a new `<canvas>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('canvas')`.
+  factory Element.canvas() => new CanvasElement();
+
+  /// Creates a new `<div>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('div')`.
+  factory Element.div() => new DivElement();
+
+  /// Creates a new `<footer>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('footer')`.
+  factory Element.footer() => new Element.tag('footer');
+
+  /// Creates a new `<header>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('header')`.
+  factory Element.header() => new Element.tag('header');
+
+  /// Creates a new `<hr>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('hr')`.
+  factory Element.hr() => new Element.tag('hr');
+
+  /// Creates a new `<iframe>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('iframe')`.
+  factory Element.iframe() => new Element.tag('iframe');
+
+  /// Creates a new `<img>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('img')`.
+  factory Element.img() => new Element.tag('img');
+
+  /// Creates a new `<li>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('li')`.
+  factory Element.li() => new Element.tag('li');
+
+  /// Creates a new `<nav>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('nav')`.
+  factory Element.nav() => new Element.tag('nav');
+
+  /// Creates a new `<ol>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('ol')`.
+  factory Element.ol() => new Element.tag('ol');
+
+  /// Creates a new `<option>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('option')`.
+  factory Element.option() => new Element.tag('option');
+
+  /// Creates a new `<p>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('p')`.
+  factory Element.p() => new Element.tag('p');
+
+  /// Creates a new `<pre>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('pre')`.
+  factory Element.pre() => new Element.tag('pre');
+
+  /// Creates a new `<section>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('section')`.
+  factory Element.section() => new Element.tag('section');
+
+  /// Creates a new `<select>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('select')`.
+  factory Element.select() => new Element.tag('select');
+
+  /// Creates a new `<span>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('span')`.
+  factory Element.span() => new Element.tag('span');
+
+  /// Creates a new `<svg>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('svg')`.
+  factory Element.svg() => new Element.tag('svg');
+
+  /// Creates a new `<table>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('table')`.
+  factory Element.table() => new Element.tag('table');
+
+  /// Creates a new `<td>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('td')`.
+  factory Element.td() => new Element.tag('td');
+
+  /// Creates a new `<textarea>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('textarea')`.
+  factory Element.textarea() => new Element.tag('textarea');
+
+  /// Creates a new `<th>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('th')`.
+  factory Element.th() => new Element.tag('th');
+
+  /// Creates a new `<tr>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('tr')`.
+  factory Element.tr() => new Element.tag('tr');
+
+  /// Creates a new `<ul>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('ul')`.
+  factory Element.ul() => new Element.tag('ul');
+
+  /// Creates a new `<video>` element.
+  ///
+  /// This is equivalent to calling `new Element.tag('video')`.
+  factory Element.video() => new Element.tag('video');
+
+  /**
+   * All attributes on this element.
+   *
+   * Any modifications to the attribute map will automatically be applied to
+   * this element.
+   *
+   * This only includes attributes which are not in a namespace
+   * (such as 'xlink:href'), additional attributes can be accessed via
+   * [getNamespacedAttributes].
+   */
+  Map<String, String> get attributes => new _ElementAttributeMap(this);
+
+  set attributes(Map<String, String> value) {
+    Map<String, String> attributes = this.attributes;
+    attributes.clear();
+    for (String key in value.keys) {
+      attributes[key] = value[key];
+    }
+  }
+
+  @pragma('dart2js:tryInline')
+  String getAttribute(String name) {
+    // Protect [name] against string conversion to "null" or "undefined".
+    assert(name != null, 'Attribute name cannot be null');
+    return _getAttribute(name);
+  }
+
+  @pragma('dart2js:tryInline')
+  String getAttributeNS(String namespaceURI, String name) {
+    // Protect [name] against string conversion to "null" or "undefined".
+    // [namespaceURI] does not need protecting, both `null` and `undefined` map to `null`.
+    assert(name != null, 'Attribute name cannot be null');
+    return _getAttributeNS(namespaceURI, name);
+  }
+
+  @pragma('dart2js:tryInline')
+  bool hasAttribute(String name) {
+    // Protect [name] against string conversion to "null" or "undefined".
+    assert(name != null, 'Attribute name cannot be null');
+    return _hasAttribute(name);
+  }
+
+  @pragma('dart2js:tryInline')
+  bool hasAttributeNS(String namespaceURI, String name) {
+    // Protect [name] against string conversion to "null" or "undefined".
+    // [namespaceURI] does not need protecting, both `null` and `undefined` map to `null`.
+    assert(name != null, 'Attribute name cannot be null');
+    return _hasAttributeNS(namespaceURI, name);
+  }
+
+  @pragma('dart2js:tryInline')
+  void removeAttribute(String name) {
+    // Protect [name] against string conversion to "null" or "undefined".
+    assert(name != null, 'Attribute name cannot be null');
+    _removeAttribute(name);
+  }
+
+  @pragma('dart2js:tryInline')
+  void removeAttributeNS(String namespaceURI, String name) {
+    // Protect [name] against string conversion to "null" or "undefined".
+    assert(name != null, 'Attribute name cannot be null');
+    _removeAttributeNS(namespaceURI, name);
+  }
+
+  @pragma('dart2js:tryInline')
+  void setAttribute(String name, String value) {
+    // Protect [name] against string conversion to "null" or "undefined".
+    assert(name != null, 'Attribute name cannot be null');
+    // TODO(sra): assert(value != null, 'Attribute value cannot be null.');
+    _setAttribute(name, value);
+  }
+
+  @pragma('dart2js:tryInline')
+  void setAttributeNS(String namespaceURI, String name, String value) {
+    // Protect [name] against string conversion to "null" or "undefined".
+    assert(name != null, 'Attribute name cannot be null');
+    // TODO(sra): assert(value != null, 'Attribute value cannot be null.');
+    _setAttributeNS(namespaceURI, name, value);
+  }
+
+  /**
+   * List of the direct children of this element.
+   *
+   * This collection can be used to add and remove elements from the document.
+   *
+   *     var item = new DivElement();
+   *     item.text = 'Something';
+   *     document.body.children.add(item) // Item is now displayed on the page.
+   *     for (var element in document.body.children) {
+   *       element.style.background = 'red'; // Turns every child of body red.
+   *     }
+   */
+  List<Element> get children => new _ChildrenElementList._wrap(this);
+
+  set children(List<Element> value) {
+    // Copy list first since we don't want liveness during iteration.
+    var copy = value.toList();
+    var children = this.children;
+    children.clear();
+    children.addAll(copy);
+  }
+
+  /**
+   * Finds all descendent elements of this element that match the specified
+   * group of selectors.
+   *
+   * [selectors] should be a string using CSS selector syntax.
+   *
+   *     var items = element.querySelectorAll('.itemClassName');
+   *
+   * For details about CSS selector syntax, see the
+   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
+   */
+  ElementList<T> querySelectorAll<T extends Element>(String selectors) =>
+      new _FrozenElementList<T>._wrap(_querySelectorAll(selectors));
+
+  @JSName('setApplyScroll')
+  void _setApplyScroll(ScrollStateCallback scrollStateCallback,
+      String nativeScrollBehavior) native;
+
+  Future<ScrollState> setApplyScroll(String nativeScrollBehavior) {
+    var completer = new Completer<ScrollState>();
+    _setApplyScroll((value) {
+      completer.complete(value);
+    }, nativeScrollBehavior);
+    return completer.future;
+  }
+
+  @JSName('setDistributeScroll')
+  void _setDistributeScroll(ScrollStateCallback scrollStateCallback,
+      String nativeScrollBehavior) native;
+
+  Future<ScrollState> setDistributeScroll(String nativeScrollBehavior) {
+    var completer = new Completer<ScrollState>();
+    _setDistributeScroll((value) {
+      completer.complete(value);
+    }, nativeScrollBehavior);
+    return completer.future;
+  }
+
+  /**
+   * The set of CSS classes applied to this element.
+   *
+   * This set makes it easy to add, remove or toggle the classes applied to
+   * this element.
+   *
+   *     element.classes.add('selected');
+   *     element.classes.toggle('isOnline');
+   *     element.classes.remove('selected');
+   */
+  CssClassSet get classes => new _ElementCssClassSet(this);
+
+  set classes(Iterable<String> value) {
+    // TODO(sra): Do this without reading the classes in clear() and addAll(),
+    // or writing the classes in clear().
+    CssClassSet classSet = classes;
+    classSet.clear();
+    classSet.addAll(value);
+  }
+
+  /**
+   * Allows access to all custom data attributes (data-*) set on this element.
+   *
+   * The keys for the map must follow these rules:
+   *
+   * * The name must not begin with 'xml'.
+   * * The name cannot contain a semi-colon (';').
+   * * The name cannot contain any capital letters.
+   *
+   * Any keys from markup will be converted to camel-cased keys in the map.
+   *
+   * For example, HTML specified as:
+   *
+   *     <div data-my-random-value='value'></div>
+   *
+   * Would be accessed in Dart as:
+   *
+   *     var value = element.dataset['myRandomValue'];
+   *
+   * See also:
+   *
+   * * [Custom data
+   *   attributes](http://dev.w3.org/html5/spec-preview/global-attributes.html#custom-data-attribute)
+   */
+  Map<String, String> get dataset => new _DataAttributeMap(attributes);
+
+  set dataset(Map<String, String> value) {
+    final data = this.dataset;
+    data.clear();
+    for (String key in value.keys) {
+      data[key] = value[key];
+    }
+  }
+
+  /**
+   * Gets a map for manipulating the attributes of a particular namespace.
+   *
+   * This is primarily useful for SVG attributes such as xref:link.
+   */
+  Map<String, String> getNamespacedAttributes(String namespace) {
+    return new _NamespacedAttributeMap(this, namespace);
+  }
+
+  /**
+   * The set of all CSS values applied to this element, including inherited
+   * and default values.
+   *
+   * The computedStyle contains values that are inherited from other
+   * sources, such as parent elements or stylesheets. This differs from the
+   * [style] property, which contains only the values specified directly on this
+   * element.
+   *
+   * PseudoElement can be values such as `::after`, `::before`, `::marker`,
+   * `::line-marker`.
+   *
+   * See also:
+   *
+   * * [Cascade and Inheritance](https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/Cascade_and_inheritance)
+   *   from MDN.
+   * * [Pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements)
+   *   from MDN.
+   */
+  CssStyleDeclaration getComputedStyle([String pseudoElement]) {
+    if (pseudoElement == null) {
+      pseudoElement = '';
+    }
+    // TODO(jacobr): last param should be null, see b/5045788
+    return window._getComputedStyle(this, pseudoElement);
+  }
+
+  /**
+   * Gets the position of this element relative to the client area of the page.
+   */
+  Rectangle get client =>
+      new Rectangle(clientLeft, clientTop, clientWidth, clientHeight);
+
+  /**
+   * Gets the offset of this element relative to its offsetParent.
+   */
+  Rectangle get offset =>
+      new Rectangle(offsetLeft, offsetTop, offsetWidth, offsetHeight);
+
+  /**
+   * Adds the specified text after the last child of this element.
+   */
+  void appendText(String text) {
+    this.append(new Text(text));
+  }
+
+  /**
+   * Parses the specified text as HTML and adds the resulting node after the
+   * last child of this element.
+   */
+  void appendHtml(String text,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    this.insertAdjacentHtml('beforeend', text,
+        validator: validator, treeSanitizer: treeSanitizer);
+  }
+
+  /**
+   * Checks to see if the tag name is supported by the current platform.
+   *
+   * The tag should be a valid HTML tag name.
+   */
+  static bool isTagSupported(String tag) {
+    var e = _ElementFactoryProvider.createElement_tag(tag, null);
+    return e is Element && !(e is UnknownElement);
+  }
+
+  /**
+   * Called by the DOM when this element has been inserted into the live
+   * document.
+   *
+   * More information can be found in the
+   * [Custom Elements](http://w3c.github.io/webcomponents/spec/custom/#dfn-attached-callback)
+   * draft specification.
+   */
+  void attached() {
+    // For the deprecation period, call the old callback.
+    enteredView();
+  }
+
+  /**
+   * Called by the DOM when this element has been removed from the live
+   * document.
+   *
+   * More information can be found in the
+   * [Custom Elements](http://w3c.github.io/webcomponents/spec/custom/#dfn-detached-callback)
+   * draft specification.
+   */
+  void detached() {
+    // For the deprecation period, call the old callback.
+    leftView();
+  }
+
+  /** *Deprecated*: override [attached] instead. */
+  @deprecated
+  void enteredView() {}
+
+  List<Rectangle> getClientRects() {
+    var value = _getClientRects();
+
+    // If no prototype we need one for the world to hookup to the proper Dart class.
+    var jsProto = JS('', '#.prototype', value);
+    if (jsProto == null) {
+      JS('', '#.prototype = Object.create(null)', value);
+    }
+
+    applyExtension('DOMRectList', value);
+
+    return value;
+  }
+
+  /** *Deprecated*: override [detached] instead. */
+  @deprecated
+  void leftView() {}
+
+  /**
+   * Creates a new AnimationEffect object whose target element is the object
+   * on which the method is called, and calls the play() method of the
+   * AnimationTimeline object of the document timeline of the node document
+   * of the element, passing the newly created AnimationEffect as the argument
+   * to the method. Returns an Animation for the effect.
+   *
+   * Examples
+   *
+   *     var animation = elem.animate([{"opacity": 75}, {"opacity": 0}], 200);
+   *
+   *     var animation = elem.animate([
+   *       {"transform": "translate(100px, -100%)"},
+   *       {"transform" : "translate(400px, 500px)"}
+   *     ], 1500);
+   *
+   * The [frames] parameter is an Iterable<Map>, where the
+   * map entries specify CSS animation effects. The
+   * [timing] paramter can be a double, representing the number of milliseconds
+   * for the transition, or a Map with fields corresponding to those
+   * of the [Timing] object.
+  **/
+  @SupportedBrowser(SupportedBrowser.CHROME, '36')
+  Animation animate(Iterable<Map<String, dynamic>> frames, [timing]) {
+    if (frames is! Iterable || !(frames.every((x) => x is Map))) {
+      throw new ArgumentError("The frames parameter should be a List of Maps "
+          "with frame information");
+    }
+    var convertedFrames;
+    if (frames is Iterable) {
+      convertedFrames = frames.map(convertDartToNative_Dictionary).toList();
+    } else {
+      convertedFrames = frames;
+    }
+    var convertedTiming =
+        timing is Map ? convertDartToNative_Dictionary(timing) : timing;
+    return convertedTiming == null
+        ? _animate(convertedFrames)
+        : _animate(convertedFrames, convertedTiming);
+  }
+
+  @JSName('animate')
+  Animation _animate(Object effect, [timing]) native;
+  /**
+   * Called by the DOM whenever an attribute on this has been changed.
+   */
+  void attributeChanged(String name, String oldValue, String newValue) {}
+
+  @Returns('String')
+  // Non-null for Elements.
+  String get localName => JS('String', '#', _localName);
+
+  /**
+   * A URI that identifies the XML namespace of this element.
+   *
+   * `null` if no namespace URI is specified.
+   *
+   * ## Other resources
+   *
+   * * [Node.namespaceURI](http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname)
+   *   from W3C.
+   */
+  String get namespaceUri => _namespaceUri;
+
+  /**
+   * The string representation of this element.
+   *
+   * This is equivalent to reading the [localName] property.
+   */
+  String toString() => localName;
+
+  /**
+   * Scrolls this element into view.
+   *
+   * Only one of of the alignment options may be specified at a time.
+   *
+   * If no options are specified then this will attempt to scroll the minimum
+   * amount needed to bring the element into view.
+   *
+   * Note that alignCenter is currently only supported on WebKit platforms. If
+   * alignCenter is specified but not supported then this will fall back to
+   * alignTop.
+   *
+   * See also:
+   *
+   * * [scrollIntoView](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView)
+   *   from MDN.
+   * * [scrollIntoViewIfNeeded](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoViewIfNeeded)
+   *   from MDN.
+   */
+  void scrollIntoView([ScrollAlignment alignment]) {
+    var hasScrollIntoViewIfNeeded = true;
+    hasScrollIntoViewIfNeeded =
+        JS('bool', '!!(#.scrollIntoViewIfNeeded)', this);
+    if (alignment == ScrollAlignment.TOP) {
+      this._scrollIntoView(true);
+    } else if (alignment == ScrollAlignment.BOTTOM) {
+      this._scrollIntoView(false);
+    } else if (hasScrollIntoViewIfNeeded) {
+      if (alignment == ScrollAlignment.CENTER) {
+        this._scrollIntoViewIfNeeded(true);
+      } else {
+        this._scrollIntoViewIfNeeded();
+      }
+    } else {
+      this._scrollIntoView();
+    }
+  }
+
+  /**
+   * Static factory designed to expose `mousewheel` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<WheelEvent> mouseWheelEvent =
+      const _CustomEventStreamProvider<WheelEvent>(
+          Element._determineMouseWheelEventType);
+
+  static String _determineMouseWheelEventType(EventTarget e) => 'wheel';
+
+  /**
+   * Static factory designed to expose `transitionend` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<TransitionEvent> transitionEndEvent =
+      const _CustomEventStreamProvider<TransitionEvent>(
+          Element._determineTransitionEventType);
+
+  static String _determineTransitionEventType(EventTarget e) {
+    // Unfortunately the normal 'ontransitionend' style checks don't work here.
+    if (Device.isWebKit) {
+      return 'webkitTransitionEnd';
+    } else if (Device.isOpera) {
+      return 'oTransitionEnd';
+    }
+    return 'transitionend';
+  }
+
+  /**
+   * Inserts text into the DOM at the specified location.
+   *
+   * To see the possible values for [where], read the doc for
+   * [insertAdjacentHtml].
+   *
+   * See also:
+   *
+   * * [insertAdjacentHtml]
+   */
+  void insertAdjacentText(String where, String text) {
+    if (JS('bool', '!!#.insertAdjacentText', this)) {
+      _insertAdjacentText(where, text);
+    } else {
+      _insertAdjacentNode(where, new Text(text));
+    }
+  }
+
+  @JSName('insertAdjacentText')
+  void _insertAdjacentText(String where, String text) native;
+
+  /**
+   * Parses text as an HTML fragment and inserts it into the DOM at the
+   * specified location.
+   *
+   * The [where] parameter indicates where to insert the HTML fragment:
+   *
+   * * 'beforeBegin': Immediately before this element.
+   * * 'afterBegin': As the first child of this element.
+   * * 'beforeEnd': As the last child of this element.
+   * * 'afterEnd': Immediately after this element.
+   *
+   *     var html = '<div class="something">content</div>';
+   *     // Inserts as the first child
+   *     document.body.insertAdjacentHtml('afterBegin', html);
+   *     var createdElement = document.body.children[0];
+   *     print(createdElement.classes[0]); // Prints 'something'
+   *
+   * See also:
+   *
+   * * [insertAdjacentText]
+   * * [insertAdjacentElement]
+   */
+  void insertAdjacentHtml(String where, String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    if (treeSanitizer is _TrustedHtmlTreeSanitizer) {
+      _insertAdjacentHtml(where, html);
+    } else {
+      _insertAdjacentNode(
+          where,
+          createFragment(html,
+              validator: validator, treeSanitizer: treeSanitizer));
+    }
+  }
+
+  @JSName('insertAdjacentHTML')
+  void _insertAdjacentHtml(String where, String text) native;
+
+  /**
+   * Inserts [element] into the DOM at the specified location.
+   *
+   * To see the possible values for [where], read the doc for
+   * [insertAdjacentHtml].
+   *
+   * See also:
+   *
+   * * [insertAdjacentHtml]
+   */
+  Element insertAdjacentElement(String where, Element element) {
+    if (JS('bool', '!!#.insertAdjacentElement', this)) {
+      _insertAdjacentElement(where, element);
+    } else {
+      _insertAdjacentNode(where, element);
+    }
+    return element;
+  }
+
+  @JSName('insertAdjacentElement')
+  void _insertAdjacentElement(String where, Element element) native;
+
+  void _insertAdjacentNode(String where, Node node) {
+    switch (where.toLowerCase()) {
+      case 'beforebegin':
+        this.parentNode.insertBefore(node, this);
+        break;
+      case 'afterbegin':
+        var first = this.nodes.length > 0 ? this.nodes[0] : null;
+        this.insertBefore(node, first);
+        break;
+      case 'beforeend':
+        this.append(node);
+        break;
+      case 'afterend':
+        this.parentNode.insertBefore(node, this.nextNode);
+        break;
+      default:
+        throw new ArgumentError("Invalid position ${where}");
+    }
+  }
+
+  /**
+   * Checks if this element matches the CSS selectors.
+   */
+  bool matches(String selectors) {
+    if (JS('bool', '!!#.matches', this)) {
+      return JS('bool', '#.matches(#)', this, selectors);
+    } else if (JS('bool', '!!#.webkitMatchesSelector', this)) {
+      return JS('bool', '#.webkitMatchesSelector(#)', this, selectors);
+    } else if (JS('bool', '!!#.mozMatchesSelector', this)) {
+      return JS('bool', '#.mozMatchesSelector(#)', this, selectors);
+    } else if (JS('bool', '!!#.msMatchesSelector', this)) {
+      return JS('bool', '#.msMatchesSelector(#)', this, selectors);
+    } else if (JS('bool', '!!#.oMatchesSelector', this)) {
+      return JS('bool', '#.oMatchesSelector(#)', this, selectors);
+    } else {
+      throw new UnsupportedError("Not supported on this platform");
+    }
+  }
+
+  /** Checks if this element or any of its parents match the CSS selectors. */
+  bool matchesWithAncestors(String selectors) {
+    var elem = this;
+    do {
+      if (elem.matches(selectors)) return true;
+      elem = elem.parent;
+    } while (elem != null);
+    return false;
+  }
+
+  /**
+   * Creates a new shadow root for this shadow host.
+   *
+   * ## Other resources
+   *
+   * * [Shadow DOM 101](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
+   *   from HTML5Rocks.
+   * * [Shadow DOM specification](http://www.w3.org/TR/shadow-dom/) from W3C.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME, '25')
+  ShadowRoot createShadowRoot() {
+    return JS(
+        'ShadowRoot',
+        '(#.createShadowRoot || #.webkitCreateShadowRoot).call(#)',
+        this,
+        this,
+        this);
+  }
+
+  /**
+   * The shadow root of this shadow host.
+   *
+   * ## Other resources
+   *
+   * * [Shadow DOM 101](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
+   *   from HTML5Rocks.
+   * * [Shadow DOM specification](http://www.w3.org/TR/shadow-dom/)
+   *   from W3C.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME, '25')
+  ShadowRoot get shadowRoot =>
+      JS('ShadowRoot|Null', '#.shadowRoot || #.webkitShadowRoot', this, this);
+
+  /**
+   * Access this element's content position.
+   *
+   * This returns a rectangle with the dimensions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not.
+   *
+   * _Important_ _note_: use of this method _will_ perform CSS calculations that
+   * can trigger a browser reflow. Therefore, use of this property _during_ an
+   * animation frame is discouraged. See also:
+   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+   */
+  CssRect get contentEdge => new _ContentCssRect(this);
+
+  /**
+   * Access the dimensions and position of this element's content + padding box.
+   *
+   * This returns a rectangle with the dimensions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's
+   * [innerHeight](http://api.jquery.com/innerHeight/) value for an element.
+   * This is also a rectangle equalling the dimensions of clientHeight and
+   * clientWidth.
+   *
+   * _Important_ _note_: use of this method _will_ perform CSS calculations that
+   * can trigger a browser reflow. Therefore, use of this property _during_ an
+   * animation frame is discouraged. See also:
+   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+   */
+  CssRect get paddingEdge => new _PaddingCssRect(this);
+
+  /**
+   * Access the dimensions and position of this element's content + padding +
+   * border box.
+   *
+   * This returns a rectangle with the dimensions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's
+   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
+   *
+   * _Important_ _note_: use of this method _will_ perform CSS calculations that
+   * can trigger a browser reflow. Therefore, use of this property _during_ an
+   * animation frame is discouraged. See also:
+   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+   */
+  CssRect get borderEdge => new _BorderCssRect(this);
+
+  /**
+   * Access the dimensions and position of this element's content + padding +
+   * border + margin box.
+   *
+   * This returns a rectangle with the dimensions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's
+   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
+   *
+   * _Important_ _note_: use of this method will perform CSS calculations that
+   * can trigger a browser reflow. Therefore, use of this property _during_ an
+   * animation frame is discouraged. See also:
+   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+   */
+  CssRect get marginEdge => new _MarginCssRect(this);
+
+  /**
+   * Provides the coordinates of the element relative to the top of the
+   * document.
+   *
+   * This method is the Dart equivalent to jQuery's
+   * [offset](http://api.jquery.com/offset/) method.
+   */
+  Point get documentOffset => offsetTo(document.documentElement);
+
+  /**
+   * Provides the offset of this element's [borderEdge] relative to the
+   * specified [parent].
+   *
+   * This is the Dart equivalent of jQuery's
+   * [position](http://api.jquery.com/position/) method. Unlike jQuery's
+   * position, however, [parent] can be any parent element of `this`,
+   * rather than only `this`'s immediate [offsetParent]. If the specified
+   * element is _not_ an offset parent or transitive offset parent to this
+   * element, an [ArgumentError] is thrown.
+   */
+  Point offsetTo(Element parent) {
+    return Element._offsetToHelper(this, parent);
+  }
+
+  static Point _offsetToHelper(Element current, Element parent) {
+    // We're hopping from _offsetParent_ to offsetParent (not just parent), so
+    // offsetParent, "tops out" at BODY. But people could conceivably pass in
+    // the document.documentElement and I want it to return an absolute offset,
+    // so we have the special case checking for HTML.
+    bool sameAsParent = identical(current, parent);
+    bool foundAsParent = sameAsParent || parent.tagName == 'HTML';
+    if (current == null || sameAsParent) {
+      if (foundAsParent) return new Point(0, 0);
+      throw new ArgumentError("Specified element is not a transitive offset "
+          "parent of this element.");
+    }
+    Element parentOffset = current.offsetParent;
+    Point p = Element._offsetToHelper(parentOffset, parent);
+    return new Point(p.x + current.offsetLeft, p.y + current.offsetTop);
+  }
+
+  static HtmlDocument _parseDocument;
+  static Range _parseRange;
+  static NodeValidatorBuilder _defaultValidator;
+  static _ValidatingTreeSanitizer _defaultSanitizer;
+
+  /**
+   * Create a DocumentFragment from the HTML fragment and ensure that it follows
+   * the sanitization rules specified by the validator or treeSanitizer.
+   *
+   * If the default validation behavior is too restrictive then a new
+   * NodeValidator should be created, either extending or wrapping a default
+   * validator and overriding the validation APIs.
+   *
+   * The treeSanitizer is used to walk the generated node tree and sanitize it.
+   * A custom treeSanitizer can also be provided to perform special validation
+   * rules but since the API is more complex to implement this is discouraged.
+   *
+   * The returned tree is guaranteed to only contain nodes and attributes which
+   * are allowed by the provided validator.
+   *
+   * See also:
+   *
+   * * [NodeValidator]
+   * * [NodeTreeSanitizer]
+   */
+  DocumentFragment createFragment(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    if (treeSanitizer == null) {
+      if (validator == null) {
+        if (_defaultValidator == null) {
+          _defaultValidator = new NodeValidatorBuilder.common();
+        }
+        validator = _defaultValidator;
+      }
+      if (_defaultSanitizer == null) {
+        _defaultSanitizer = new _ValidatingTreeSanitizer(validator);
+      } else {
+        _defaultSanitizer.validator = validator;
+      }
+      treeSanitizer = _defaultSanitizer;
+    } else if (validator != null) {
+      throw new ArgumentError(
+          'validator can only be passed if treeSanitizer is null');
+    }
+
+    if (_parseDocument == null) {
+      _parseDocument = document.implementation.createHtmlDocument('');
+      _parseRange = _parseDocument.createRange();
+
+      // Workaround for Safari bug. Was also previously Chrome bug 229142
+      // - URIs are not resolved in new doc.
+      BaseElement base = _parseDocument.createElement('base');
+      base.href = document.baseUri;
+      _parseDocument.head.append(base);
+    }
+
+    // TODO(terry): Fixes Chromium 50 change no body after createHtmlDocument()
+    if (_parseDocument.body == null) {
+      _parseDocument.body = _parseDocument.createElement("body");
+    }
+
+    var contextElement;
+    if (this is BodyElement) {
+      contextElement = _parseDocument.body;
+    } else {
+      contextElement = _parseDocument.createElement(tagName);
+      _parseDocument.body.append(contextElement);
+    }
+    var fragment;
+    if (Range.supportsCreateContextualFragment &&
+        _canBeUsedToCreateContextualFragment) {
+      _parseRange.selectNodeContents(contextElement);
+      fragment = _parseRange.createContextualFragment(html);
+    } else {
+      contextElement._innerHtml = html;
+
+      fragment = _parseDocument.createDocumentFragment();
+      while (contextElement.firstChild != null) {
+        fragment.append(contextElement.firstChild);
+      }
+    }
+    if (contextElement != _parseDocument.body) {
+      contextElement.remove();
+    }
+
+    treeSanitizer.sanitizeTree(fragment);
+    // Copy the fragment over to the main document (fix for 14184)
+    document.adoptNode(fragment);
+
+    return fragment;
+  }
+
+  /** Test if createContextualFragment is supported for this element type */
+  bool get _canBeUsedToCreateContextualFragment =>
+      !_cannotBeUsedToCreateContextualFragment;
+
+  /** Test if createContextualFragment is NOT supported for this element type */
+  bool get _cannotBeUsedToCreateContextualFragment =>
+      _tagsForWhichCreateContextualFragmentIsNotSupported.contains(tagName);
+
+  /**
+   * A hard-coded list of the tag names for which createContextualFragment
+   * isn't supported.
+   */
+  static const _tagsForWhichCreateContextualFragmentIsNotSupported = const [
+    'HEAD',
+    'AREA',
+    'BASE',
+    'BASEFONT',
+    'BR',
+    'COL',
+    'COLGROUP',
+    'EMBED',
+    'FRAME',
+    'FRAMESET',
+    'HR',
+    'IMAGE',
+    'IMG',
+    'INPUT',
+    'ISINDEX',
+    'LINK',
+    'META',
+    'PARAM',
+    'SOURCE',
+    'STYLE',
+    'TITLE',
+    'WBR'
+  ];
+
+  /**
+   * Parses the HTML fragment and sets it as the contents of this element.
+   *
+   * This uses the default sanitization behavior to sanitize the HTML fragment,
+   * use [setInnerHtml] to override the default behavior.
+   */
+  set innerHtml(String html) {
+    this.setInnerHtml(html);
+  }
+
+  /**
+   * Parses the HTML fragment and sets it as the contents of this element.
+   * This ensures that the generated content follows the sanitization rules
+   * specified by the validator or treeSanitizer.
+   *
+   * If the default validation behavior is too restrictive then a new
+   * NodeValidator should be created, either extending or wrapping a default
+   * validator and overriding the validation APIs.
+   *
+   * The treeSanitizer is used to walk the generated node tree and sanitize it.
+   * A custom treeSanitizer can also be provided to perform special validation
+   * rules but since the API is more complex to implement this is discouraged.
+   *
+   * The resulting tree is guaranteed to only contain nodes and attributes which
+   * are allowed by the provided validator.
+   *
+   * See also:
+   *
+   * * [NodeValidator]
+   * * [NodeTreeSanitizer]
+   */
+  void setInnerHtml(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    text = null;
+    if (treeSanitizer is _TrustedHtmlTreeSanitizer) {
+      _innerHtml = html;
+    } else {
+      append(createFragment(html,
+          validator: validator, treeSanitizer: treeSanitizer));
+    }
+  }
+
+  String get innerHtml => _innerHtml;
+
+  @JSName('innerText')
+  String innerText;
+
+  /**
+   * This is an ease-of-use accessor for event streams which should only be
+   * used when an explicit accessor is not available.
+   */
+  ElementEvents get on => new ElementEvents(this);
+
+  /**
+   * Verify if any of the attributes that we use in the sanitizer look unexpected,
+   * possibly indicating DOM clobbering attacks.
+   *
+   * Those attributes are: attributes, lastChild, children, previousNode and tagName.
+   */
+  static bool _hasCorruptedAttributes(Element element) {
+    return JS(
+        'bool',
+        r'''
+       (function(element) {
+         if (!(element.attributes instanceof NamedNodeMap)) {
+	   return true;
+	 }
+	 var childNodes = element.childNodes;
+	 if (element.lastChild &&
+	     element.lastChild !== childNodes[childNodes.length -1]) {
+	   return true;
+	 }
+	 if (element.children) { // On Safari, children can apparently be null.
+  	   if (!((element.children instanceof HTMLCollection) ||
+               (element.children instanceof NodeList))) {
+	     return true;
+	   }
+	 }
+         var length = 0;
+         if (element.children) {
+           length = element.children.length;
+         }
+         for (var i = 0; i < length; i++) {
+           var child = element.children[i];
+           // On IE it seems like we sometimes don't see the clobbered attribute,
+           // perhaps as a result of an over-optimization. Also use another route
+           // to check of attributes, children, or lastChild are clobbered. It may
+           // seem silly to check children as we rely on children to do this iteration,
+           // but it seems possible that the access to children might see the real thing,
+           // allowing us to check for clobbering that may show up in other accesses.
+           if (child["id"] == 'attributes' || child["name"] == 'attributes' ||
+               child["id"] == 'lastChild'  || child["name"] == 'lastChild' ||
+               child["id"] == 'children' || child["name"] == 'children') {
+             return true;
+           }
+         }
+	 return false;
+          })(#)''',
+        element);
+  }
+
+  /// A secondary check for corruption, needed on IE
+  static bool _hasCorruptedAttributesAdditionalCheck(Element element) {
+    return JS('bool', r'!(#.attributes instanceof NamedNodeMap)', element);
+  }
+
+  static String _safeTagName(element) {
+    String result = 'element tag unavailable';
+    try {
+      if (element.tagName is String) {
+        result = element.tagName;
+      }
+    } catch (e) {}
+    return result;
+  }
+
+  final Element offsetParent;
+
+  int get offsetHeight => JS<num>('num', '#.offsetHeight', this).round();
+
+  int get offsetLeft => JS<num>('num', '#.offsetLeft', this).round();
+
+  int get offsetTop => JS<num>('num', '#.offsetTop', this).round();
+
+  int get offsetWidth => JS<num>('num', '#.offsetWidth', this).round();
+
+  int get scrollHeight => JS<num>('num', '#.scrollHeight', this).round();
+  int get scrollLeft => JS<num>('num', '#.scrollLeft', this).round();
+
+  set scrollLeft(int value) {
+    JS("void", "#.scrollLeft = #", this, value.round());
+  }
+
+  int get scrollTop => JS<num>('num', '#.scrollTop', this).round();
+
+  set scrollTop(int value) {
+    JS("void", "#.scrollTop = #", this, value.round());
+  }
+
+  int get scrollWidth => JS<num>('num', '#.scrollWidth', this).round();
+
+  // To suppress missing implicit constructor warnings.
+  factory Element._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `abort` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> abortEvent =
+      const EventStreamProvider<Event>('abort');
+
+  /**
+   * Static factory designed to expose `beforecopy` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> beforeCopyEvent =
+      const EventStreamProvider<Event>('beforecopy');
+
+  /**
+   * Static factory designed to expose `beforecut` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> beforeCutEvent =
+      const EventStreamProvider<Event>('beforecut');
+
+  /**
+   * Static factory designed to expose `beforepaste` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> beforePasteEvent =
+      const EventStreamProvider<Event>('beforepaste');
+
+  /**
+   * Static factory designed to expose `blur` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> blurEvent =
+      const EventStreamProvider<Event>('blur');
+
+  static const EventStreamProvider<Event> canPlayEvent =
+      const EventStreamProvider<Event>('canplay');
+
+  static const EventStreamProvider<Event> canPlayThroughEvent =
+      const EventStreamProvider<Event>('canplaythrough');
+
+  /**
+   * Static factory designed to expose `change` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> changeEvent =
+      const EventStreamProvider<Event>('change');
+
+  /**
+   * Static factory designed to expose `click` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MouseEvent> clickEvent =
+      const EventStreamProvider<MouseEvent>('click');
+
+  /**
+   * Static factory designed to expose `contextmenu` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MouseEvent> contextMenuEvent =
+      const EventStreamProvider<MouseEvent>('contextmenu');
+
+  /**
+   * Static factory designed to expose `copy` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ClipboardEvent> copyEvent =
+      const EventStreamProvider<ClipboardEvent>('copy');
+
+  /**
+   * Static factory designed to expose `cut` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ClipboardEvent> cutEvent =
+      const EventStreamProvider<ClipboardEvent>('cut');
+
+  /**
+   * Static factory designed to expose `doubleclick` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  @DomName('Element.dblclickEvent')
+  static const EventStreamProvider<Event> doubleClickEvent =
+      const EventStreamProvider<Event>('dblclick');
+
+  /**
+   * A stream of `drag` events fired when an element is currently being dragged.
+   *
+   * A `drag` event is added to this stream as soon as the drag begins.
+   * A `drag` event is also added to this stream at intervals while the drag
+   * operation is still ongoing.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  static const EventStreamProvider<MouseEvent> dragEvent =
+      const EventStreamProvider<MouseEvent>('drag');
+
+  /**
+   * A stream of `dragend` events fired when an element completes a drag
+   * operation.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  static const EventStreamProvider<MouseEvent> dragEndEvent =
+      const EventStreamProvider<MouseEvent>('dragend');
+
+  /**
+   * A stream of `dragenter` events fired when a dragged object is first dragged
+   * over an element.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  static const EventStreamProvider<MouseEvent> dragEnterEvent =
+      const EventStreamProvider<MouseEvent>('dragenter');
+
+  /**
+   * A stream of `dragleave` events fired when an object being dragged over an
+   * element leaves the element's target area.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  static const EventStreamProvider<MouseEvent> dragLeaveEvent =
+      const EventStreamProvider<MouseEvent>('dragleave');
+
+  /**
+   * A stream of `dragover` events fired when a dragged object is currently
+   * being dragged over an element.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  static const EventStreamProvider<MouseEvent> dragOverEvent =
+      const EventStreamProvider<MouseEvent>('dragover');
+
+  /**
+   * A stream of `dragstart` events for a dragged element whose drag has begun.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  static const EventStreamProvider<MouseEvent> dragStartEvent =
+      const EventStreamProvider<MouseEvent>('dragstart');
+
+  /**
+   * A stream of `drop` events fired when a dragged object is dropped on an
+   * element.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  static const EventStreamProvider<MouseEvent> dropEvent =
+      const EventStreamProvider<MouseEvent>('drop');
+
+  static const EventStreamProvider<Event> durationChangeEvent =
+      const EventStreamProvider<Event>('durationchange');
+
+  static const EventStreamProvider<Event> emptiedEvent =
+      const EventStreamProvider<Event>('emptied');
+
+  static const EventStreamProvider<Event> endedEvent =
+      const EventStreamProvider<Event>('ended');
+
+  /**
+   * Static factory designed to expose `error` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  /**
+   * Static factory designed to expose `focus` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> focusEvent =
+      const EventStreamProvider<Event>('focus');
+
+  /**
+   * Static factory designed to expose `input` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> inputEvent =
+      const EventStreamProvider<Event>('input');
+
+  /**
+   * Static factory designed to expose `invalid` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> invalidEvent =
+      const EventStreamProvider<Event>('invalid');
+
+  /**
+   * Static factory designed to expose `keydown` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<KeyboardEvent> keyDownEvent =
+      const EventStreamProvider<KeyboardEvent>('keydown');
+
+  /**
+   * Static factory designed to expose `keypress` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<KeyboardEvent> keyPressEvent =
+      const EventStreamProvider<KeyboardEvent>('keypress');
+
+  /**
+   * Static factory designed to expose `keyup` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<KeyboardEvent> keyUpEvent =
+      const EventStreamProvider<KeyboardEvent>('keyup');
+
+  /**
+   * Static factory designed to expose `load` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> loadEvent =
+      const EventStreamProvider<Event>('load');
+
+  static const EventStreamProvider<Event> loadedDataEvent =
+      const EventStreamProvider<Event>('loadeddata');
+
+  static const EventStreamProvider<Event> loadedMetadataEvent =
+      const EventStreamProvider<Event>('loadedmetadata');
+
+  /**
+   * Static factory designed to expose `mousedown` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MouseEvent> mouseDownEvent =
+      const EventStreamProvider<MouseEvent>('mousedown');
+
+  /**
+   * Static factory designed to expose `mouseenter` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MouseEvent> mouseEnterEvent =
+      const EventStreamProvider<MouseEvent>('mouseenter');
+
+  /**
+   * Static factory designed to expose `mouseleave` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MouseEvent> mouseLeaveEvent =
+      const EventStreamProvider<MouseEvent>('mouseleave');
+
+  /**
+   * Static factory designed to expose `mousemove` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MouseEvent> mouseMoveEvent =
+      const EventStreamProvider<MouseEvent>('mousemove');
+
+  /**
+   * Static factory designed to expose `mouseout` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MouseEvent> mouseOutEvent =
+      const EventStreamProvider<MouseEvent>('mouseout');
+
+  /**
+   * Static factory designed to expose `mouseover` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MouseEvent> mouseOverEvent =
+      const EventStreamProvider<MouseEvent>('mouseover');
+
+  /**
+   * Static factory designed to expose `mouseup` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MouseEvent> mouseUpEvent =
+      const EventStreamProvider<MouseEvent>('mouseup');
+
+  /**
+   * Static factory designed to expose `paste` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ClipboardEvent> pasteEvent =
+      const EventStreamProvider<ClipboardEvent>('paste');
+
+  static const EventStreamProvider<Event> pauseEvent =
+      const EventStreamProvider<Event>('pause');
+
+  static const EventStreamProvider<Event> playEvent =
+      const EventStreamProvider<Event>('play');
+
+  static const EventStreamProvider<Event> playingEvent =
+      const EventStreamProvider<Event>('playing');
+
+  static const EventStreamProvider<Event> rateChangeEvent =
+      const EventStreamProvider<Event>('ratechange');
+
+  /**
+   * Static factory designed to expose `reset` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> resetEvent =
+      const EventStreamProvider<Event>('reset');
+
+  static const EventStreamProvider<Event> resizeEvent =
+      const EventStreamProvider<Event>('resize');
+
+  /**
+   * Static factory designed to expose `scroll` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> scrollEvent =
+      const EventStreamProvider<Event>('scroll');
+
+  /**
+   * Static factory designed to expose `search` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> searchEvent =
+      const EventStreamProvider<Event>('search');
+
+  static const EventStreamProvider<Event> seekedEvent =
+      const EventStreamProvider<Event>('seeked');
+
+  static const EventStreamProvider<Event> seekingEvent =
+      const EventStreamProvider<Event>('seeking');
+
+  /**
+   * Static factory designed to expose `select` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> selectEvent =
+      const EventStreamProvider<Event>('select');
+
+  /**
+   * Static factory designed to expose `selectstart` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> selectStartEvent =
+      const EventStreamProvider<Event>('selectstart');
+
+  static const EventStreamProvider<Event> stalledEvent =
+      const EventStreamProvider<Event>('stalled');
+
+  /**
+   * Static factory designed to expose `submit` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> submitEvent =
+      const EventStreamProvider<Event>('submit');
+
+  static const EventStreamProvider<Event> suspendEvent =
+      const EventStreamProvider<Event>('suspend');
+
+  static const EventStreamProvider<Event> timeUpdateEvent =
+      const EventStreamProvider<Event>('timeupdate');
+
+  /**
+   * Static factory designed to expose `touchcancel` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<TouchEvent> touchCancelEvent =
+      const EventStreamProvider<TouchEvent>('touchcancel');
+
+  /**
+   * Static factory designed to expose `touchend` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<TouchEvent> touchEndEvent =
+      const EventStreamProvider<TouchEvent>('touchend');
+
+  /**
+   * Static factory designed to expose `touchenter` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<TouchEvent> touchEnterEvent =
+      const EventStreamProvider<TouchEvent>('touchenter');
+
+  /**
+   * Static factory designed to expose `touchleave` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<TouchEvent> touchLeaveEvent =
+      const EventStreamProvider<TouchEvent>('touchleave');
+
+  /**
+   * Static factory designed to expose `touchmove` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<TouchEvent> touchMoveEvent =
+      const EventStreamProvider<TouchEvent>('touchmove');
+
+  /**
+   * Static factory designed to expose `touchstart` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<TouchEvent> touchStartEvent =
+      const EventStreamProvider<TouchEvent>('touchstart');
+
+  static const EventStreamProvider<Event> volumeChangeEvent =
+      const EventStreamProvider<Event>('volumechange');
+
+  static const EventStreamProvider<Event> waitingEvent =
+      const EventStreamProvider<Event>('waiting');
+
+  /**
+   * Static factory designed to expose `fullscreenchange` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  static const EventStreamProvider<Event> fullscreenChangeEvent =
+      const EventStreamProvider<Event>('webkitfullscreenchange');
+
+  /**
+   * Static factory designed to expose `fullscreenerror` events to event
+   * handlers that are not necessarily instances of [Element].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  static const EventStreamProvider<Event> fullscreenErrorEvent =
+      const EventStreamProvider<Event>('webkitfullscreenerror');
+
+  static const EventStreamProvider<WheelEvent> wheelEvent =
+      const EventStreamProvider<WheelEvent>('wheel');
+
+  String contentEditable;
+
+  String dir;
+
+  /**
+   * Indicates whether the element can be dragged and dropped.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  bool draggable;
+
+  /**
+   * Indicates whether the element is not relevant to the page's current state.
+   *
+   * ## Other resources
+   *
+   * * [Hidden attribute
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#the-hidden-attribute)
+   *   from WHATWG.
+   */
+  bool hidden;
+
+  bool inert;
+
+  String inputMode;
+
+  // Using property as subclass shadows.
+  bool get isContentEditable => JS("bool", "#.isContentEditable", this);
+
+  String lang;
+
+  bool spellcheck;
+
+  final CssStyleDeclaration style;
+
+  int tabIndex;
+
+  String title;
+
+  /**
+   * Specifies whether this element's text content changes when the page is
+   * localized.
+   *
+   * ## Other resources
+   *
+   * * [The translate
+   *   attribute](https://html.spec.whatwg.org/multipage/dom.html#the-translate-attribute)
+   *   from WHATWG.
+   */
+  bool translate;
+
+  void blur() native;
+
+  void click() native;
+
+  void focus() native;
+
+  final AccessibleNode accessibleNode;
+
+  final SlotElement assignedSlot;
+
+  @JSName('attributes')
+  final _NamedNodeMap _attributes;
+
+  String className;
+
+  final int clientHeight;
+
+  final int clientLeft;
+
+  final int clientTop;
+
+  final int clientWidth;
+
+  final String computedName;
+
+  final String computedRole;
+
+  String id;
+
+  @JSName('innerHTML')
+  String _innerHtml;
+
+  @JSName('localName')
+  final String _localName;
+
+  @JSName('namespaceURI')
+  final String _namespaceUri;
+
+  // Using property as subclass shadows.
+  String get outerHtml => JS("String", "#.outerHTML", this);
+
+  @JSName('scrollHeight')
+  final int _scrollHeight;
+
+  @JSName('scrollLeft')
+  num _scrollLeft;
+
+  @JSName('scrollTop')
+  num _scrollTop;
+
+  @JSName('scrollWidth')
+  final int _scrollWidth;
+
+  String slot;
+
+  final StylePropertyMap styleMap;
+
+  final String tagName;
+
+  ShadowRoot attachShadow(Map shadowRootInitDict) {
+    var shadowRootInitDict_1 =
+        convertDartToNative_Dictionary(shadowRootInitDict);
+    return _attachShadow_1(shadowRootInitDict_1);
+  }
+
+  @JSName('attachShadow')
+  ShadowRoot _attachShadow_1(shadowRootInitDict) native;
+
+  Element closest(String selectors) native;
+
+  List<Animation> getAnimations() native;
+
+  @JSName('getAttribute')
+  String _getAttribute(String name) native;
+
+  @JSName('getAttributeNS')
+  String _getAttributeNS(String namespaceURI, String localName) native;
+
+  List<String> getAttributeNames() native;
+
+  /**
+   * Returns the smallest bounding rectangle that encompasses this element's
+   * padding, scrollbar, and border.
+   *
+   * ## Other resources
+   *
+   * * [Element.getBoundingClientRect](https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect)
+   *   from MDN.
+   * * [The getBoundingClientRect()
+   *   method](http://www.w3.org/TR/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods)
+   *   from W3C.
+   */
+  @Creates('_DomRect')
+  @Returns('_DomRect|Null')
+  Rectangle getBoundingClientRect() native;
+
+  @JSName('getClientRects')
+  /**
+   * Returns a list of bounding rectangles for each box associated with this
+   * element.
+   *
+   * ## Other resources
+   *
+   * * [Element.getClientRects](https://developer.mozilla.org/en-US/docs/Web/API/Element.getClientRects)
+   *   from MDN.
+   * * [The getClientRects()
+   *   method](http://www.w3.org/TR/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods)
+   *   from W3C.
+   */
+  @Creates('DomRectList')
+  @Returns('DomRectList|Null')
+  List<Rectangle> _getClientRects() native;
+
+  /**
+   * Returns a list of shadow DOM insertion points to which this element is
+   * distributed.
+   *
+   * ## Other resources
+   *
+   * * [Shadow DOM
+   *   specification](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html)
+   *   from W3C.
+   */
+  @Returns('NodeList|Null')
+  @Creates('NodeList')
+  List<Node> getDestinationInsertionPoints() native;
+
+  /**
+   * Returns a list of nodes with the given class name inside this element.
+   *
+   * ## Other resources
+   *
+   * * [getElementsByClassName](https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName)
+   *   from MDN.
+   * * [DOM specification](http://www.w3.org/TR/domcore/) from W3C.
+   */
+  @Creates('NodeList|HtmlCollection')
+  @Returns('NodeList|HtmlCollection')
+  List<Node> getElementsByClassName(String classNames) native;
+
+  @JSName('getElementsByTagName')
+  @Creates('NodeList|HtmlCollection')
+  @Returns('NodeList|HtmlCollection')
+  List<Node> _getElementsByTagName(String localName) native;
+
+  @JSName('hasAttribute')
+  bool _hasAttribute(String name) native;
+
+  @JSName('hasAttributeNS')
+  bool _hasAttributeNS(String namespaceURI, String localName) native;
+
+  bool hasPointerCapture(int pointerId) native;
+
+  void releasePointerCapture(int pointerId) native;
+
+  @JSName('removeAttribute')
+  void _removeAttribute(String name) native;
+
+  @JSName('removeAttributeNS')
+  void _removeAttributeNS(String namespaceURI, String localName) native;
+
+  void requestPointerLock() native;
+
+  void scroll([options_OR_x, num y]) {
+    if (options_OR_x == null && y == null) {
+      _scroll_1();
+      return;
+    }
+    if ((options_OR_x is Map) && y == null) {
+      var options_1 = convertDartToNative_Dictionary(options_OR_x);
+      _scroll_2(options_1);
+      return;
+    }
+    if (y != null && (options_OR_x is num)) {
+      _scroll_3(options_OR_x, y);
+      return;
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('scroll')
+  void _scroll_1() native;
+  @JSName('scroll')
+  void _scroll_2(options) native;
+  @JSName('scroll')
+  void _scroll_3(num x, y) native;
+
+  void scrollBy([options_OR_x, num y]) {
+    if (options_OR_x == null && y == null) {
+      _scrollBy_1();
+      return;
+    }
+    if ((options_OR_x is Map) && y == null) {
+      var options_1 = convertDartToNative_Dictionary(options_OR_x);
+      _scrollBy_2(options_1);
+      return;
+    }
+    if (y != null && (options_OR_x is num)) {
+      _scrollBy_3(options_OR_x, y);
+      return;
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('scrollBy')
+  void _scrollBy_1() native;
+  @JSName('scrollBy')
+  void _scrollBy_2(options) native;
+  @JSName('scrollBy')
+  void _scrollBy_3(num x, y) native;
+
+  @JSName('scrollIntoView')
+  void _scrollIntoView([Object arg]) native;
+
+  @JSName('scrollIntoViewIfNeeded')
+  void _scrollIntoViewIfNeeded([bool centerIfNeeded]) native;
+
+  void scrollTo([options_OR_x, num y]) {
+    if (options_OR_x == null && y == null) {
+      _scrollTo_1();
+      return;
+    }
+    if ((options_OR_x is Map) && y == null) {
+      var options_1 = convertDartToNative_Dictionary(options_OR_x);
+      _scrollTo_2(options_1);
+      return;
+    }
+    if (y != null && (options_OR_x is num)) {
+      _scrollTo_3(options_OR_x, y);
+      return;
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('scrollTo')
+  void _scrollTo_1() native;
+  @JSName('scrollTo')
+  void _scrollTo_2(options) native;
+  @JSName('scrollTo')
+  void _scrollTo_3(num x, y) native;
+
+  @JSName('setAttribute')
+  void _setAttribute(String name, String value) native;
+
+  @JSName('setAttributeNS')
+  void _setAttributeNS(String namespaceURI, String name, String value) native;
+
+  void setPointerCapture(int pointerId) native;
+
+  @JSName('webkitRequestFullscreen')
+  /**
+   * Displays this element fullscreen.
+   *
+   * ## Other resources
+   *
+   * * [Fullscreen
+   *   API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API)
+   *   from MDN.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void requestFullscreen() native;
+
+  // From ChildNode
+
+  void after(Object nodes) native;
+
+  void before(Object nodes) native;
+
+  // From NonDocumentTypeChildNode
+
+  final Element nextElementSibling;
+
+  final Element previousElementSibling;
+
+  // From ParentNode
+
+  @JSName('childElementCount')
+  final int _childElementCount;
+
+  @JSName('children')
+  @Returns('HtmlCollection|Null')
+  @Creates('HtmlCollection')
+  final List<Node> _children;
+
+  @JSName('firstElementChild')
+  final Element _firstElementChild;
+
+  @JSName('lastElementChild')
+  final Element _lastElementChild;
+
+  /**
+   * Finds the first descendant element of this element that matches the
+   * specified group of selectors.
+   *
+   * [selectors] should be a string using CSS selector syntax.
+   *
+   *     // Gets the first descendant with the class 'classname'
+   *     var element = element.querySelector('.className');
+   *     // Gets the element with id 'id'
+   *     var element = element.querySelector('#id');
+   *     // Gets the first descendant [ImageElement]
+   *     var img = element.querySelector('img');
+   *
+   * For details about CSS selector syntax, see the
+   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
+   */
+  Element querySelector(String selectors) native;
+
+  @JSName('querySelectorAll')
+  @Creates('NodeList')
+  @Returns('NodeList')
+  List<Node> _querySelectorAll(String selectors) native;
+
+  /// Stream of `abort` events handled by this [Element].
+  ElementStream<Event> get onAbort => abortEvent.forElement(this);
+
+  /// Stream of `beforecopy` events handled by this [Element].
+  ElementStream<Event> get onBeforeCopy => beforeCopyEvent.forElement(this);
+
+  /// Stream of `beforecut` events handled by this [Element].
+  ElementStream<Event> get onBeforeCut => beforeCutEvent.forElement(this);
+
+  /// Stream of `beforepaste` events handled by this [Element].
+  ElementStream<Event> get onBeforePaste => beforePasteEvent.forElement(this);
+
+  /// Stream of `blur` events handled by this [Element].
+  ElementStream<Event> get onBlur => blurEvent.forElement(this);
+
+  ElementStream<Event> get onCanPlay => canPlayEvent.forElement(this);
+
+  ElementStream<Event> get onCanPlayThrough =>
+      canPlayThroughEvent.forElement(this);
+
+  /// Stream of `change` events handled by this [Element].
+  ElementStream<Event> get onChange => changeEvent.forElement(this);
+
+  /// Stream of `click` events handled by this [Element].
+  ElementStream<MouseEvent> get onClick => clickEvent.forElement(this);
+
+  /// Stream of `contextmenu` events handled by this [Element].
+  ElementStream<MouseEvent> get onContextMenu =>
+      contextMenuEvent.forElement(this);
+
+  /// Stream of `copy` events handled by this [Element].
+  ElementStream<ClipboardEvent> get onCopy => copyEvent.forElement(this);
+
+  /// Stream of `cut` events handled by this [Element].
+  ElementStream<ClipboardEvent> get onCut => cutEvent.forElement(this);
+
+  /// Stream of `doubleclick` events handled by this [Element].
+  @DomName('Element.ondblclick')
+  ElementStream<Event> get onDoubleClick => doubleClickEvent.forElement(this);
+
+  /**
+   * A stream of `drag` events fired when this element currently being dragged.
+   *
+   * A `drag` event is added to this stream as soon as the drag begins.
+   * A `drag` event is also added to this stream at intervals while the drag
+   * operation is still ongoing.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDrag => dragEvent.forElement(this);
+
+  /**
+   * A stream of `dragend` events fired when this element completes a drag
+   * operation.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDragEnd => dragEndEvent.forElement(this);
+
+  /**
+   * A stream of `dragenter` events fired when a dragged object is first dragged
+   * over this element.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDragEnter => dragEnterEvent.forElement(this);
+
+  /**
+   * A stream of `dragleave` events fired when an object being dragged over this
+   * element leaves this element's target area.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDragLeave => dragLeaveEvent.forElement(this);
+
+  /**
+   * A stream of `dragover` events fired when a dragged object is currently
+   * being dragged over this element.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDragOver => dragOverEvent.forElement(this);
+
+  /**
+   * A stream of `dragstart` events fired when this element starts being
+   * dragged.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDragStart => dragStartEvent.forElement(this);
+
+  /**
+   * A stream of `drop` events fired when a dragged object is dropped on this
+   * element.
+   *
+   * ## Other resources
+   *
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
+   */
+  ElementStream<MouseEvent> get onDrop => dropEvent.forElement(this);
+
+  ElementStream<Event> get onDurationChange =>
+      durationChangeEvent.forElement(this);
+
+  ElementStream<Event> get onEmptied => emptiedEvent.forElement(this);
+
+  ElementStream<Event> get onEnded => endedEvent.forElement(this);
+
+  /// Stream of `error` events handled by this [Element].
+  ElementStream<Event> get onError => errorEvent.forElement(this);
+
+  /// Stream of `focus` events handled by this [Element].
+  ElementStream<Event> get onFocus => focusEvent.forElement(this);
+
+  /// Stream of `input` events handled by this [Element].
+  ElementStream<Event> get onInput => inputEvent.forElement(this);
+
+  /// Stream of `invalid` events handled by this [Element].
+  ElementStream<Event> get onInvalid => invalidEvent.forElement(this);
+
+  /// Stream of `keydown` events handled by this [Element].
+  ElementStream<KeyboardEvent> get onKeyDown => keyDownEvent.forElement(this);
+
+  /// Stream of `keypress` events handled by this [Element].
+  ElementStream<KeyboardEvent> get onKeyPress => keyPressEvent.forElement(this);
+
+  /// Stream of `keyup` events handled by this [Element].
+  ElementStream<KeyboardEvent> get onKeyUp => keyUpEvent.forElement(this);
+
+  /// Stream of `load` events handled by this [Element].
+  ElementStream<Event> get onLoad => loadEvent.forElement(this);
+
+  ElementStream<Event> get onLoadedData => loadedDataEvent.forElement(this);
+
+  ElementStream<Event> get onLoadedMetadata =>
+      loadedMetadataEvent.forElement(this);
+
+  /// Stream of `mousedown` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseDown => mouseDownEvent.forElement(this);
+
+  /// Stream of `mouseenter` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseEnter =>
+      mouseEnterEvent.forElement(this);
+
+  /// Stream of `mouseleave` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseLeave =>
+      mouseLeaveEvent.forElement(this);
+
+  /// Stream of `mousemove` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseMove => mouseMoveEvent.forElement(this);
+
+  /// Stream of `mouseout` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseOut => mouseOutEvent.forElement(this);
+
+  /// Stream of `mouseover` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseOver => mouseOverEvent.forElement(this);
+
+  /// Stream of `mouseup` events handled by this [Element].
+  ElementStream<MouseEvent> get onMouseUp => mouseUpEvent.forElement(this);
+
+  /// Stream of `mousewheel` events handled by this [Element].
+  ElementStream<WheelEvent> get onMouseWheel =>
+      mouseWheelEvent.forElement(this);
+
+  /// Stream of `paste` events handled by this [Element].
+  ElementStream<ClipboardEvent> get onPaste => pasteEvent.forElement(this);
+
+  ElementStream<Event> get onPause => pauseEvent.forElement(this);
+
+  ElementStream<Event> get onPlay => playEvent.forElement(this);
+
+  ElementStream<Event> get onPlaying => playingEvent.forElement(this);
+
+  ElementStream<Event> get onRateChange => rateChangeEvent.forElement(this);
+
+  /// Stream of `reset` events handled by this [Element].
+  ElementStream<Event> get onReset => resetEvent.forElement(this);
+
+  ElementStream<Event> get onResize => resizeEvent.forElement(this);
+
+  /// Stream of `scroll` events handled by this [Element].
+  ElementStream<Event> get onScroll => scrollEvent.forElement(this);
+
+  /// Stream of `search` events handled by this [Element].
+  ElementStream<Event> get onSearch => searchEvent.forElement(this);
+
+  ElementStream<Event> get onSeeked => seekedEvent.forElement(this);
+
+  ElementStream<Event> get onSeeking => seekingEvent.forElement(this);
+
+  /// Stream of `select` events handled by this [Element].
+  ElementStream<Event> get onSelect => selectEvent.forElement(this);
+
+  /// Stream of `selectstart` events handled by this [Element].
+  ElementStream<Event> get onSelectStart => selectStartEvent.forElement(this);
+
+  ElementStream<Event> get onStalled => stalledEvent.forElement(this);
+
+  /// Stream of `submit` events handled by this [Element].
+  ElementStream<Event> get onSubmit => submitEvent.forElement(this);
+
+  ElementStream<Event> get onSuspend => suspendEvent.forElement(this);
+
+  ElementStream<Event> get onTimeUpdate => timeUpdateEvent.forElement(this);
+
+  /// Stream of `touchcancel` events handled by this [Element].
+  ElementStream<TouchEvent> get onTouchCancel =>
+      touchCancelEvent.forElement(this);
+
+  /// Stream of `touchend` events handled by this [Element].
+  ElementStream<TouchEvent> get onTouchEnd => touchEndEvent.forElement(this);
+
+  /// Stream of `touchenter` events handled by this [Element].
+  ElementStream<TouchEvent> get onTouchEnter =>
+      touchEnterEvent.forElement(this);
+
+  /// Stream of `touchleave` events handled by this [Element].
+  ElementStream<TouchEvent> get onTouchLeave =>
+      touchLeaveEvent.forElement(this);
+
+  /// Stream of `touchmove` events handled by this [Element].
+  ElementStream<TouchEvent> get onTouchMove => touchMoveEvent.forElement(this);
+
+  /// Stream of `touchstart` events handled by this [Element].
+  ElementStream<TouchEvent> get onTouchStart =>
+      touchStartEvent.forElement(this);
+
+  /// Stream of `transitionend` events handled by this [Element].
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  ElementStream<TransitionEvent> get onTransitionEnd =>
+      transitionEndEvent.forElement(this);
+
+  ElementStream<Event> get onVolumeChange => volumeChangeEvent.forElement(this);
+
+  ElementStream<Event> get onWaiting => waitingEvent.forElement(this);
+
+  /// Stream of `fullscreenchange` events handled by this [Element].
+  ElementStream<Event> get onFullscreenChange =>
+      fullscreenChangeEvent.forElement(this);
+
+  /// Stream of `fullscreenerror` events handled by this [Element].
+  ElementStream<Event> get onFullscreenError =>
+      fullscreenErrorEvent.forElement(this);
+
+  ElementStream<WheelEvent> get onWheel => wheelEvent.forElement(this);
+}
+
+class _ElementFactoryProvider {
+  // Optimization to improve performance until the dart2js compiler inlines this
+  // method.
+  static dynamic createElement_tag(String tag, String typeExtension) {
+    // Firefox may return a JS function for some types (Embed, Object).
+    if (typeExtension != null) {
+      return JS('Element|=Object', 'document.createElement(#, #)', tag,
+          typeExtension);
+    }
+    // Should be able to eliminate this and just call the two-arg version above
+    // with null typeExtension, but Chrome treats the tag as case-sensitive if
+    // typeExtension is null.
+    // https://code.google.com/p/chromium/issues/detail?id=282467
+    return JS('Element|=Object', 'document.createElement(#)', tag);
+  }
+}
+
+/**
+ * Options for Element.scrollIntoView.
+ */
+class ScrollAlignment {
+  final _value;
+  const ScrollAlignment._internal(this._value);
+  toString() => 'ScrollAlignment.$_value';
+
+  /// Attempt to align the element to the top of the scrollable area.
+  static const TOP = const ScrollAlignment._internal('TOP');
+
+  /// Attempt to center the element in the scrollable area.
+  static const CENTER = const ScrollAlignment._internal('CENTER');
+
+  /// Attempt to align the element to the bottom of the scrollable area.
+  static const BOTTOM = const ScrollAlignment._internal('BOTTOM');
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.IE)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("HTMLEmbedElement")
+class EmbedElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory EmbedElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory EmbedElement() => document.createElement("embed");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  EmbedElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => Element.isTagSupported('embed');
+
+  String height;
+
+  String name;
+
+  String src;
+
+  String type;
+
+  String width;
+
+  Node __getter__(String name) native;
+
+  void __setter__(String name, Node value) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void _EntriesCallback(List entries);
+// Copyright (c) 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.
+
+@Native("Entry")
+class Entry extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Entry._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final FileSystem filesystem;
+
+  final String fullPath;
+
+  final bool isDirectory;
+
+  final bool isFile;
+
+  final String name;
+
+  @JSName('copyTo')
+  void _copyTo(DirectoryEntry parent,
+      [String name,
+      _EntryCallback successCallback,
+      _ErrorCallback errorCallback]) native;
+
+  @JSName('copyTo')
+  Future<Entry> copyTo(DirectoryEntry parent, {String name}) {
+    var completer = new Completer<Entry>();
+    _copyTo(parent, name, (value) {
+      completer.complete(value);
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+
+  @JSName('getMetadata')
+  void _getMetadata(MetadataCallback successCallback,
+      [_ErrorCallback errorCallback]) native;
+
+  @JSName('getMetadata')
+  Future<Metadata> getMetadata() {
+    var completer = new Completer<Metadata>();
+    _getMetadata((value) {
+      applyExtension('Metadata', value);
+      completer.complete(value);
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+
+  @JSName('getParent')
+  void _getParent(
+      [_EntryCallback successCallback, _ErrorCallback errorCallback]) native;
+
+  @JSName('getParent')
+  Future<Entry> getParent() {
+    var completer = new Completer<Entry>();
+    _getParent((value) {
+      applyExtension('Entry', value);
+      completer.complete(value);
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+
+  @JSName('moveTo')
+  void _moveTo(DirectoryEntry parent,
+      [String name,
+      _EntryCallback successCallback,
+      _ErrorCallback errorCallback]) native;
+
+  @JSName('moveTo')
+  Future<Entry> moveTo(DirectoryEntry parent, {String name}) {
+    var completer = new Completer<Entry>();
+    _moveTo(parent, name, (value) {
+      completer.complete(value);
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+
+  @JSName('remove')
+  void _remove(VoidCallback successCallback, [_ErrorCallback errorCallback])
+      native;
+
+  @JSName('remove')
+  Future remove() {
+    var completer = new Completer();
+    _remove(() {
+      completer.complete();
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+
+  @JSName('toURL')
+  String toUrl() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void _EntryCallback(Entry entry);
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void _ErrorCallback(DomException error);
+// Copyright (c) 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.
+
+@Unstable()
+@Native("ErrorEvent")
+class ErrorEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory ErrorEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ErrorEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return ErrorEvent._create_1(type, eventInitDict_1);
+    }
+    return ErrorEvent._create_2(type);
+  }
+  static ErrorEvent _create_1(type, eventInitDict) =>
+      JS('ErrorEvent', 'new ErrorEvent(#,#)', type, eventInitDict);
+  static ErrorEvent _create_2(type) =>
+      JS('ErrorEvent', 'new ErrorEvent(#)', type);
+
+  final int colno;
+
+  @Creates('Null')
+  final Object error;
+
+  final String filename;
+
+  final int lineno;
+
+  final String message;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@Native("Event,InputEvent")
+class Event extends Interceptor {
+  // In JS, canBubble and cancelable are technically required parameters to
+  // init*Event. In practice, though, if they aren't provided they simply
+  // default to false (since that's Boolean(undefined)).
+  //
+  // Contrary to JS, we default canBubble and cancelable to true, since that's
+  // what people want most of the time anyway.
+  factory Event(String type, {bool canBubble: true, bool cancelable: true}) {
+    return new Event.eventType('Event', type,
+        canBubble: canBubble, cancelable: cancelable);
+  }
+
+  /**
+   * Creates a new Event object of the specified type.
+   *
+   * This is analogous to document.createEvent.
+   * Normally events should be created via their constructors, if available.
+   *
+   *     var e = new Event.type('MouseEvent', 'mousedown', true, true);
+   */
+  factory Event.eventType(String type, String name,
+      {bool canBubble: true, bool cancelable: true}) {
+    final Event e = document._createEvent(type);
+    e._initEvent(name, canBubble, cancelable);
+    return e;
+  }
+
+  /** The CSS selector involved with event delegation. */
+  String _selector;
+
+  /**
+   * A pointer to the element whose CSS selector matched within which an event
+   * was fired. If this Event was not associated with any Event delegation,
+   * accessing this value will throw an [UnsupportedError].
+   */
+  Element get matchingTarget {
+    if (_selector == null) {
+      throw new UnsupportedError('Cannot call matchingTarget if this Event did'
+          ' not arise as a result of event delegation.');
+    }
+    Element currentTarget = this.currentTarget;
+    Element target = this.target;
+    var matchedTarget;
+    do {
+      if (target.matches(_selector)) return target;
+      target = target.parent;
+    } while (target != null && target != currentTarget.parent);
+    throw new StateError('No selector matched for populating matchedTarget.');
+  }
+
+  List<EventTarget> get path =>
+      JS('bool', '!!#.composedPath', this) ? composedPath() : [];
+
+  factory Event._(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return Event._create_1(type, eventInitDict_1);
+    }
+    return Event._create_2(type);
+  }
+  static Event _create_1(type, eventInitDict) =>
+      JS('Event', 'new Event(#,#)', type, eventInitDict);
+  static Event _create_2(type) => JS('Event', 'new Event(#)', type);
+
+  /**
+   * This event is being handled by the event target.
+   *
+   * ## Other resources
+   *
+   * * [Target phase](http://www.w3.org/TR/DOM-Level-3-Events/#target-phase)
+   *   from W3C.
+   */
+  static const int AT_TARGET = 2;
+
+  /**
+   * This event is bubbling up through the target's ancestors.
+   *
+   * ## Other resources
+   *
+   * * [Bubble phase](http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
+   *   from W3C.
+   */
+  static const int BUBBLING_PHASE = 3;
+
+  /**
+   * This event is propagating through the target's ancestors, starting from the
+   * document.
+   *
+   * ## Other resources
+   *
+   * * [Bubble phase](http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
+   *   from W3C.
+   */
+  static const int CAPTURING_PHASE = 1;
+
+  final bool bubbles;
+
+  final bool cancelable;
+
+  final bool composed;
+
+  EventTarget get currentTarget =>
+      _convertNativeToDart_EventTarget(this._get_currentTarget);
+  @JSName('currentTarget')
+  @Creates('Null')
+  @Returns('EventTarget|=Object|Null')
+  final dynamic _get_currentTarget;
+
+  final bool defaultPrevented;
+
+  final int eventPhase;
+
+  final bool isTrusted;
+
+  EventTarget get target => _convertNativeToDart_EventTarget(this._get_target);
+  @JSName('target')
+  @Creates('Node')
+  @Returns('EventTarget|=Object')
+  final dynamic _get_target;
+
+  final num timeStamp;
+
+  final String type;
+
+  List<EventTarget> composedPath() native;
+
+  @JSName('initEvent')
+  void _initEvent(String type, [bool bubbles, bool cancelable]) native;
+
+  void preventDefault() native;
+
+  void stopImmediatePropagation() native;
+
+  void stopPropagation() native;
+}
+// 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.
+
+@Native("EventSource")
+class EventSource extends EventTarget {
+  factory EventSource(String url, {withCredentials: false}) {
+    var parsedOptions = {
+      'withCredentials': withCredentials,
+    };
+    return EventSource._factoryEventSource(url, parsedOptions);
+  }
+  // To suppress missing implicit constructor warnings.
+  factory EventSource._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `error` events to event
+   * handlers that are not necessarily instances of [EventSource].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  /**
+   * Static factory designed to expose `message` events to event
+   * handlers that are not necessarily instances of [EventSource].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MessageEvent> messageEvent =
+      const EventStreamProvider<MessageEvent>('message');
+
+  /**
+   * Static factory designed to expose `open` events to event
+   * handlers that are not necessarily instances of [EventSource].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> openEvent =
+      const EventStreamProvider<Event>('open');
+
+  static EventSource _factoryEventSource(String url,
+      [Map eventSourceInitDict]) {
+    if (eventSourceInitDict != null) {
+      var eventSourceInitDict_1 =
+          convertDartToNative_Dictionary(eventSourceInitDict);
+      return EventSource._create_1(url, eventSourceInitDict_1);
+    }
+    return EventSource._create_2(url);
+  }
+
+  static EventSource _create_1(url, eventSourceInitDict) =>
+      JS('EventSource', 'new EventSource(#,#)', url, eventSourceInitDict);
+  static EventSource _create_2(url) =>
+      JS('EventSource', 'new EventSource(#)', url);
+
+  static const int CLOSED = 2;
+
+  static const int CONNECTING = 0;
+
+  static const int OPEN = 1;
+
+  final int readyState;
+
+  final String url;
+
+  final bool withCredentials;
+
+  void close() native;
+
+  /// Stream of `error` events handled by this [EventSource].
+  Stream<Event> get onError => errorEvent.forTarget(this);
+
+  /// Stream of `message` events handled by this [EventSource].
+  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
+
+  /// Stream of `open` events handled by this [EventSource].
+  Stream<Event> get onOpen => openEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+/**
+ * Base class that supports listening for and dispatching browser events.
+ *
+ * Normally events are accessed via the Stream getter:
+ *
+ *     element.onMouseOver.listen((e) => print('Mouse over!'));
+ *
+ * To access bubbling events which are declared on one element, but may bubble
+ * up to another element type (common for MediaElement events):
+ *
+ *     MediaElement.pauseEvent.forTarget(document.body).listen(...);
+ *
+ * To useCapture on events:
+ *
+ *     Element.keyDownEvent.forTarget(element, useCapture: true).listen(...);
+ *
+ * Custom events can be declared as:
+ *
+ *     class DataGenerator {
+ *       static EventStreamProvider<Event> dataEvent =
+ *           new EventStreamProvider('data');
+ *     }
+ *
+ * Then listeners should access the event with:
+ *
+ *     DataGenerator.dataEvent.forTarget(element).listen(...);
+ *
+ * Custom events can also be accessed as:
+ *
+ *     element.on['some_event'].listen(...);
+ *
+ * This approach is generally discouraged as it loses the event typing and
+ * some DOM events may have multiple platform-dependent event names under the
+ * covers. By using the standard Stream getters you will get the platform
+ * specific event name automatically.
+ */
+class Events {
+  /* Raw event target. */
+  final EventTarget _ptr;
+
+  Events(this._ptr);
+
+  Stream<Event> operator [](String type) {
+    return new _EventStream(_ptr, type, false);
+  }
+}
+
+class ElementEvents extends Events {
+  static final webkitEvents = {
+    'animationend': 'webkitAnimationEnd',
+    'animationiteration': 'webkitAnimationIteration',
+    'animationstart': 'webkitAnimationStart',
+    'fullscreenchange': 'webkitfullscreenchange',
+    'fullscreenerror': 'webkitfullscreenerror',
+    'keyadded': 'webkitkeyadded',
+    'keyerror': 'webkitkeyerror',
+    'keymessage': 'webkitkeymessage',
+    'needkey': 'webkitneedkey',
+    'pointerlockchange': 'webkitpointerlockchange',
+    'pointerlockerror': 'webkitpointerlockerror',
+    'resourcetimingbufferfull': 'webkitresourcetimingbufferfull',
+    'transitionend': 'webkitTransitionEnd',
+    'speechchange': 'webkitSpeechChange'
+  };
+
+  ElementEvents(Element ptr) : super(ptr);
+
+  Stream<Event> operator [](String type) {
+    if (webkitEvents.keys.contains(type.toLowerCase())) {
+      if (Device.isWebKit) {
+        return new _ElementEventStreamImpl(
+            _ptr, webkitEvents[type.toLowerCase()], false);
+      }
+    }
+    return new _ElementEventStreamImpl(_ptr, type, false);
+  }
+}
+
+/**
+ * Base class for all browser objects that support events.
+ *
+ * Use the [on] property to add, and remove events
+ * for compile-time type checks and a more concise API.
+ */
+@Native("EventTarget")
+class EventTarget extends Interceptor {
+  // Custom element created callback.
+  EventTarget._created();
+
+  /**
+   * This is an ease-of-use accessor for event streams which should only be
+   * used when an explicit accessor is not available.
+   */
+  Events get on => new Events(this);
+
+  void addEventListener(String type, EventListener listener,
+      [bool useCapture]) {
+    // TODO(leafp): This check is avoid a bug in our dispatch code when
+    // listener is null.  The browser treats this call as a no-op in this
+    // case, so it's fine to short-circuit it, but we should not have to.
+    if (listener != null) {
+      _addEventListener(type, listener, useCapture);
+    }
+  }
+
+  void removeEventListener(String type, EventListener listener,
+      [bool useCapture]) {
+    // TODO(leafp): This check is avoid a bug in our dispatch code when
+    // listener is null.  The browser treats this call as a no-op in this
+    // case, so it's fine to short-circuit it, but we should not have to.
+    if (listener != null) {
+      _removeEventListener(type, listener, useCapture);
+    }
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory EventTarget._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('addEventListener')
+  void _addEventListener(String type, EventListener listener, [bool options])
+      native;
+
+  bool dispatchEvent(Event event) native;
+
+  @JSName('removeEventListener')
+  void _removeEventListener(String type, EventListener listener, [bool options])
+      native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("ExtendableEvent")
+class ExtendableEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory ExtendableEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ExtendableEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return ExtendableEvent._create_1(type, eventInitDict_1);
+    }
+    return ExtendableEvent._create_2(type);
+  }
+  static ExtendableEvent _create_1(type, eventInitDict) =>
+      JS('ExtendableEvent', 'new ExtendableEvent(#,#)', type, eventInitDict);
+  static ExtendableEvent _create_2(type) =>
+      JS('ExtendableEvent', 'new ExtendableEvent(#)', type);
+
+  void waitUntil(Future f) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("ExtendableMessageEvent")
+class ExtendableMessageEvent extends ExtendableEvent {
+  // To suppress missing implicit constructor warnings.
+  factory ExtendableMessageEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @annotation_Creates_SerializedScriptValue
+  @annotation_Returns_SerializedScriptValue
+  final Object data;
+
+  final String lastEventId;
+
+  final String origin;
+
+  final List<MessagePort> ports;
+
+  @Creates('Client|ServiceWorker|MessagePort')
+  @Returns('Client|ServiceWorker|MessagePort|Null')
+  final Object source;
+}
+// Copyright (c) 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.
+
+@Native("External")
+class External extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory External._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  void AddSearchProvider() native;
+
+  void IsSearchProviderInstalled() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("FaceDetector")
+class FaceDetector extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory FaceDetector._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FaceDetector([Map faceDetectorOptions]) {
+    if (faceDetectorOptions != null) {
+      var faceDetectorOptions_1 =
+          convertDartToNative_Dictionary(faceDetectorOptions);
+      return FaceDetector._create_1(faceDetectorOptions_1);
+    }
+    return FaceDetector._create_2();
+  }
+  static FaceDetector _create_1(faceDetectorOptions) =>
+      JS('FaceDetector', 'new FaceDetector(#)', faceDetectorOptions);
+  static FaceDetector _create_2() => JS('FaceDetector', 'new FaceDetector()');
+
+  Future<List<DetectedFace>> detect(/*ImageBitmapSource*/ image) =>
+      promiseToFuture<List<DetectedFace>>(JS("", "#.detect(#)", this, image));
+}
+// Copyright (c) 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.
+
+@Native("FederatedCredential")
+class FederatedCredential extends Credential implements CredentialUserData {
+  // To suppress missing implicit constructor warnings.
+  factory FederatedCredential._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FederatedCredential(Map data) {
+    var data_1 = convertDartToNative_Dictionary(data);
+    return FederatedCredential._create_1(data_1);
+  }
+  static FederatedCredential _create_1(data) =>
+      JS('FederatedCredential', 'new FederatedCredential(#)', data);
+
+  final String protocol;
+
+  final String provider;
+
+  // From CredentialUserData
+
+  @JSName('iconURL')
+  final String iconUrl;
+
+  final String name;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("FetchEvent")
+class FetchEvent extends ExtendableEvent {
+  // To suppress missing implicit constructor warnings.
+  factory FetchEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FetchEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return FetchEvent._create_1(type, eventInitDict_1);
+  }
+  static FetchEvent _create_1(type, eventInitDict) =>
+      JS('FetchEvent', 'new FetchEvent(#,#)', type, eventInitDict);
+
+  final String clientId;
+
+  final bool isReload;
+
+  Future get preloadResponse =>
+      promiseToFuture(JS("", "#.preloadResponse", this));
+
+  final _Request request;
+
+  void respondWith(Future r) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("HTMLFieldSetElement")
+class FieldSetElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory FieldSetElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FieldSetElement() => JS(
+      'returns:FieldSetElement;creates:FieldSetElement;new:true',
+      '#.createElement(#)',
+      document,
+      "fieldset");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FieldSetElement.created() : super.created();
+
+  bool disabled;
+
+  @Returns('HtmlCollection|Null')
+  @Creates('HtmlCollection')
+  final List<Node> elements;
+
+  final FormElement form;
+
+  String name;
+
+  final String type;
+
+  final String validationMessage;
+
+  final ValidityState validity;
+
+  final bool willValidate;
+
+  bool checkValidity() native;
+
+  bool reportValidity() native;
+
+  void setCustomValidity(String error) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("File")
+class File extends Blob {
+  // To suppress missing implicit constructor warnings.
+  factory File._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory File(List<Object> fileBits, String fileName, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return File._create_1(fileBits, fileName, options_1);
+    }
+    return File._create_2(fileBits, fileName);
+  }
+  static File _create_1(fileBits, fileName, options) =>
+      JS('File', 'new File(#,#,#)', fileBits, fileName, options);
+  static File _create_2(fileBits, fileName) =>
+      JS('File', 'new File(#,#)', fileBits, fileName);
+
+  final int lastModified;
+
+  DateTime get lastModifiedDate =>
+      convertNativeToDart_DateTime(this._get_lastModifiedDate);
+  @JSName('lastModifiedDate')
+  @Creates('Null')
+  final dynamic _get_lastModifiedDate;
+
+  final String name;
+
+  @JSName('webkitRelativePath')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  final String relativePath;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void _FileCallback(File file);
+// Copyright (c) 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.
+
+@Native("FileEntry")
+class FileEntry extends Entry {
+  // To suppress missing implicit constructor warnings.
+  factory FileEntry._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('createWriter')
+  void _createWriter(_FileWriterCallback successCallback,
+      [_ErrorCallback errorCallback]) native;
+
+  @JSName('createWriter')
+  Future<FileWriter> createWriter() {
+    var completer = new Completer<FileWriter>();
+    _createWriter((value) {
+      applyExtension('FileWriter', value);
+      completer.complete(value);
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+
+  @JSName('file')
+  void _file(_FileCallback successCallback, [_ErrorCallback errorCallback])
+      native;
+
+  @JSName('file')
+  Future<File> file() {
+    var completer = new Completer<File>();
+    _file((value) {
+      applyExtension('File', value);
+      completer.complete(value);
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+}
+// Copyright (c) 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.
+
+@Native("FileList")
+class FileList extends Interceptor
+    with ListMixin<File>, ImmutableListMixin<File>
+    implements List<File>, JavaScriptIndexingBehavior<File> {
+  // To suppress missing implicit constructor warnings.
+  factory FileList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  File operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return JS("File", "#[#]", this, index);
+  }
+
+  void operator []=(int index, File value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<File> mixins.
+  // File is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  File get first {
+    if (this.length > 0) {
+      return JS('File', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  File get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('File', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  File get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('File', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  File elementAt(int index) => this[index];
+  // -- end List<File> mixins.
+
+  File item(int index) native;
+}
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("FileReader")
+class FileReader extends EventTarget {
+  Object get result {
+    var res = JS('Null|String|NativeByteBuffer', '#.result', this);
+    if (res is ByteBuffer) {
+      return new Uint8List.view(res);
+    }
+    return res;
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory FileReader._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `abort` events to event
+   * handlers that are not necessarily instances of [FileReader].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> abortEvent =
+      const EventStreamProvider<ProgressEvent>('abort');
+
+  /**
+   * Static factory designed to expose `error` events to event
+   * handlers that are not necessarily instances of [FileReader].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> errorEvent =
+      const EventStreamProvider<ProgressEvent>('error');
+
+  /**
+   * Static factory designed to expose `load` events to event
+   * handlers that are not necessarily instances of [FileReader].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> loadEvent =
+      const EventStreamProvider<ProgressEvent>('load');
+
+  /**
+   * Static factory designed to expose `loadend` events to event
+   * handlers that are not necessarily instances of [FileReader].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> loadEndEvent =
+      const EventStreamProvider<ProgressEvent>('loadend');
+
+  /**
+   * Static factory designed to expose `loadstart` events to event
+   * handlers that are not necessarily instances of [FileReader].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> loadStartEvent =
+      const EventStreamProvider<ProgressEvent>('loadstart');
+
+  /**
+   * Static factory designed to expose `progress` events to event
+   * handlers that are not necessarily instances of [FileReader].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> progressEvent =
+      const EventStreamProvider<ProgressEvent>('progress');
+
+  factory FileReader() {
+    return FileReader._create_1();
+  }
+  static FileReader _create_1() => JS('FileReader', 'new FileReader()');
+
+  static const int DONE = 2;
+
+  static const int EMPTY = 0;
+
+  static const int LOADING = 1;
+
+  final DomException error;
+
+  final int readyState;
+
+  void abort() native;
+
+  void readAsArrayBuffer(Blob blob) native;
+
+  @JSName('readAsDataURL')
+  void readAsDataUrl(Blob blob) native;
+
+  void readAsText(Blob blob, [String label]) native;
+
+  /// Stream of `abort` events handled by this [FileReader].
+  Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);
+
+  /// Stream of `error` events handled by this [FileReader].
+  Stream<ProgressEvent> get onError => errorEvent.forTarget(this);
+
+  /// Stream of `load` events handled by this [FileReader].
+  Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);
+
+  /// Stream of `loadend` events handled by this [FileReader].
+  Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);
+
+  /// Stream of `loadstart` events handled by this [FileReader].
+  Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);
+
+  /// Stream of `progress` events handled by this [FileReader].
+  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@Native("DOMFileSystem")
+class FileSystem extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory FileSystem._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(window.webkitRequestFileSystem)');
+
+  final String name;
+
+  final DirectoryEntry root;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void _FileSystemCallback(FileSystem fileSystem);
+// Copyright (c) 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.
+
+@Native("FileWriter")
+class FileWriter extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory FileWriter._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `abort` events to event
+   * handlers that are not necessarily instances of [FileWriter].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> abortEvent =
+      const EventStreamProvider<ProgressEvent>('abort');
+
+  /**
+   * Static factory designed to expose `error` events to event
+   * handlers that are not necessarily instances of [FileWriter].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  /**
+   * Static factory designed to expose `progress` events to event
+   * handlers that are not necessarily instances of [FileWriter].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> progressEvent =
+      const EventStreamProvider<ProgressEvent>('progress');
+
+  /**
+   * Static factory designed to expose `write` events to event
+   * handlers that are not necessarily instances of [FileWriter].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> writeEvent =
+      const EventStreamProvider<ProgressEvent>('write');
+
+  /**
+   * Static factory designed to expose `writeend` events to event
+   * handlers that are not necessarily instances of [FileWriter].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> writeEndEvent =
+      const EventStreamProvider<ProgressEvent>('writeend');
+
+  /**
+   * Static factory designed to expose `writestart` events to event
+   * handlers that are not necessarily instances of [FileWriter].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> writeStartEvent =
+      const EventStreamProvider<ProgressEvent>('writestart');
+
+  static const int DONE = 2;
+
+  static const int INIT = 0;
+
+  static const int WRITING = 1;
+
+  final DomException error;
+
+  final int length;
+
+  final int position;
+
+  final int readyState;
+
+  void abort() native;
+
+  void seek(int position) native;
+
+  void truncate(int size) native;
+
+  void write(Blob data) native;
+
+  /// Stream of `abort` events handled by this [FileWriter].
+  Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);
+
+  /// Stream of `error` events handled by this [FileWriter].
+  Stream<Event> get onError => errorEvent.forTarget(this);
+
+  /// Stream of `progress` events handled by this [FileWriter].
+  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
+
+  /// Stream of `write` events handled by this [FileWriter].
+  Stream<ProgressEvent> get onWrite => writeEvent.forTarget(this);
+
+  /// Stream of `writeend` events handled by this [FileWriter].
+  Stream<ProgressEvent> get onWriteEnd => writeEndEvent.forTarget(this);
+
+  /// Stream of `writestart` events handled by this [FileWriter].
+  Stream<ProgressEvent> get onWriteStart => writeStartEvent.forTarget(this);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void _FileWriterCallback(FileWriter fileWriter);
+// Copyright (c) 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.
+
+@Native("FocusEvent")
+class FocusEvent extends UIEvent {
+  // To suppress missing implicit constructor warnings.
+  factory FocusEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FocusEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return FocusEvent._create_1(type, eventInitDict_1);
+    }
+    return FocusEvent._create_2(type);
+  }
+  static FocusEvent _create_1(type, eventInitDict) =>
+      JS('FocusEvent', 'new FocusEvent(#,#)', type, eventInitDict);
+  static FocusEvent _create_2(type) =>
+      JS('FocusEvent', 'new FocusEvent(#)', type);
+
+  EventTarget get relatedTarget =>
+      _convertNativeToDart_EventTarget(this._get_relatedTarget);
+  @JSName('relatedTarget')
+  @Creates('Null')
+  final dynamic _get_relatedTarget;
+}
+// Copyright (c) 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.
+
+@Native("FontFace")
+class FontFace extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory FontFace._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FontFace(String family, Object source, [Map descriptors]) {
+    if (descriptors != null) {
+      var descriptors_1 = convertDartToNative_Dictionary(descriptors);
+      return FontFace._create_1(family, source, descriptors_1);
+    }
+    return FontFace._create_2(family, source);
+  }
+  static FontFace _create_1(family, source, descriptors) =>
+      JS('FontFace', 'new FontFace(#,#,#)', family, source, descriptors);
+  static FontFace _create_2(family, source) =>
+      JS('FontFace', 'new FontFace(#,#)', family, source);
+
+  String display;
+
+  String family;
+
+  String featureSettings;
+
+  Future<FontFace> get loaded =>
+      promiseToFuture<FontFace>(JS("", "#.loaded", this));
+
+  final String status;
+
+  String stretch;
+
+  String style;
+
+  String unicodeRange;
+
+  String variant;
+
+  String weight;
+
+  Future<FontFace> load() =>
+      promiseToFuture<FontFace>(JS("", "#.load()", this));
+}
+// Copyright (c) 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.
+
+@Native("FontFaceSet")
+class FontFaceSet extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory FontFaceSet._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<FontFaceSetLoadEvent> loadingEvent =
+      const EventStreamProvider<FontFaceSetLoadEvent>('loading');
+
+  static const EventStreamProvider<FontFaceSetLoadEvent> loadingDoneEvent =
+      const EventStreamProvider<FontFaceSetLoadEvent>('loadingdone');
+
+  static const EventStreamProvider<FontFaceSetLoadEvent> loadingErrorEvent =
+      const EventStreamProvider<FontFaceSetLoadEvent>('loadingerror');
+
+  final String status;
+
+  FontFaceSet add(FontFace arg) native;
+
+  bool check(String font, [String text]) native;
+
+  void clear() native;
+
+  bool delete(FontFace arg) native;
+
+  void forEach(FontFaceSetForEachCallback callback, [Object thisArg]) native;
+
+  bool has(FontFace arg) native;
+
+  Stream<FontFaceSetLoadEvent> get onLoading => loadingEvent.forTarget(this);
+
+  Stream<FontFaceSetLoadEvent> get onLoadingDone =>
+      loadingDoneEvent.forTarget(this);
+
+  Stream<FontFaceSetLoadEvent> get onLoadingError =>
+      loadingErrorEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("FontFaceSetLoadEvent")
+class FontFaceSetLoadEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory FontFaceSetLoadEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FontFaceSetLoadEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return FontFaceSetLoadEvent._create_1(type, eventInitDict_1);
+    }
+    return FontFaceSetLoadEvent._create_2(type);
+  }
+  static FontFaceSetLoadEvent _create_1(type, eventInitDict) => JS(
+      'FontFaceSetLoadEvent',
+      'new FontFaceSetLoadEvent(#,#)',
+      type,
+      eventInitDict);
+  static FontFaceSetLoadEvent _create_2(type) =>
+      JS('FontFaceSetLoadEvent', 'new FontFaceSetLoadEvent(#)', type);
+
+  final List<FontFace> fontfaces;
+}
+// Copyright (c) 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.
+
+@Native("FontFaceSource")
+class FontFaceSource extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory FontFaceSource._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final FontFaceSet fonts;
+}
+// Copyright (c) 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.
+
+@Native("ForeignFetchEvent")
+class ForeignFetchEvent extends ExtendableEvent {
+  // To suppress missing implicit constructor warnings.
+  factory ForeignFetchEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ForeignFetchEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return ForeignFetchEvent._create_1(type, eventInitDict_1);
+  }
+  static ForeignFetchEvent _create_1(type, eventInitDict) => JS(
+      'ForeignFetchEvent', 'new ForeignFetchEvent(#,#)', type, eventInitDict);
+
+  final String origin;
+
+  final _Request request;
+
+  void respondWith(Future r) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Native("FormData")
+class FormData extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory FormData._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FormData([FormElement form]) {
+    if (form != null) {
+      return FormData._create_1(form);
+    }
+    return FormData._create_2();
+  }
+  static FormData _create_1(form) => JS('FormData', 'new FormData(#)', form);
+  static FormData _create_2() => JS('FormData', 'new FormData()');
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(window.FormData)');
+
+  void append(String name, String value) native;
+
+  @JSName('append')
+  void appendBlob(String name, Blob value, [String filename]) native;
+
+  void delete(String name) native;
+
+  Object get(String name) native;
+
+  List<Object> getAll(String name) native;
+
+  bool has(String name) native;
+
+  void set(String name, value, [String filename]) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("HTMLFormElement")
+class FormElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory FormElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FormElement() => JS(
+      'returns:FormElement;creates:FormElement;new:true',
+      '#.createElement(#)',
+      document,
+      "form");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FormElement.created() : super.created();
+
+  String acceptCharset;
+
+  String action;
+
+  String autocomplete;
+
+  String encoding;
+
+  String enctype;
+
+  final int length;
+
+  String method;
+
+  String name;
+
+  bool noValidate;
+
+  String target;
+
+  Object __getter__(String name) native;
+
+  bool checkValidity() native;
+
+  Element item(int index) native;
+
+  bool reportValidity() native;
+
+  void requestAutocomplete(Map details) {
+    var details_1 = convertDartToNative_Dictionary(details);
+    _requestAutocomplete_1(details_1);
+    return;
+  }
+
+  @JSName('requestAutocomplete')
+  void _requestAutocomplete_1(details) native;
+
+  void reset() native;
+
+  void submit() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void FrameRequestCallback(num highResTime);
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void FunctionStringCallback(String data);
+// Copyright (c) 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.
+
+@Native("Gamepad")
+class Gamepad extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Gamepad._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final List<num> axes;
+
+  @Creates('JSExtendableArray|GamepadButton')
+  @Returns('JSExtendableArray')
+  final List<GamepadButton> buttons;
+
+  final bool connected;
+
+  final int displayId;
+
+  final String hand;
+
+  final String id;
+
+  final int index;
+
+  final String mapping;
+
+  final GamepadPose pose;
+
+  final int timestamp;
+}
+// Copyright (c) 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.
+
+@Native("GamepadButton")
+class GamepadButton extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory GamepadButton._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool pressed;
+
+  final bool touched;
+
+  final num value;
+}
+// Copyright (c) 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.
+
+@Native("GamepadEvent")
+class GamepadEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory GamepadEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory GamepadEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return GamepadEvent._create_1(type, eventInitDict_1);
+    }
+    return GamepadEvent._create_2(type);
+  }
+  static GamepadEvent _create_1(type, eventInitDict) =>
+      JS('GamepadEvent', 'new GamepadEvent(#,#)', type, eventInitDict);
+  static GamepadEvent _create_2(type) =>
+      JS('GamepadEvent', 'new GamepadEvent(#)', type);
+
+  final Gamepad gamepad;
+}
+// Copyright (c) 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.
+
+@Native("GamepadPose")
+class GamepadPose extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory GamepadPose._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final Float32List angularAcceleration;
+
+  final Float32List angularVelocity;
+
+  final bool hasOrientation;
+
+  final bool hasPosition;
+
+  final Float32List linearAcceleration;
+
+  final Float32List linearVelocity;
+
+  final Float32List orientation;
+
+  final Float32List position;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("Geolocation")
+class Geolocation extends Interceptor {
+  Future<Geoposition> getCurrentPosition(
+      {bool enableHighAccuracy, Duration timeout, Duration maximumAge}) {
+    var options = {};
+    if (enableHighAccuracy != null) {
+      options['enableHighAccuracy'] = enableHighAccuracy;
+    }
+    if (timeout != null) {
+      options['timeout'] = timeout.inMilliseconds;
+    }
+    if (maximumAge != null) {
+      options['maximumAge'] = maximumAge.inMilliseconds;
+    }
+    var completer = new Completer<Geoposition>();
+    try {
+      _getCurrentPosition((position) {
+        completer.complete(_ensurePosition(position));
+      }, (error) {
+        completer.completeError(error);
+      }, options);
+    } catch (e, stacktrace) {
+      completer.completeError(e, stacktrace);
+    }
+    return completer.future;
+  }
+
+  Stream<Geoposition> watchPosition(
+      {bool enableHighAccuracy, Duration timeout, Duration maximumAge}) {
+    var options = {};
+    if (enableHighAccuracy != null) {
+      options['enableHighAccuracy'] = enableHighAccuracy;
+    }
+    if (timeout != null) {
+      options['timeout'] = timeout.inMilliseconds;
+    }
+    if (maximumAge != null) {
+      options['maximumAge'] = maximumAge.inMilliseconds;
+    }
+
+    int watchId;
+    // TODO(jacobr): it seems like a bug that we have to specifiy the static
+    // type here for controller.stream to have the right type.
+    // dartbug.com/26278
+    StreamController<Geoposition> controller;
+    controller = new StreamController<Geoposition>(
+        sync: true,
+        onListen: () {
+          assert(watchId == null);
+          watchId = _watchPosition((position) {
+            controller.add(_ensurePosition(position));
+          }, (error) {
+            controller.addError(error);
+          }, options);
+        },
+        onCancel: () {
+          assert(watchId != null);
+          _clearWatch(watchId);
+        });
+
+    return controller.stream;
+  }
+
+  Geoposition _ensurePosition(domPosition) {
+    try {
+      // Firefox may throw on this.
+      if (domPosition is Geoposition) {
+        return domPosition;
+      }
+    } catch (e) {}
+    return new _GeopositionWrapper(domPosition);
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory Geolocation._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('clearWatch')
+  void _clearWatch(int watchID) native;
+
+  void _getCurrentPosition(_PositionCallback successCallback,
+      [_PositionErrorCallback errorCallback, Map options]) {
+    if (options != null) {
+      var successCallback_1 = convertDartClosureToJS(successCallback, 1);
+      var options_2 = convertDartToNative_Dictionary(options);
+      _getCurrentPosition_1(successCallback_1, errorCallback, options_2);
+      return;
+    }
+    if (errorCallback != null) {
+      var successCallback_1 = convertDartClosureToJS(successCallback, 1);
+      _getCurrentPosition_2(successCallback_1, errorCallback);
+      return;
+    }
+    var successCallback_1 = convertDartClosureToJS(successCallback, 1);
+    _getCurrentPosition_3(successCallback_1);
+    return;
+  }
+
+  @JSName('getCurrentPosition')
+  void _getCurrentPosition_1(
+      successCallback, _PositionErrorCallback errorCallback, options) native;
+  @JSName('getCurrentPosition')
+  void _getCurrentPosition_2(
+      successCallback, _PositionErrorCallback errorCallback) native;
+  @JSName('getCurrentPosition')
+  void _getCurrentPosition_3(successCallback) native;
+
+  int _watchPosition(_PositionCallback successCallback,
+      [_PositionErrorCallback errorCallback, Map options]) {
+    if (options != null) {
+      var successCallback_1 = convertDartClosureToJS(successCallback, 1);
+      var options_2 = convertDartToNative_Dictionary(options);
+      return _watchPosition_1(successCallback_1, errorCallback, options_2);
+    }
+    if (errorCallback != null) {
+      var successCallback_1 = convertDartClosureToJS(successCallback, 1);
+      return _watchPosition_2(successCallback_1, errorCallback);
+    }
+    var successCallback_1 = convertDartClosureToJS(successCallback, 1);
+    return _watchPosition_3(successCallback_1);
+  }
+
+  @JSName('watchPosition')
+  int _watchPosition_1(
+      successCallback, _PositionErrorCallback errorCallback, options) native;
+  @JSName('watchPosition')
+  int _watchPosition_2(successCallback, _PositionErrorCallback errorCallback)
+      native;
+  @JSName('watchPosition')
+  int _watchPosition_3(successCallback) native;
+}
+
+/**
+ * Wrapper for Firefox- it returns an object which we cannot map correctly.
+ * Basically Firefox was returning a [xpconnect wrapped nsIDOMGeoPosition] but
+ * which has further oddities.
+ */
+class _GeopositionWrapper implements Geoposition {
+  var _ptr;
+  _GeopositionWrapper(this._ptr);
+
+  Coordinates get coords => JS('Coordinates', '#.coords', _ptr);
+  int get timestamp => JS('int', '#.timestamp', _ptr);
+}
+// Copyright (c) 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.
+
+@Native("Position")
+class Geoposition extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Geoposition._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final Coordinates coords;
+
+  final int timestamp;
+}
+// Copyright (c) 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.
+
+// We implement EventTarget and have stubs for its methods because it's tricky to
+// convince the scripts to make our instance methods abstract, and the bodies that
+// get generated require `this` to be an EventTarget.
+abstract class GlobalEventHandlers implements EventTarget {
+  void addEventListener(String type, dynamic listener(Event event),
+      [bool useCapture]);
+  bool dispatchEvent(Event event);
+  void removeEventListener(String type, dynamic listener(Event event),
+      [bool useCapture]);
+  Events get on;
+
+  // To suppress missing implicit constructor warnings.
+  factory GlobalEventHandlers._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> abortEvent =
+      const EventStreamProvider<Event>('abort');
+
+  static const EventStreamProvider<Event> blurEvent =
+      const EventStreamProvider<Event>('blur');
+
+  static const EventStreamProvider<Event> canPlayEvent =
+      const EventStreamProvider<Event>('canplay');
+
+  static const EventStreamProvider<Event> canPlayThroughEvent =
+      const EventStreamProvider<Event>('canplaythrough');
+
+  static const EventStreamProvider<Event> changeEvent =
+      const EventStreamProvider<Event>('change');
+
+  static const EventStreamProvider<MouseEvent> clickEvent =
+      const EventStreamProvider<MouseEvent>('click');
+
+  static const EventStreamProvider<MouseEvent> contextMenuEvent =
+      const EventStreamProvider<MouseEvent>('contextmenu');
+
+  @DomName('GlobalEventHandlers.dblclickEvent')
+  static const EventStreamProvider<Event> doubleClickEvent =
+      const EventStreamProvider<Event>('dblclick');
+
+  static const EventStreamProvider<MouseEvent> dragEvent =
+      const EventStreamProvider<MouseEvent>('drag');
+
+  static const EventStreamProvider<MouseEvent> dragEndEvent =
+      const EventStreamProvider<MouseEvent>('dragend');
+
+  static const EventStreamProvider<MouseEvent> dragEnterEvent =
+      const EventStreamProvider<MouseEvent>('dragenter');
+
+  static const EventStreamProvider<MouseEvent> dragLeaveEvent =
+      const EventStreamProvider<MouseEvent>('dragleave');
+
+  static const EventStreamProvider<MouseEvent> dragOverEvent =
+      const EventStreamProvider<MouseEvent>('dragover');
+
+  static const EventStreamProvider<MouseEvent> dragStartEvent =
+      const EventStreamProvider<MouseEvent>('dragstart');
+
+  static const EventStreamProvider<MouseEvent> dropEvent =
+      const EventStreamProvider<MouseEvent>('drop');
+
+  static const EventStreamProvider<Event> durationChangeEvent =
+      const EventStreamProvider<Event>('durationchange');
+
+  static const EventStreamProvider<Event> emptiedEvent =
+      const EventStreamProvider<Event>('emptied');
+
+  static const EventStreamProvider<Event> endedEvent =
+      const EventStreamProvider<Event>('ended');
+
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  static const EventStreamProvider<Event> focusEvent =
+      const EventStreamProvider<Event>('focus');
+
+  static const EventStreamProvider<Event> inputEvent =
+      const EventStreamProvider<Event>('input');
+
+  static const EventStreamProvider<Event> invalidEvent =
+      const EventStreamProvider<Event>('invalid');
+
+  static const EventStreamProvider<KeyboardEvent> keyDownEvent =
+      const EventStreamProvider<KeyboardEvent>('keydown');
+
+  static const EventStreamProvider<KeyboardEvent> keyPressEvent =
+      const EventStreamProvider<KeyboardEvent>('keypress');
+
+  static const EventStreamProvider<KeyboardEvent> keyUpEvent =
+      const EventStreamProvider<KeyboardEvent>('keyup');
+
+  static const EventStreamProvider<Event> loadEvent =
+      const EventStreamProvider<Event>('load');
+
+  static const EventStreamProvider<Event> loadedDataEvent =
+      const EventStreamProvider<Event>('loadeddata');
+
+  static const EventStreamProvider<Event> loadedMetadataEvent =
+      const EventStreamProvider<Event>('loadedmetadata');
+
+  static const EventStreamProvider<MouseEvent> mouseDownEvent =
+      const EventStreamProvider<MouseEvent>('mousedown');
+
+  static const EventStreamProvider<MouseEvent> mouseEnterEvent =
+      const EventStreamProvider<MouseEvent>('mouseenter');
+
+  static const EventStreamProvider<MouseEvent> mouseLeaveEvent =
+      const EventStreamProvider<MouseEvent>('mouseleave');
+
+  static const EventStreamProvider<MouseEvent> mouseMoveEvent =
+      const EventStreamProvider<MouseEvent>('mousemove');
+
+  static const EventStreamProvider<MouseEvent> mouseOutEvent =
+      const EventStreamProvider<MouseEvent>('mouseout');
+
+  static const EventStreamProvider<MouseEvent> mouseOverEvent =
+      const EventStreamProvider<MouseEvent>('mouseover');
+
+  static const EventStreamProvider<MouseEvent> mouseUpEvent =
+      const EventStreamProvider<MouseEvent>('mouseup');
+
+  static const EventStreamProvider<WheelEvent> mouseWheelEvent =
+      const EventStreamProvider<WheelEvent>('mousewheel');
+
+  static const EventStreamProvider<Event> pauseEvent =
+      const EventStreamProvider<Event>('pause');
+
+  static const EventStreamProvider<Event> playEvent =
+      const EventStreamProvider<Event>('play');
+
+  static const EventStreamProvider<Event> playingEvent =
+      const EventStreamProvider<Event>('playing');
+
+  static const EventStreamProvider<Event> rateChangeEvent =
+      const EventStreamProvider<Event>('ratechange');
+
+  static const EventStreamProvider<Event> resetEvent =
+      const EventStreamProvider<Event>('reset');
+
+  static const EventStreamProvider<Event> resizeEvent =
+      const EventStreamProvider<Event>('resize');
+
+  static const EventStreamProvider<Event> scrollEvent =
+      const EventStreamProvider<Event>('scroll');
+
+  static const EventStreamProvider<Event> seekedEvent =
+      const EventStreamProvider<Event>('seeked');
+
+  static const EventStreamProvider<Event> seekingEvent =
+      const EventStreamProvider<Event>('seeking');
+
+  static const EventStreamProvider<Event> selectEvent =
+      const EventStreamProvider<Event>('select');
+
+  static const EventStreamProvider<Event> stalledEvent =
+      const EventStreamProvider<Event>('stalled');
+
+  static const EventStreamProvider<Event> submitEvent =
+      const EventStreamProvider<Event>('submit');
+
+  static const EventStreamProvider<Event> suspendEvent =
+      const EventStreamProvider<Event>('suspend');
+
+  static const EventStreamProvider<Event> timeUpdateEvent =
+      const EventStreamProvider<Event>('timeupdate');
+
+  static const EventStreamProvider<TouchEvent> touchCancelEvent =
+      const EventStreamProvider<TouchEvent>('touchcancel');
+
+  static const EventStreamProvider<TouchEvent> touchEndEvent =
+      const EventStreamProvider<TouchEvent>('touchend');
+
+  static const EventStreamProvider<TouchEvent> touchMoveEvent =
+      const EventStreamProvider<TouchEvent>('touchmove');
+
+  static const EventStreamProvider<TouchEvent> touchStartEvent =
+      const EventStreamProvider<TouchEvent>('touchstart');
+
+  static const EventStreamProvider<Event> volumeChangeEvent =
+      const EventStreamProvider<Event>('volumechange');
+
+  static const EventStreamProvider<Event> waitingEvent =
+      const EventStreamProvider<Event>('waiting');
+
+  static const EventStreamProvider<WheelEvent> wheelEvent =
+      const EventStreamProvider<WheelEvent>('wheel');
+
+  Stream<Event> get onAbort => abortEvent.forTarget(this);
+
+  Stream<Event> get onBlur => blurEvent.forTarget(this);
+
+  Stream<Event> get onCanPlay => canPlayEvent.forTarget(this);
+
+  Stream<Event> get onCanPlayThrough => canPlayThroughEvent.forTarget(this);
+
+  Stream<Event> get onChange => changeEvent.forTarget(this);
+
+  Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
+
+  Stream<MouseEvent> get onContextMenu => contextMenuEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.ondblclick')
+  Stream<Event> get onDoubleClick => doubleClickEvent.forTarget(this);
+
+  Stream<MouseEvent> get onDrag => dragEvent.forTarget(this);
+
+  Stream<MouseEvent> get onDragEnd => dragEndEvent.forTarget(this);
+
+  Stream<MouseEvent> get onDragEnter => dragEnterEvent.forTarget(this);
+
+  Stream<MouseEvent> get onDragLeave => dragLeaveEvent.forTarget(this);
+
+  Stream<MouseEvent> get onDragOver => dragOverEvent.forTarget(this);
+
+  Stream<MouseEvent> get onDragStart => dragStartEvent.forTarget(this);
+
+  Stream<MouseEvent> get onDrop => dropEvent.forTarget(this);
+
+  Stream<Event> get onDurationChange => durationChangeEvent.forTarget(this);
+
+  Stream<Event> get onEmptied => emptiedEvent.forTarget(this);
+
+  Stream<Event> get onEnded => endedEvent.forTarget(this);
+
+  Stream<Event> get onError => errorEvent.forTarget(this);
+
+  Stream<Event> get onFocus => focusEvent.forTarget(this);
+
+  Stream<Event> get onInput => inputEvent.forTarget(this);
+
+  Stream<Event> get onInvalid => invalidEvent.forTarget(this);
+
+  Stream<KeyboardEvent> get onKeyDown => keyDownEvent.forTarget(this);
+
+  Stream<KeyboardEvent> get onKeyPress => keyPressEvent.forTarget(this);
+
+  Stream<KeyboardEvent> get onKeyUp => keyUpEvent.forTarget(this);
+
+  Stream<Event> get onLoad => loadEvent.forTarget(this);
+
+  Stream<Event> get onLoadedData => loadedDataEvent.forTarget(this);
+
+  Stream<Event> get onLoadedMetadata => loadedMetadataEvent.forTarget(this);
+
+  Stream<MouseEvent> get onMouseDown => mouseDownEvent.forTarget(this);
+
+  Stream<MouseEvent> get onMouseEnter => mouseEnterEvent.forTarget(this);
+
+  Stream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forTarget(this);
+
+  Stream<MouseEvent> get onMouseMove => mouseMoveEvent.forTarget(this);
+
+  Stream<MouseEvent> get onMouseOut => mouseOutEvent.forTarget(this);
+
+  Stream<MouseEvent> get onMouseOver => mouseOverEvent.forTarget(this);
+
+  Stream<MouseEvent> get onMouseUp => mouseUpEvent.forTarget(this);
+
+  Stream<WheelEvent> get onMouseWheel => mouseWheelEvent.forTarget(this);
+
+  Stream<Event> get onPause => pauseEvent.forTarget(this);
+
+  Stream<Event> get onPlay => playEvent.forTarget(this);
+
+  Stream<Event> get onPlaying => playingEvent.forTarget(this);
+
+  Stream<Event> get onRateChange => rateChangeEvent.forTarget(this);
+
+  Stream<Event> get onReset => resetEvent.forTarget(this);
+
+  Stream<Event> get onResize => resizeEvent.forTarget(this);
+
+  Stream<Event> get onScroll => scrollEvent.forTarget(this);
+
+  Stream<Event> get onSeeked => seekedEvent.forTarget(this);
+
+  Stream<Event> get onSeeking => seekingEvent.forTarget(this);
+
+  Stream<Event> get onSelect => selectEvent.forTarget(this);
+
+  Stream<Event> get onStalled => stalledEvent.forTarget(this);
+
+  Stream<Event> get onSubmit => submitEvent.forTarget(this);
+
+  Stream<Event> get onSuspend => suspendEvent.forTarget(this);
+
+  Stream<Event> get onTimeUpdate => timeUpdateEvent.forTarget(this);
+
+  Stream<TouchEvent> get onTouchCancel => touchCancelEvent.forTarget(this);
+
+  Stream<TouchEvent> get onTouchEnd => touchEndEvent.forTarget(this);
+
+  Stream<TouchEvent> get onTouchMove => touchMoveEvent.forTarget(this);
+
+  Stream<TouchEvent> get onTouchStart => touchStartEvent.forTarget(this);
+
+  Stream<Event> get onVolumeChange => volumeChangeEvent.forTarget(this);
+
+  Stream<Event> get onWaiting => waitingEvent.forTarget(this);
+
+  Stream<WheelEvent> get onWheel => wheelEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("Gyroscope")
+class Gyroscope extends Sensor {
+  // To suppress missing implicit constructor warnings.
+  factory Gyroscope._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory Gyroscope([Map sensorOptions]) {
+    if (sensorOptions != null) {
+      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
+      return Gyroscope._create_1(sensorOptions_1);
+    }
+    return Gyroscope._create_2();
+  }
+  static Gyroscope _create_1(sensorOptions) =>
+      JS('Gyroscope', 'new Gyroscope(#)', sensorOptions);
+  static Gyroscope _create_2() => JS('Gyroscope', 'new Gyroscope()');
+
+  final num x;
+
+  final num y;
+
+  final num z;
+}
+// Copyright (c) 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.
+
+/**
+ * An `<hr>` tag.
+ */
+@Native("HTMLHRElement")
+class HRElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory HRElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory HRElement() => JS('returns:HRElement;creates:HRElement;new:true',
+      '#.createElement(#)', document, "hr");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  HRElement.created() : super.created();
+
+  String color;
+}
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("HashChangeEvent")
+class HashChangeEvent extends Event {
+  factory HashChangeEvent(String type,
+      {bool canBubble: true,
+      bool cancelable: true,
+      String oldUrl,
+      String newUrl}) {
+    var options = {
+      'canBubble': canBubble,
+      'cancelable': cancelable,
+      'oldURL': oldUrl,
+      'newURL': newUrl,
+    };
+    return JS('HashChangeEvent', 'new HashChangeEvent(#, #)', type,
+        convertDartToNative_Dictionary(options));
+  }
+
+  factory HashChangeEvent._(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return HashChangeEvent._create_1(type, eventInitDict_1);
+    }
+    return HashChangeEvent._create_2(type);
+  }
+  static HashChangeEvent _create_1(type, eventInitDict) =>
+      JS('HashChangeEvent', 'new HashChangeEvent(#,#)', type, eventInitDict);
+  static HashChangeEvent _create_2(type) =>
+      JS('HashChangeEvent', 'new HashChangeEvent(#)', type);
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => Device.isEventTypeSupported('HashChangeEvent');
+
+  @JSName('newURL')
+  final String newUrl;
+
+  @JSName('oldURL')
+  final String oldUrl;
+}
+// Copyright (c) 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.
+
+@Native("HTMLHeadElement")
+class HeadElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory HeadElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory HeadElement() => JS(
+      'returns:HeadElement;creates:HeadElement;new:true',
+      '#.createElement(#)',
+      document,
+      "head");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  HeadElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Native("Headers")
+class Headers extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Headers._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory Headers([Object init]) {
+    if (init != null) {
+      return Headers._create_1(init);
+    }
+    return Headers._create_2();
+  }
+  static Headers _create_1(init) => JS('Headers', 'new Headers(#)', init);
+  static Headers _create_2() => JS('Headers', 'new Headers()');
+}
+// Copyright (c) 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.
+
+@Native("HTMLHeadingElement")
+class HeadingElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory HeadingElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory HeadingElement.h1() => JS(
+      'returns:HeadingElement;creates:HeadingElement;new:true',
+      '#.createElement(#)',
+      document,
+      "h1");
+
+  factory HeadingElement.h2() => JS(
+      'returns:HeadingElement;creates:HeadingElement;new:true',
+      '#.createElement(#)',
+      document,
+      "h2");
+
+  factory HeadingElement.h3() => JS(
+      'returns:HeadingElement;creates:HeadingElement;new:true',
+      '#.createElement(#)',
+      document,
+      "h3");
+
+  factory HeadingElement.h4() => JS(
+      'returns:HeadingElement;creates:HeadingElement;new:true',
+      '#.createElement(#)',
+      document,
+      "h4");
+
+  factory HeadingElement.h5() => JS(
+      'returns:HeadingElement;creates:HeadingElement;new:true',
+      '#.createElement(#)',
+      document,
+      "h5");
+
+  factory HeadingElement.h6() => JS(
+      'returns:HeadingElement;creates:HeadingElement;new:true',
+      '#.createElement(#)',
+      document,
+      "h6");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  HeadingElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Native("History")
+class History extends Interceptor implements HistoryBase {
+  /**
+   * Checks if the State APIs are supported on the current platform.
+   *
+   * See also:
+   *
+   * * [pushState]
+   * * [replaceState]
+   * * [state]
+   */
+  static bool get supportsState => JS('bool', '!!window.history.pushState');
+  // To suppress missing implicit constructor warnings.
+  factory History._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int length;
+
+  String scrollRestoration;
+
+  dynamic get state =>
+      convertNativeToDart_SerializedScriptValue(this._get_state);
+  @JSName('state')
+  @annotation_Creates_SerializedScriptValue
+  @annotation_Returns_SerializedScriptValue
+  final dynamic _get_state;
+
+  void back() native;
+
+  void forward() native;
+
+  void go([int delta]) native;
+
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void pushState(/*SerializedScriptValue*/ data, String title, String url) {
+    var data_1 = convertDartToNative_SerializedScriptValue(data);
+    _pushState_1(data_1, title, url);
+    return;
+  }
+
+  @JSName('pushState')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void _pushState_1(data, title, url) native;
+
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void replaceState(/*SerializedScriptValue*/ data, String title, String url) {
+    var data_1 = convertDartToNative_SerializedScriptValue(data);
+    _replaceState_1(data_1, title, url);
+    return;
+  }
+
+  @JSName('replaceState')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void _replaceState_1(data, title, url) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("HTMLCollection")
+class HtmlCollection extends Interceptor
+    with ListMixin<Node>, ImmutableListMixin<Node>
+    implements JavaScriptIndexingBehavior<Node>, List<Node> {
+  // To suppress missing implicit constructor warnings.
+  factory HtmlCollection._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  Node operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return JS("Node", "#[#]", this, index);
+  }
+
+  void operator []=(int index, Node value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<Node> mixins.
+  // Node is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  Node get first {
+    if (this.length > 0) {
+      return JS('Node', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  Node get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('Node', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  Node get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('Node', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  Node elementAt(int index) => this[index];
+  // -- end List<Node> mixins.
+
+  Node item(int index) native;
+
+  Object namedItem(String name) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@Native("HTMLDocument")
+class HtmlDocument extends Document {
+  // To suppress missing implicit constructor warnings.
+  factory HtmlDocument._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  BodyElement body;
+
+  /// UNSTABLE: Chrome-only - create a Range from the given point.
+  @Unstable()
+  Range caretRangeFromPoint(int x, int y) {
+    return _caretRangeFromPoint(x, y);
+  }
+
+  Element elementFromPoint(int x, int y) {
+    return _elementFromPoint(x, y);
+  }
+
+  HeadElement get head => _head;
+
+  String get lastModified => _lastModified;
+
+  String get preferredStylesheetSet => _preferredStylesheetSet;
+
+  String get referrer => _referrer;
+
+  String get selectedStylesheetSet => _selectedStylesheetSet;
+  set selectedStylesheetSet(String value) {
+    _selectedStylesheetSet = value;
+  }
+
+  List<StyleSheet> get styleSheets => _styleSheets;
+
+  String get title => _title;
+
+  set title(String value) {
+    _title = value;
+  }
+
+  /**
+   * Returns page to standard layout.
+   *
+   * Has no effect if the page is not in fullscreen mode.
+   *
+   * ## Other resources
+   *
+   * * [Fullscreen
+   *   API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API)
+   *   from MDN.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void exitFullscreen() {
+    _webkitExitFullscreen();
+  }
+
+  /**
+   * Register a custom subclass of Element to be instantiatable by the DOM.
+   *
+   * This is necessary to allow the construction of any custom elements.
+   *
+   * The class being registered must either subclass HtmlElement or SvgElement.
+   * If they subclass these directly then they can be used as:
+   *
+   *     class FooElement extends HtmlElement{
+   *        void created() {
+   *          print('FooElement created!');
+   *        }
+   *     }
+   *
+   *     main() {
+   *       document.registerElement('x-foo', FooElement);
+   *       var myFoo = new Element.tag('x-foo');
+   *       // prints 'FooElement created!' to the console.
+   *     }
+   *
+   * The custom element can also be instantiated via HTML using the syntax
+   * `<x-foo></x-foo>`
+   *
+   * Other elements can be subclassed as well:
+   *
+   *     class BarElement extends InputElement{
+   *        void created() {
+   *          print('BarElement created!');
+   *        }
+   *     }
+   *
+   *     main() {
+   *       document.registerElement('x-bar', BarElement);
+   *       var myBar = new Element.tag('input', 'x-bar');
+   *       // prints 'BarElement created!' to the console.
+   *     }
+   *
+   * This custom element can also be instantiated via HTML using the syntax
+   * `<input is="x-bar"></input>`
+   *
+   */
+  Function registerElement2(String tag, [Map options]) {
+    return _registerCustomElement(JS('', 'window'), this, tag, options);
+  }
+
+  /** *Deprecated*: use [registerElement] instead. */
+  @deprecated
+  void register(String tag, Type customElementClass, {String extendsTag}) {
+    return registerElement(tag, customElementClass, extendsTag: extendsTag);
+  }
+
+  /**
+   * Static factory designed to expose `visibilitychange` events to event
+   * handlers that are not necessarily instances of [Document].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  static const EventStreamProvider<Event> visibilityChangeEvent =
+      const _CustomEventStreamProvider<Event>(
+          _determineVisibilityChangeEventType);
+
+  static String _determineVisibilityChangeEventType(EventTarget e) {
+    if (JS('bool', '(typeof #.hidden !== "undefined")', e)) {
+      // Opera 12.10 and Firefox 18 and later support
+      return 'visibilitychange';
+    } else if (JS('bool', '(typeof #.mozHidden !== "undefined")', e)) {
+      return 'mozvisibilitychange';
+    } else if (JS('bool', '(typeof #.msHidden !== "undefined")', e)) {
+      return 'msvisibilitychange';
+    } else if (JS('bool', '(typeof #.webkitHidden !== "undefined")', e)) {
+      return 'webkitvisibilitychange';
+    }
+    return 'visibilitychange';
+  }
+
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  Stream<Event> get onVisibilityChange => visibilityChangeEvent.forTarget(this);
+
+  /// Creates an element upgrader which can be used to change the Dart wrapper
+  /// type for elements.
+  ///
+  /// The type specified must be a subclass of HtmlElement, when an element is
+  /// upgraded then the created constructor will be invoked on that element.
+  ///
+  /// If the type is not a direct subclass of HtmlElement then the extendsTag
+  /// parameter must be provided.
+  ElementUpgrader createElementUpgrader(Type type, {String extendsTag}) {
+    return new _JSElementUpgrader(this, type, extendsTag);
+  }
+}
+// Copyright (c) 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.
+
+@Native("HTMLFormControlsCollection")
+class HtmlFormControlsCollection extends HtmlCollection {
+  // To suppress missing implicit constructor warnings.
+  factory HtmlFormControlsCollection._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Node item(int index) native;
+
+  Object namedItem(String name) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("HTMLHtmlElement")
+class HtmlHtmlElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory HtmlHtmlElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory HtmlHtmlElement() => JS(
+      'returns:HtmlHtmlElement;creates:HtmlHtmlElement;new:true',
+      '#.createElement(#)',
+      document,
+      "html");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  HtmlHtmlElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Native("HTMLHyperlinkElementUtils")
+class HtmlHyperlinkElementUtils extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory HtmlHyperlinkElementUtils._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  String hash;
+
+  String host;
+
+  String hostname;
+
+  String href;
+
+  final String origin;
+
+  String password;
+
+  String pathname;
+
+  String port;
+
+  String protocol;
+
+  String search;
+
+  String username;
+}
+// Copyright (c) 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.
+
+@Native("HTMLOptionsCollection")
+class HtmlOptionsCollection extends HtmlCollection {
+  // To suppress missing implicit constructor warnings.
+  factory HtmlOptionsCollection._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('item')
+  Element _item(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+  * A client-side XHR request for getting data from a URL,
+  * formally known as XMLHttpRequest.
+  *
+  * HttpRequest can be used to obtain data from HTTP and FTP protocols,
+  * and is useful for AJAX-style page updates.
+  *
+  * The simplest way to get the contents of a text file, such as a
+  * JSON-formatted file, is with [getString].
+  * For example, the following code gets the contents of a JSON file
+  * and prints its length:
+  *
+  *     var path = 'myData.json';
+  *     HttpRequest.getString(path).then((String fileContents) {
+  *       print(fileContents.length);
+  *     }).catchError((error) {
+  *       print(error.toString());
+  *     });
+  *
+  * ## Fetching data from other servers
+  *
+  * For security reasons, browsers impose restrictions on requests
+  * made by embedded apps.
+  * With the default behavior of this class,
+  * the code making the request must be served from the same origin
+  * (domain name, port, and application layer protocol)
+  * as the requested resource.
+  * In the example above, the myData.json file must be co-located with the
+  * app that uses it.
+  * You might be able to
+  * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#a-note-on-cors-and-httprequest)
+  * by using CORS headers or JSONP.
+  *
+  * ## Other resources
+  *
+  * * [Fetch Data Dynamically](https://www.dartlang.org/docs/tutorials/fetchdata/),
+  * a tutorial from _A Game of Darts_,
+  * shows two different ways to use HttpRequest to get a JSON file.
+  * * [Get Input from a Form](https://www.dartlang.org/docs/tutorials/forms/),
+  * another tutorial from _A Game of Darts_,
+  * shows using HttpRequest with a custom server.
+  * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
+  * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
+  * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
+ */
+@Native("XMLHttpRequest")
+class HttpRequest extends HttpRequestEventTarget {
+  /**
+   * Creates a GET request for the specified [url].
+   *
+   * This is similar to [request] but specialized for HTTP GET requests which
+   * return text content.
+   *
+   * To add query parameters, append them to the [url] following a `?`,
+   * joining each key to its value with `=` and separating key-value pairs with
+   * `&`.
+   *
+   *     var name = Uri.encodeQueryComponent('John');
+   *     var id = Uri.encodeQueryComponent('42');
+   *     HttpRequest.getString('users.json?name=$name&id=$id')
+   *       .then((String resp) {
+   *         // Do something with the response.
+   *     });
+   *
+   * See also:
+   *
+   * * [request]
+   */
+  static Future<String> getString(String url,
+      {bool withCredentials, void onProgress(ProgressEvent e)}) {
+    return request(url,
+            withCredentials: withCredentials, onProgress: onProgress)
+        .then((HttpRequest xhr) => xhr.responseText);
+  }
+
+  /**
+   * Makes a server POST request with the specified data encoded as form data.
+   *
+   * This is roughly the POST equivalent of [getString]. This method is similar
+   * to sending a [FormData] object with broader browser support but limited to
+   * String values.
+   *
+   * If [data] is supplied, the key/value pairs are URI encoded with
+   * [Uri.encodeQueryComponent] and converted into an HTTP query string.
+   *
+   * Unless otherwise specified, this method appends the following header:
+   *
+   *     Content-Type: application/x-www-form-urlencoded; charset=UTF-8
+   *
+   * Here's an example of using this method:
+   *
+   *     var data = { 'firstName' : 'John', 'lastName' : 'Doe' };
+   *     HttpRequest.postFormData('/send', data).then((HttpRequest resp) {
+   *       // Do something with the response.
+   *     });
+   *
+   * See also:
+   *
+   * * [request]
+   */
+  static Future<HttpRequest> postFormData(String url, Map<String, String> data,
+      {bool withCredentials,
+      String responseType,
+      Map<String, String> requestHeaders,
+      void onProgress(ProgressEvent e)}) {
+    var parts = [];
+    data.forEach((key, value) {
+      parts.add('${Uri.encodeQueryComponent(key)}='
+          '${Uri.encodeQueryComponent(value)}');
+    });
+    var formData = parts.join('&');
+
+    if (requestHeaders == null) {
+      requestHeaders = <String, String>{};
+    }
+    requestHeaders.putIfAbsent('Content-Type',
+        () => 'application/x-www-form-urlencoded; charset=UTF-8');
+
+    return request(url,
+        method: 'POST',
+        withCredentials: withCredentials,
+        responseType: responseType,
+        requestHeaders: requestHeaders,
+        sendData: formData,
+        onProgress: onProgress);
+  }
+
+  /**
+   * Creates and sends a URL request for the specified [url].
+   *
+   * By default `request` will perform an HTTP GET request, but a different
+   * method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the
+   * [method] parameter. (See also [HttpRequest.postFormData] for `POST` 
+   * requests only.
+   *
+   * The Future is completed when the response is available.
+   *
+   * If specified, `sendData` will send data in the form of a [ByteBuffer],
+   * [Blob], [Document], [String], or [FormData] along with the HttpRequest.
+   *
+   * If specified, [responseType] sets the desired response format for the
+   * request. By default it is [String], but can also be 'arraybuffer', 'blob', 
+   * 'document', 'json', or 'text'. See also [HttpRequest.responseType] 
+   * for more information.
+   *
+   * The [withCredentials] parameter specified that credentials such as a cookie
+   * (already) set in the header or
+   * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2)
+   * should be specified for the request. Details to keep in mind when using
+   * credentials:
+   *
+   * * Using credentials is only useful for cross-origin requests.
+   * * The `Access-Control-Allow-Origin` header of `url` cannot contain a wildcard (*).
+   * * The `Access-Control-Allow-Credentials` header of `url` must be set to true.
+   * * If `Access-Control-Expose-Headers` has not been set to true, only a subset of all the response headers will be returned when calling [getAllRequestHeaders].
+   *
+   * The following is equivalent to the [getString] sample above:
+   *
+   *     var name = Uri.encodeQueryComponent('John');
+   *     var id = Uri.encodeQueryComponent('42');
+   *     HttpRequest.request('users.json?name=$name&id=$id')
+   *       .then((HttpRequest resp) {
+   *         // Do something with the response.
+   *     });
+   *
+   * Here's an example of submitting an entire form with [FormData].
+   *
+   *     var myForm = querySelector('form#myForm');
+   *     var data = new FormData(myForm);
+   *     HttpRequest.request('/submit', method: 'POST', sendData: data)
+   *       .then((HttpRequest resp) {
+   *         // Do something with the response.
+   *     });
+   *
+   * Note that requests for file:// URIs are only supported by Chrome extensions
+   * with appropriate permissions in their manifest. Requests to file:// URIs
+   * will also never fail- the Future will always complete successfully, even
+   * when the file cannot be found.
+   *
+   * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication).
+   */
+  static Future<HttpRequest> request(String url,
+      {String method,
+      bool withCredentials,
+      String responseType,
+      String mimeType,
+      Map<String, String> requestHeaders,
+      sendData,
+      void onProgress(ProgressEvent e)}) {
+    var completer = new Completer<HttpRequest>();
+
+    var xhr = new HttpRequest();
+    if (method == null) {
+      method = 'GET';
+    }
+    xhr.open(method, url, async: true);
+
+    if (withCredentials != null) {
+      xhr.withCredentials = withCredentials;
+    }
+
+    if (responseType != null) {
+      xhr.responseType = responseType;
+    }
+
+    if (mimeType != null) {
+      xhr.overrideMimeType(mimeType);
+    }
+
+    if (requestHeaders != null) {
+      requestHeaders.forEach((header, value) {
+        xhr.setRequestHeader(header, value);
+      });
+    }
+
+    if (onProgress != null) {
+      xhr.onProgress.listen(onProgress);
+    }
+
+    xhr.onLoad.listen((e) {
+      var accepted = xhr.status >= 200 && xhr.status < 300;
+      var fileUri = xhr.status == 0; // file:// URIs have status of 0.
+      var notModified = xhr.status == 304;
+      // Redirect status is specified up to 307, but others have been used in
+      // practice. Notably Google Drive uses 308 Resume Incomplete for
+      // resumable uploads, and it's also been used as a redirect. The
+      // redirect case will be handled by the browser before it gets to us,
+      // so if we see it we should pass it through to the user.
+      var unknownRedirect = xhr.status > 307 && xhr.status < 400;
+
+      if (accepted || fileUri || notModified || unknownRedirect) {
+        completer.complete(xhr);
+      } else {
+        completer.completeError(e);
+      }
+    });
+
+    xhr.onError.listen(completer.completeError);
+
+    if (sendData != null) {
+      xhr.send(sendData);
+    } else {
+      xhr.send();
+    }
+
+    return completer.future;
+  }
+
+  /**
+   * Checks to see if the Progress event is supported on the current platform.
+   */
+  static bool get supportsProgressEvent {
+    var xhr = new HttpRequest();
+    return JS('bool', '("onprogress" in #)', xhr);
+  }
+
+  /**
+   * Checks to see if the current platform supports making cross origin
+   * requests.
+   *
+   * Note that even if cross origin requests are supported, they still may fail
+   * if the destination server does not support CORS requests.
+   */
+  static bool get supportsCrossOrigin {
+    var xhr = new HttpRequest();
+    return JS('bool', '("withCredentials" in #)', xhr);
+  }
+
+  /**
+   * Checks to see if the LoadEnd event is supported on the current platform.
+   */
+  static bool get supportsLoadEndEvent {
+    var xhr = new HttpRequest();
+    return JS('bool', '("onloadend" in #)', xhr);
+  }
+
+  /**
+   * Checks to see if the overrideMimeType method is supported on the current
+   * platform.
+   */
+  static bool get supportsOverrideMimeType {
+    var xhr = new HttpRequest();
+    return JS('bool', '("overrideMimeType" in #)', xhr);
+  }
+
+  /**
+   * Makes a cross-origin request to the specified URL.
+   *
+   * This API provides a subset of [request] which works on IE9. If IE9
+   * cross-origin support is not required then [request] should be used instead.
+   */
+  static Future<String> requestCrossOrigin(String url,
+      {String method, String sendData}) {
+    if (supportsCrossOrigin) {
+      return request(url, method: method, sendData: sendData).then((xhr) {
+        return xhr.responseText;
+      });
+    }
+    var completer = new Completer<String>();
+    if (method == null) {
+      method = 'GET';
+    }
+    var xhr = JS('var', 'new XDomainRequest()');
+    JS('', '#.open(#, #)', xhr, method, url);
+    JS(
+        '',
+        '#.onload = #',
+        xhr,
+        convertDartClosureToJS((e) {
+          var response = JS('String', '#.responseText', xhr);
+          completer.complete(response);
+        }, 1));
+    JS(
+        '',
+        '#.onerror = #',
+        xhr,
+        convertDartClosureToJS((e) {
+          completer.completeError(e);
+        }, 1));
+
+    // IE9 RTM - XDomainRequest issued requests may abort if all event handlers
+    // not specified
+    // http://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified
+    JS('', '#.onprogress = {}', xhr);
+    JS('', '#.ontimeout = {}', xhr);
+    JS('', '#.timeout = Number.MAX_VALUE', xhr);
+
+    if (sendData != null) {
+      JS('', '#.send(#)', xhr, sendData);
+    } else {
+      JS('', '#.send()', xhr);
+    }
+
+    return completer.future;
+  }
+
+  /**
+   * Returns all response headers as a key-value map.
+   *
+   * Multiple values for the same header key can be combined into one,
+   * separated by a comma and a space.
+   *
+   * See: http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method
+   */
+  Map<String, String> get responseHeaders {
+    // from Closure's goog.net.Xhrio.getResponseHeaders.
+    var headers = <String, String>{};
+    var headersString = this.getAllResponseHeaders();
+    if (headersString == null) {
+      return headers;
+    }
+    var headersList = headersString.split('\r\n');
+    for (var header in headersList) {
+      if (header.isEmpty) {
+        continue;
+      }
+
+      var splitIdx = header.indexOf(': ');
+      if (splitIdx == -1) {
+        continue;
+      }
+      var key = header.substring(0, splitIdx).toLowerCase();
+      var value = header.substring(splitIdx + 2);
+      if (headers.containsKey(key)) {
+        headers[key] = '${headers[key]}, $value';
+      } else {
+        headers[key] = value;
+      }
+    }
+    return headers;
+  }
+
+  /**
+   * Specify the desired `url`, and `method` to use in making the request.
+   *
+   * By default the request is done asyncronously, with no user or password
+   * authentication information. If `async` is false, the request will be sent
+   * synchronously.
+   *
+   * Calling `open` again on a currently active request is equivalent to
+   * calling [abort].
+   *
+   * Note: Most simple HTTP requests can be accomplished using the [getString],
+   * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
+   * `open` method is intended only for more complex HTTP requests where
+   * finer-grained control is needed.
+   */
+  void open(String method, String url,
+      {bool async, String user, String password}) native;
+
+  // To suppress missing implicit constructor warnings.
+  factory HttpRequest._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `readystatechange` events to event
+   * handlers that are not necessarily instances of [HttpRequest].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> readyStateChangeEvent =
+      const EventStreamProvider<Event>('readystatechange');
+
+  /**
+   * General constructor for any type of request (GET, POST, etc).
+   *
+   * This call is used in conjunction with [open]:
+   *
+   *     var request = new HttpRequest();
+   *     request.open('GET', 'http://dartlang.org');
+   *     request.onLoad.listen((event) => print(
+   *         'Request complete ${event.target.reponseText}'));
+   *     request.send();
+   *
+   * is the (more verbose) equivalent of
+   *
+   *     HttpRequest.getString('http://dartlang.org').then(
+   *         (result) => print('Request complete: $result'));
+   */
+  factory HttpRequest() {
+    return HttpRequest._create_1();
+  }
+  static HttpRequest _create_1() => JS('HttpRequest', 'new XMLHttpRequest()');
+
+  static const int DONE = 4;
+
+  static const int HEADERS_RECEIVED = 2;
+
+  static const int LOADING = 3;
+
+  static const int OPENED = 1;
+
+  static const int UNSENT = 0;
+
+  /**
+   * Indicator of the current state of the request:
+   *
+   * <table>
+   *   <tr>
+   *     <td>Value</td>
+   *     <td>State</td>
+   *     <td>Meaning</td>
+   *   </tr>
+   *   <tr>
+   *     <td>0</td>
+   *     <td>unsent</td>
+   *     <td><code>open()</code> has not yet been called</td>
+   *   </tr>
+   *   <tr>
+   *     <td>1</td>
+   *     <td>opened</td>
+   *     <td><code>send()</code> has not yet been called</td>
+   *   </tr>
+   *   <tr>
+   *     <td>2</td>
+   *     <td>headers received</td>
+   *     <td><code>sent()</code> has been called; response headers and <code>status</code> are available</td>
+   *   </tr>
+   *   <tr>
+   *     <td>3</td> <td>loading</td> <td><code>responseText</code> holds some data</td>
+   *   </tr>
+   *   <tr>
+   *     <td>4</td> <td>done</td> <td>request is complete</td>
+   *   </tr>
+   * </table>
+   */
+  final int readyState;
+
+  /**
+   * The data received as a reponse from the request.
+   *
+   * The data could be in the
+   * form of a [String], [ByteBuffer], [Document], [Blob], or json (also a
+   * [String]). `null` indicates request failure.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  dynamic get response => _convertNativeToDart_XHR_Response(this._get_response);
+  @JSName('response')
+  /**
+   * The data received as a reponse from the request.
+   *
+   * The data could be in the
+   * form of a [String], [ByteBuffer], [Document], [Blob], or json (also a
+   * [String]). `null` indicates request failure.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Creates(
+      'NativeByteBuffer|Blob|Document|=Object|JSExtendableArray|String|num')
+  final dynamic _get_response;
+
+  /**
+   * The response in String form or empty String on failure.
+   */
+  final String responseText;
+
+  /**
+   * [String] telling the server the desired response format.
+   *
+   * Default is `String`.
+   * Other options are one of 'arraybuffer', 'blob', 'document', 'json',
+   * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
+   * `responseType` is set while performing a synchronous request.
+   *
+   * See also: [MDN
+   * responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype)
+   */
+  String responseType;
+
+  @JSName('responseURL')
+  final String responseUrl;
+
+  @JSName('responseXML')
+  /**
+   * The request response, or null on failure.
+   *
+   * The response is processed as
+   * `text/xml` stream, unless responseType = 'document' and the request is
+   * synchronous.
+   */
+  final Document responseXml;
+
+  /**
+   * The HTTP result code from the request (200, 404, etc).
+   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+   */
+  final int status;
+
+  /**
+   * The request response string (such as \"OK\").
+   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+   */
+  final String statusText;
+
+  /**
+   * Length of time in milliseconds before a request is automatically
+   * terminated.
+   *
+   * When the time has passed, a [TimeoutEvent] is dispatched.
+   *
+   * If [timeout] is set to 0, then the request will not time out.
+   *
+   * ## Other resources
+   *
+   * * [XMLHttpRequest.timeout](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-timeout)
+   *   from MDN.
+   * * [The timeout attribute](http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
+   *   from W3C.
+   */
+  int timeout;
+
+  /**
+   * [EventTarget] that can hold listeners to track the progress of the request.
+   * The events fired will be members of [HttpRequestUploadEvents].
+   */
+  @Unstable()
+  final HttpRequestUpload upload;
+
+  /**
+   * True if cross-site requests should use credentials such as cookies
+   * or authorization headers; false otherwise.
+   *
+   * This value is ignored for same-site requests.
+   */
+  bool withCredentials;
+
+  /**
+   * Stop the current request.
+   *
+   * The request can only be stopped if readyState is `HEADERS_RECEIVED` or
+   * `LOADING`. If this method is not in the process of being sent, the method
+   * has no effect.
+   */
+  void abort() native;
+
+  /**
+   * Retrieve all the response headers from a request.
+   *
+   * `null` if no headers have been received. For multipart requests,
+   * `getAllResponseHeaders` will return the response headers for the current
+   * part of the request.
+   *
+   * See also [HTTP response
+   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)
+   * for a list of common response headers.
+   */
+  @Unstable()
+  String getAllResponseHeaders() native;
+
+  /**
+   * Return the response header named `header`, or null if not found.
+   *
+   * See also [HTTP response
+   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)
+   * for a list of common response headers.
+   */
+  @Unstable()
+  String getResponseHeader(String name) native;
+
+  /**
+   * Specify a particular MIME type (such as `text/xml`) desired for the
+   * response.
+   *
+   * This value must be set before the request has been sent. See also the list
+   * of [IANA Official MIME types](https://www.iana.org/assignments/media-types/media-types.xhtml).
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void overrideMimeType(String mime) native;
+
+  /**
+   * Send the request with any given `data`.
+   *
+   * Note: Most simple HTTP requests can be accomplished using the [getString],
+   * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
+   * `send` method is intended only for more complex HTTP requests where
+   * finer-grained control is needed.
+   *
+   * ## Other resources
+   *
+   * * [XMLHttpRequest.send](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
+   *   from MDN.
+   */
+  void send([body_OR_data]) native;
+
+  /**
+   * Sets the value of an HTTP request header.
+   *
+   * This method should be called after the request is opened, but before
+   * the request is sent.
+   *
+   * Multiple calls with the same header will combine all their values into a
+   * single header.
+   *
+   * ## Other resources
+   *
+   * * [XMLHttpRequest.setRequestHeader](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#setRequestHeader())
+   *   from MDN.
+   * * [The setRequestHeader()
+   *   method](http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method)
+   *   from W3C.
+   */
+  void setRequestHeader(String name, String value) native;
+
+  /// Stream of `readystatechange` events handled by this [HttpRequest].
+/**
+   * Event listeners to be notified every time the [HttpRequest]
+   * object's `readyState` changes values.
+   */
+  Stream<Event> get onReadyStateChange => readyStateChangeEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("XMLHttpRequestEventTarget")
+class HttpRequestEventTarget extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory HttpRequestEventTarget._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `abort` events to event
+   * handlers that are not necessarily instances of [HttpRequestEventTarget].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> abortEvent =
+      const EventStreamProvider<ProgressEvent>('abort');
+
+  /**
+   * Static factory designed to expose `error` events to event
+   * handlers that are not necessarily instances of [HttpRequestEventTarget].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> errorEvent =
+      const EventStreamProvider<ProgressEvent>('error');
+
+  /**
+   * Static factory designed to expose `load` events to event
+   * handlers that are not necessarily instances of [HttpRequestEventTarget].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> loadEvent =
+      const EventStreamProvider<ProgressEvent>('load');
+
+  /**
+   * Static factory designed to expose `loadend` events to event
+   * handlers that are not necessarily instances of [HttpRequestEventTarget].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> loadEndEvent =
+      const EventStreamProvider<ProgressEvent>('loadend');
+
+  /**
+   * Static factory designed to expose `loadstart` events to event
+   * handlers that are not necessarily instances of [HttpRequestEventTarget].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> loadStartEvent =
+      const EventStreamProvider<ProgressEvent>('loadstart');
+
+  /**
+   * Static factory designed to expose `progress` events to event
+   * handlers that are not necessarily instances of [HttpRequestEventTarget].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> progressEvent =
+      const EventStreamProvider<ProgressEvent>('progress');
+
+  /**
+   * Static factory designed to expose `timeout` events to event
+   * handlers that are not necessarily instances of [HttpRequestEventTarget].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<ProgressEvent> timeoutEvent =
+      const EventStreamProvider<ProgressEvent>('timeout');
+
+  /// Stream of `abort` events handled by this [HttpRequestEventTarget].
+  Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);
+
+  /// Stream of `error` events handled by this [HttpRequestEventTarget].
+  Stream<ProgressEvent> get onError => errorEvent.forTarget(this);
+
+  /// Stream of `load` events handled by this [HttpRequestEventTarget].
+  Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);
+
+  /// Stream of `loadend` events handled by this [HttpRequestEventTarget].
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);
+
+  /// Stream of `loadstart` events handled by this [HttpRequestEventTarget].
+  Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);
+
+  /// Stream of `progress` events handled by this [HttpRequestEventTarget].
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
+
+  /// Stream of `timeout` events handled by this [HttpRequestEventTarget].
+  Stream<ProgressEvent> get onTimeout => timeoutEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("XMLHttpRequestUpload")
+class HttpRequestUpload extends HttpRequestEventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory HttpRequestUpload._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("HTMLIFrameElement")
+class IFrameElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory IFrameElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory IFrameElement() => JS(
+      'returns:IFrameElement;creates:IFrameElement;new:true',
+      '#.createElement(#)',
+      document,
+      "iframe");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  IFrameElement.created() : super.created();
+
+  String allow;
+
+  bool allowFullscreen;
+
+  bool allowPaymentRequest;
+
+  WindowBase get contentWindow =>
+      _convertNativeToDart_Window(this._get_contentWindow);
+  @JSName('contentWindow')
+  @Creates('Window|=Object')
+  @Returns('Window|=Object')
+  final dynamic _get_contentWindow;
+
+  String csp;
+
+  String height;
+
+  String name;
+
+  String referrerPolicy;
+
+  final DomTokenList sandbox;
+
+  String src;
+
+  String srcdoc;
+
+  String width;
+}
+// Copyright (c) 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.
+
+@Native("IdleDeadline")
+class IdleDeadline extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory IdleDeadline._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool didTimeout;
+
+  double timeRemaining() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void IdleRequestCallback(IdleDeadline deadline);
+// Copyright (c) 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.
+
+@Native("ImageBitmap")
+class ImageBitmap extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ImageBitmap._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int height;
+
+  final int width;
+
+  void close() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("ImageBitmapRenderingContext")
+class ImageBitmapRenderingContext extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ImageBitmapRenderingContext._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final CanvasElement canvas;
+
+  void transferFromImageBitmap(ImageBitmap bitmap) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("ImageCapture")
+class ImageCapture extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ImageCapture._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ImageCapture(MediaStreamTrack track) {
+    return ImageCapture._create_1(track);
+  }
+  static ImageCapture _create_1(track) =>
+      JS('ImageCapture', 'new ImageCapture(#)', track);
+
+  final MediaStreamTrack track;
+
+  Future<PhotoCapabilities> getPhotoCapabilities() =>
+      promiseToFuture<PhotoCapabilities>(
+          JS("", "#.getPhotoCapabilities()", this));
+
+  Future<Map<String, dynamic>> getPhotoSettings() =>
+      promiseToFutureAsMap(JS("", "#.getPhotoSettings()", this));
+
+  Future<ImageBitmap> grabFrame() =>
+      promiseToFuture<ImageBitmap>(JS("", "#.grabFrame()", this));
+
+  Future setOptions(Map photoSettings) {
+    var photoSettings_dict = convertDartToNative_Dictionary(photoSettings);
+    return promiseToFuture(JS("", "#.setOptions(#)", this, photoSettings_dict));
+  }
+
+  Future<Blob> takePhoto([Map photoSettings]) {
+    var photoSettings_dict = null;
+    if (photoSettings != null) {
+      photoSettings_dict = convertDartToNative_Dictionary(photoSettings);
+    }
+    return promiseToFuture<Blob>(
+        JS("", "#.takePhoto(#)", this, photoSettings_dict));
+  }
+}
+// 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.
+
+@Native("ImageData")
+class ImageData extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ImageData._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ImageData(data_OR_sw, int sh_OR_sw, [int sh]) {
+    if ((sh_OR_sw is int) && (data_OR_sw is int) && sh == null) {
+      return ImageData._create_1(data_OR_sw, sh_OR_sw);
+    }
+    if ((sh_OR_sw is int) && (data_OR_sw is Uint8ClampedList) && sh == null) {
+      return ImageData._create_2(data_OR_sw, sh_OR_sw);
+    }
+    if ((sh is int) && (sh_OR_sw is int) && (data_OR_sw is Uint8ClampedList)) {
+      return ImageData._create_3(data_OR_sw, sh_OR_sw, sh);
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+  static ImageData _create_1(data_OR_sw, sh_OR_sw) =>
+      JS('ImageData', 'new ImageData(#,#)', data_OR_sw, sh_OR_sw);
+  static ImageData _create_2(data_OR_sw, sh_OR_sw) =>
+      JS('ImageData', 'new ImageData(#,#)', data_OR_sw, sh_OR_sw);
+  static ImageData _create_3(data_OR_sw, sh_OR_sw, sh) =>
+      JS('ImageData', 'new ImageData(#,#,#)', data_OR_sw, sh_OR_sw, sh);
+
+  @Creates('NativeUint8ClampedList')
+  @Returns('NativeUint8ClampedList')
+  final Uint8ClampedList data;
+
+  final int height;
+
+  final int width;
+}
+// Copyright (c) 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.
+
+@Native("HTMLImageElement")
+class ImageElement extends HtmlElement implements CanvasImageSource {
+  // To suppress missing implicit constructor warnings.
+  factory ImageElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ImageElement({String src, int width, int height}) {
+    ImageElement e = JS('returns:ImageElement;creates:ImageElement;new:true',
+        '#.createElement(#)', document, "img");
+    if (src != null) e.src = src;
+    if (width != null) e.width = width;
+    if (height != null) e.height = height;
+    return e;
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ImageElement.created() : super.created();
+
+  String alt;
+
+  String async;
+
+  final bool complete;
+
+  String crossOrigin;
+
+  final String currentSrc;
+
+  int height;
+
+  bool isMap;
+
+  final int naturalHeight;
+
+  final int naturalWidth;
+
+  String referrerPolicy;
+
+  String sizes;
+
+  String src;
+
+  String srcset;
+
+  String useMap;
+
+  int width;
+
+  Future decode() => promiseToFuture(JS("", "#.decode()", this));
+}
+// Copyright (c) 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.
+
+@Native("InputDeviceCapabilities")
+class InputDeviceCapabilities extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory InputDeviceCapabilities._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory InputDeviceCapabilities([Map deviceInitDict]) {
+    if (deviceInitDict != null) {
+      var deviceInitDict_1 = convertDartToNative_Dictionary(deviceInitDict);
+      return InputDeviceCapabilities._create_1(deviceInitDict_1);
+    }
+    return InputDeviceCapabilities._create_2();
+  }
+  static InputDeviceCapabilities _create_1(deviceInitDict) => JS(
+      'InputDeviceCapabilities',
+      'new InputDeviceCapabilities(#)',
+      deviceInitDict);
+  static InputDeviceCapabilities _create_2() =>
+      JS('InputDeviceCapabilities', 'new InputDeviceCapabilities()');
+
+  final bool firesTouchEvents;
+}
+// Copyright (c) 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.
+
+@Native("HTMLInputElement")
+class InputElement extends HtmlElement
+    implements
+        HiddenInputElement,
+        SearchInputElement,
+        TextInputElement,
+        UrlInputElement,
+        TelephoneInputElement,
+        EmailInputElement,
+        PasswordInputElement,
+        DateInputElement,
+        MonthInputElement,
+        WeekInputElement,
+        TimeInputElement,
+        LocalDateTimeInputElement,
+        NumberInputElement,
+        RangeInputElement,
+        CheckboxInputElement,
+        RadioButtonInputElement,
+        FileUploadInputElement,
+        SubmitButtonInputElement,
+        ImageButtonInputElement,
+        ResetButtonInputElement,
+        ButtonInputElement {
+  factory InputElement({String type}) {
+    InputElement e = document.createElement("input");
+    if (type != null) {
+      try {
+        // IE throws an exception for unknown types.
+        e.type = type;
+      } catch (_) {}
+    }
+    return e;
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory InputElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  InputElement.created() : super.created();
+
+  String accept;
+
+  String alt;
+
+  String autocapitalize;
+
+  String autocomplete;
+
+  bool autofocus;
+
+  String capture;
+
+  bool checked;
+
+  bool defaultChecked;
+
+  String defaultValue;
+
+  String dirName;
+
+  bool disabled;
+
+  @Returns('FileList|Null')
+  @Creates('FileList')
+  List<File> files;
+
+  final FormElement form;
+
+  String formAction;
+
+  String formEnctype;
+
+  String formMethod;
+
+  bool formNoValidate;
+
+  String formTarget;
+
+  int height;
+
+  bool incremental;
+
+  bool indeterminate;
+
+  @Returns('NodeList|Null')
+  @Creates('NodeList')
+  final List<Node> labels;
+
+  final HtmlElement list;
+
+  String max;
+
+  int maxLength;
+
+  String min;
+
+  int minLength;
+
+  bool multiple;
+
+  String name;
+
+  String pattern;
+
+  String placeholder;
+
+  bool readOnly;
+
+  bool required;
+
+  String selectionDirection;
+
+  int selectionEnd;
+
+  int selectionStart;
+
+  int size;
+
+  String src;
+
+  String step;
+
+  String type;
+
+  final String validationMessage;
+
+  final ValidityState validity;
+
+  String value;
+
+  DateTime get valueAsDate =>
+      convertNativeToDart_DateTime(this._get_valueAsDate);
+  @JSName('valueAsDate')
+  @Creates('Null')
+  final dynamic _get_valueAsDate;
+
+  set valueAsDate(DateTime value) {
+    this._set_valueAsDate = convertDartToNative_DateTime(value);
+  }
+
+  set _set_valueAsDate(/*dynamic*/ value) {
+    JS("void", "#.valueAsDate = #", this, value);
+  }
+
+  num valueAsNumber;
+
+  @JSName('webkitEntries')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  final List<Entry> entries;
+
+  @JSName('webkitdirectory')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  bool directory;
+
+  int width;
+
+  final bool willValidate;
+
+  bool checkValidity() native;
+
+  bool reportValidity() native;
+
+  void select() native;
+
+  void setCustomValidity(String error) native;
+
+  void setRangeText(String replacement,
+      {int start, int end, String selectionMode}) native;
+
+  void setSelectionRange(int start, int end, [String direction]) native;
+
+  void stepDown([int n]) native;
+
+  void stepUp([int n]) native;
+}
+
+// Interfaces representing the InputElement APIs which are supported
+// for the various types of InputElement. From:
+// https://w3c.github.io/html/sec-forms.html#the-input-element.
+
+/**
+ * Exposes the functionality common between all InputElement types.
+ */
+abstract class InputElementBase implements Element {
+  bool autofocus;
+
+  bool disabled;
+
+  bool incremental;
+
+  bool indeterminate;
+
+  List<Node> get labels;
+
+  String name;
+
+  String get validationMessage;
+
+  ValidityState get validity;
+
+  String value;
+
+  bool get willValidate;
+
+  bool checkValidity();
+
+  void setCustomValidity(String error);
+}
+
+/**
+ * Hidden input which is not intended to be seen or edited by the user.
+ */
+abstract class HiddenInputElement implements InputElementBase {
+  factory HiddenInputElement() => new InputElement(type: 'hidden');
+}
+
+/**
+ * Base interface for all inputs which involve text editing.
+ */
+abstract class TextInputElementBase implements InputElementBase {
+  String autocomplete;
+
+  int maxLength;
+
+  String pattern;
+
+  String placeholder;
+
+  bool readOnly;
+
+  bool required;
+
+  int size;
+
+  void select();
+
+  String selectionDirection;
+
+  int selectionEnd;
+
+  int selectionStart;
+
+  void setSelectionRange(int start, int end, [String direction]);
+}
+
+/**
+ * Similar to [TextInputElement], but on platforms where search is styled
+ * differently this will get the search style.
+ *
+ * Use [supported] to check if this is supported on the current platform.
+ */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+abstract class SearchInputElement implements TextInputElementBase {
+  factory SearchInputElement() => new InputElement(type: 'search');
+
+  String dirName;
+
+  Element get list;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'search')).type == 'search';
+  }
+}
+
+/**
+ * A basic text input editor control.
+ */
+abstract class TextInputElement implements TextInputElementBase {
+  factory TextInputElement() => new InputElement(type: 'text');
+
+  String dirName;
+
+  Element get list;
+}
+
+/**
+ * A control for editing an absolute URL.
+ *
+ * Use [supported] to check if this is supported on the current platform.
+ */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+abstract class UrlInputElement implements TextInputElementBase {
+  factory UrlInputElement() => new InputElement(type: 'url');
+
+  Element get list;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'url')).type == 'url';
+  }
+}
+
+/**
+ * Represents a control for editing a telephone number.
+ *
+ * This provides a single line of text with minimal formatting help since
+ * there is a wide variety of telephone numbers.
+ *
+ * Use [supported] to check if this is supported on the current platform.
+ */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+abstract class TelephoneInputElement implements TextInputElementBase {
+  factory TelephoneInputElement() => new InputElement(type: 'tel');
+
+  Element get list;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'tel')).type == 'tel';
+  }
+}
+
+/**
+ * An e-mail address or list of e-mail addresses.
+ *
+ * Use [supported] to check if this is supported on the current platform.
+ */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+abstract class EmailInputElement implements TextInputElementBase {
+  factory EmailInputElement() => new InputElement(type: 'email');
+
+  String autocomplete;
+
+  bool autofocus;
+
+  Element get list;
+
+  int maxLength;
+
+  bool multiple;
+
+  String pattern;
+
+  String placeholder;
+
+  bool readOnly;
+
+  bool required;
+
+  int size;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'email')).type == 'email';
+  }
+}
+
+/**
+ * Text with no line breaks (sensitive information).
+ */
+abstract class PasswordInputElement implements TextInputElementBase {
+  factory PasswordInputElement() => new InputElement(type: 'password');
+}
+
+/**
+ * Base interface for all input element types which involve ranges.
+ */
+abstract class RangeInputElementBase implements InputElementBase {
+  Element get list;
+
+  String max;
+
+  String min;
+
+  String step;
+
+  num valueAsNumber;
+
+  void stepDown([int n]);
+
+  void stepUp([int n]);
+}
+
+/**
+ * A date (year, month, day) with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
+ */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+abstract class DateInputElement implements RangeInputElementBase {
+  factory DateInputElement() => new InputElement(type: 'date');
+
+  DateTime valueAsDate;
+
+  bool readOnly;
+
+  bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'date')).type == 'date';
+  }
+}
+
+/**
+ * A date consisting of a year and a month with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
+ */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+abstract class MonthInputElement implements RangeInputElementBase {
+  factory MonthInputElement() => new InputElement(type: 'month');
+
+  DateTime valueAsDate;
+
+  bool readOnly;
+
+  bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'month')).type == 'month';
+  }
+}
+
+/**
+ * A date consisting of a week-year number and a week number with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
+ */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+abstract class WeekInputElement implements RangeInputElementBase {
+  factory WeekInputElement() => new InputElement(type: 'week');
+
+  DateTime valueAsDate;
+
+  bool readOnly;
+
+  bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'week')).type == 'week';
+  }
+}
+
+/**
+ * A time (hour, minute, seconds, fractional seconds) with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
+ */
+@SupportedBrowser(SupportedBrowser.CHROME)
+abstract class TimeInputElement implements RangeInputElementBase {
+  factory TimeInputElement() => new InputElement(type: 'time');
+
+  DateTime valueAsDate;
+
+  bool readOnly;
+
+  bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'time')).type == 'time';
+  }
+}
+
+/**
+ * A date and time (year, month, day, hour, minute, second, fraction of a
+ * second) with no time zone.
+ *
+ * Use [supported] to check if this is supported on the current platform.
+ */
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+abstract class LocalDateTimeInputElement implements RangeInputElementBase {
+  factory LocalDateTimeInputElement() =>
+      new InputElement(type: 'datetime-local');
+
+  bool readOnly;
+
+  bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'datetime-local')).type == 'datetime-local';
+  }
+}
+
+/**
+ * A numeric editor control.
+ */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.IE)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+abstract class NumberInputElement implements RangeInputElementBase {
+  factory NumberInputElement() => new InputElement(type: 'number');
+
+  String placeholder;
+
+  bool readOnly;
+
+  bool required;
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'number')).type == 'number';
+  }
+}
+
+/**
+ * Similar to [NumberInputElement] but the browser may provide more optimal
+ * styling (such as a slider control).
+ *
+ * Use [supported] to check if this is supported on the current platform.
+ */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+abstract class RangeInputElement implements RangeInputElementBase {
+  factory RangeInputElement() => new InputElement(type: 'range');
+
+  /// Returns true if this input type is supported on the current platform.
+  static bool get supported {
+    return (new InputElement(type: 'range')).type == 'range';
+  }
+}
+
+/**
+ * A boolean editor control.
+ *
+ * Note that if [indeterminate] is set then this control is in a third
+ * indeterminate state.
+ */
+abstract class CheckboxInputElement implements InputElementBase {
+  factory CheckboxInputElement() => new InputElement(type: 'checkbox');
+
+  bool checked;
+
+  bool required;
+}
+
+/**
+ * A control that when used with other [ReadioButtonInputElement] controls
+ * forms a radio button group in which only one control can be checked at a
+ * time.
+ *
+ * Radio buttons are considered to be in the same radio button group if:
+ *
+ * * They are all of type 'radio'.
+ * * They all have either the same [FormElement] owner, or no owner.
+ * * Their name attributes contain the same name.
+ */
+abstract class RadioButtonInputElement implements InputElementBase {
+  factory RadioButtonInputElement() => new InputElement(type: 'radio');
+
+  bool checked;
+
+  bool required;
+}
+
+/**
+ * A control for picking files from the user's computer.
+ */
+abstract class FileUploadInputElement implements InputElementBase {
+  factory FileUploadInputElement() => new InputElement(type: 'file');
+
+  String accept;
+
+  bool multiple;
+
+  bool required;
+
+  List<File> files;
+}
+
+/**
+ * A button, which when clicked, submits the form.
+ */
+abstract class SubmitButtonInputElement implements InputElementBase {
+  factory SubmitButtonInputElement() => new InputElement(type: 'submit');
+
+  String formAction;
+
+  String formEnctype;
+
+  String formMethod;
+
+  bool formNoValidate;
+
+  String formTarget;
+}
+
+/**
+ * Either an image which the user can select a coordinate to or a form
+ * submit button.
+ */
+abstract class ImageButtonInputElement implements InputElementBase {
+  factory ImageButtonInputElement() => new InputElement(type: 'image');
+
+  String alt;
+
+  String formAction;
+
+  String formEnctype;
+
+  String formMethod;
+
+  bool formNoValidate;
+
+  String formTarget;
+
+  int height;
+
+  String src;
+
+  int width;
+}
+
+/**
+ * A button, which when clicked, resets the form.
+ */
+abstract class ResetButtonInputElement implements InputElementBase {
+  factory ResetButtonInputElement() => new InputElement(type: 'reset');
+}
+
+/**
+ * A button, with no default behavior.
+ */
+abstract class ButtonInputElement implements InputElementBase {
+  factory ButtonInputElement() => new InputElement(type: 'button');
+}
+// Copyright (c) 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.
+
+@Native("InstallEvent")
+class InstallEvent extends ExtendableEvent {
+  // To suppress missing implicit constructor warnings.
+  factory InstallEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory InstallEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return InstallEvent._create_1(type, eventInitDict_1);
+    }
+    return InstallEvent._create_2(type);
+  }
+  static InstallEvent _create_1(type, eventInitDict) =>
+      JS('InstallEvent', 'new InstallEvent(#,#)', type, eventInitDict);
+  static InstallEvent _create_2(type) =>
+      JS('InstallEvent', 'new InstallEvent(#)', type);
+
+  void registerForeignFetch(Map options) {
+    var options_1 = convertDartToNative_Dictionary(options);
+    _registerForeignFetch_1(options_1);
+    return;
+  }
+
+  @JSName('registerForeignFetch')
+  void _registerForeignFetch_1(options) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("IntersectionObserver")
+class IntersectionObserver extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory IntersectionObserver._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory IntersectionObserver(IntersectionObserverCallback callback,
+      [Map options]) {
+    if (options != null) {
+      var callback_1 = convertDartClosureToJS(callback, 2);
+      var options_2 = convertDartToNative_Dictionary(options);
+      return IntersectionObserver._create_1(callback_1, options_2);
+    }
+    var callback_1 = convertDartClosureToJS(callback, 2);
+    return IntersectionObserver._create_2(callback_1);
+  }
+  static IntersectionObserver _create_1(callback, options) => JS(
+      'IntersectionObserver',
+      'new IntersectionObserver(#,#)',
+      callback,
+      options);
+  static IntersectionObserver _create_2(callback) =>
+      JS('IntersectionObserver', 'new IntersectionObserver(#)', callback);
+
+  final Element root;
+
+  final String rootMargin;
+
+  final List<num> thresholds;
+
+  void disconnect() native;
+
+  void observe(Element target) native;
+
+  List<IntersectionObserverEntry> takeRecords() native;
+
+  void unobserve(Element target) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void IntersectionObserverCallback(
+    List entries, IntersectionObserver observer);
+// Copyright (c) 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.
+
+@Native("IntersectionObserverEntry")
+class IntersectionObserverEntry extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory IntersectionObserverEntry._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final DomRectReadOnly boundingClientRect;
+
+  final num intersectionRatio;
+
+  final DomRectReadOnly intersectionRect;
+
+  final bool isIntersecting;
+
+  final DomRectReadOnly rootBounds;
+
+  final Element target;
+
+  final num time;
+}
+// Copyright (c) 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.
+
+@Native("InterventionReport")
+class InterventionReport extends ReportBody {
+  // To suppress missing implicit constructor warnings.
+  factory InterventionReport._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int lineNumber;
+
+  final String message;
+
+  final String sourceFile;
+}
+// Copyright (c) 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.
+
+/**
+ * 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.
+ */
+@Native("KeyboardEvent")
+class KeyboardEvent extends UIEvent {
+  /**
+   * Programmatically create a KeyboardEvent.
+   *
+   * Due to browser differences, keyCode, charCode, or keyIdentifier values
+   * cannot be specified in this base level constructor. This constructor
+   * enables the user to programmatically create and dispatch a [KeyboardEvent],
+   * but it will not contain any particular key content. For programmatically
+   * creating keyboard events with specific key value contents, see the custom
+   * Event [KeyEvent].
+   */
+  factory KeyboardEvent(String type,
+      {Window view,
+      bool canBubble: true,
+      bool cancelable: true,
+      int location,
+      int keyLocation, // Legacy alias for location
+      bool ctrlKey: false,
+      bool altKey: false,
+      bool shiftKey: false,
+      bool metaKey: false}) {
+    if (view == null) {
+      view = window;
+    }
+    location ??= keyLocation ?? 1;
+    KeyboardEvent e = document._createEvent("KeyboardEvent");
+    e._initKeyboardEvent(type, canBubble, cancelable, view, "", location,
+        ctrlKey, altKey, shiftKey, metaKey);
+    return e;
+  }
+
+  void _initKeyboardEvent(
+      String type,
+      bool canBubble,
+      bool cancelable,
+      Window view,
+      String keyIdentifier,
+      int location,
+      bool ctrlKey,
+      bool altKey,
+      bool shiftKey,
+      bool metaKey) {
+    if (JS('bool', 'typeof(#.initKeyEvent) == "function"', this)) {
+      // initKeyEvent is only in Firefox (instead of initKeyboardEvent). It has
+      // a slightly different signature, and allows you to specify keyCode and
+      // charCode as the last two arguments, but we just set them as the default
+      // since they can't be specified in other browsers.
+      JS('void', '#.initKeyEvent(#, #, #, #, #, #, #, #, 0, 0)', this, type,
+          canBubble, cancelable, view, ctrlKey, altKey, shiftKey, metaKey);
+    } else {
+      // initKeyboardEvent is for all other browsers.
+      JS(
+          'void',
+          '#.initKeyboardEvent(#, #, #, #, #, #, #, #, #, #)',
+          this,
+          type,
+          canBubble,
+          cancelable,
+          view,
+          keyIdentifier,
+          location,
+          ctrlKey,
+          altKey,
+          shiftKey,
+          metaKey);
+    }
+  }
+
+  final int keyCode;
+
+  final int charCode;
+
+  int get which => _which;
+
+  factory KeyboardEvent._(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return KeyboardEvent._create_1(type, eventInitDict_1);
+    }
+    return KeyboardEvent._create_2(type);
+  }
+  static KeyboardEvent _create_1(type, eventInitDict) =>
+      JS('KeyboardEvent', 'new KeyboardEvent(#,#)', type, eventInitDict);
+  static KeyboardEvent _create_2(type) =>
+      JS('KeyboardEvent', 'new KeyboardEvent(#)', type);
+
+  static const int DOM_KEY_LOCATION_LEFT = 0x01;
+
+  static const int DOM_KEY_LOCATION_NUMPAD = 0x03;
+
+  static const int DOM_KEY_LOCATION_RIGHT = 0x02;
+
+  static const int DOM_KEY_LOCATION_STANDARD = 0x00;
+
+  final bool altKey;
+
+  @JSName('charCode')
+  final int _charCode;
+
+  final String code;
+
+  final bool ctrlKey;
+
+  final bool isComposing;
+
+  final String key;
+
+  @JSName('keyCode')
+  final int _keyCode;
+
+  final int location;
+
+  final bool metaKey;
+
+  final bool repeat;
+
+  final bool shiftKey;
+
+  bool getModifierState(String keyArg) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("KeyframeEffect")
+class KeyframeEffect extends KeyframeEffectReadOnly {
+  // To suppress missing implicit constructor warnings.
+  factory KeyframeEffect._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory KeyframeEffect(Element target, Object effect, [Object options]) {
+    if (options != null) {
+      return KeyframeEffect._create_1(target, effect, options);
+    }
+    return KeyframeEffect._create_2(target, effect);
+  }
+  static KeyframeEffect _create_1(target, effect, options) => JS(
+      'KeyframeEffect', 'new KeyframeEffect(#,#,#)', target, effect, options);
+  static KeyframeEffect _create_2(target, effect) =>
+      JS('KeyframeEffect', 'new KeyframeEffect(#,#)', target, effect);
+}
+// Copyright (c) 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.
+
+@Native("KeyframeEffectReadOnly")
+class KeyframeEffectReadOnly extends AnimationEffectReadOnly {
+  // To suppress missing implicit constructor warnings.
+  factory KeyframeEffectReadOnly._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory KeyframeEffectReadOnly(Element target, Object effect,
+      [Object options]) {
+    if (options != null) {
+      return KeyframeEffectReadOnly._create_1(target, effect, options);
+    }
+    return KeyframeEffectReadOnly._create_2(target, effect);
+  }
+  static KeyframeEffectReadOnly _create_1(target, effect, options) => JS(
+      'KeyframeEffectReadOnly',
+      'new KeyframeEffectReadOnly(#,#,#)',
+      target,
+      effect,
+      options);
+  static KeyframeEffectReadOnly _create_2(target, effect) => JS(
+      'KeyframeEffectReadOnly',
+      'new KeyframeEffectReadOnly(#,#)',
+      target,
+      effect);
+}
+// Copyright (c) 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.
+
+@Native("HTMLLIElement")
+class LIElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory LIElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory LIElement() => JS('returns:LIElement;creates:LIElement;new:true',
+      '#.createElement(#)', document, "li");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  LIElement.created() : super.created();
+
+  int value;
+}
+// Copyright (c) 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.
+
+@Native("HTMLLabelElement")
+class LabelElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory LabelElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory LabelElement() => JS(
+      'returns:LabelElement;creates:LabelElement;new:true',
+      '#.createElement(#)',
+      document,
+      "label");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  LabelElement.created() : super.created();
+
+  final HtmlElement control;
+
+  final FormElement form;
+
+  String htmlFor;
+}
+// Copyright (c) 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.
+
+@Native("HTMLLegendElement")
+class LegendElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory LegendElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory LegendElement() => JS(
+      'returns:LegendElement;creates:LegendElement;new:true',
+      '#.createElement(#)',
+      document,
+      "legend");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  LegendElement.created() : super.created();
+
+  final FormElement form;
+}
+// Copyright (c) 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.
+
+@Native("LinearAccelerationSensor")
+class LinearAccelerationSensor extends Accelerometer {
+  // To suppress missing implicit constructor warnings.
+  factory LinearAccelerationSensor._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory LinearAccelerationSensor([Map sensorOptions]) {
+    if (sensorOptions != null) {
+      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
+      return LinearAccelerationSensor._create_1(sensorOptions_1);
+    }
+    return LinearAccelerationSensor._create_2();
+  }
+  static LinearAccelerationSensor _create_1(sensorOptions) => JS(
+      'LinearAccelerationSensor',
+      'new LinearAccelerationSensor(#)',
+      sensorOptions);
+  static LinearAccelerationSensor _create_2() =>
+      JS('LinearAccelerationSensor', 'new LinearAccelerationSensor()');
+}
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("HTMLLinkElement")
+class LinkElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory LinkElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory LinkElement() => JS(
+      'returns:LinkElement;creates:LinkElement;new:true',
+      '#.createElement(#)',
+      document,
+      "link");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  LinkElement.created() : super.created();
+
+  String as;
+
+  String crossOrigin;
+
+  bool disabled;
+
+  String href;
+
+  String hreflang;
+
+  final Document import;
+
+  String integrity;
+
+  String media;
+
+  String referrerPolicy;
+
+  String rel;
+
+  final DomTokenList relList;
+
+  String scope;
+
+  final StyleSheet sheet;
+
+  final DomTokenList sizes;
+
+  String type;
+
+  /// Checks if HTML imports are supported on the current platform.
+  bool get supportsImport {
+    return JS('bool', '("import" in #)', this);
+  }
+}
+// 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.
+
+@Native("Location")
+class Location extends Interceptor implements LocationBase {
+  // To suppress missing implicit constructor warnings.
+  factory Location._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @Returns('DomStringList|Null')
+  @Creates('DomStringList')
+  final List<String> ancestorOrigins;
+
+  String hash;
+
+  String host;
+
+  String hostname;
+
+  String href;
+
+  String pathname;
+
+  String port;
+
+  String protocol;
+
+  String search;
+
+  TrustedUrl trustedHref;
+
+  void assign([String url]) native;
+
+  void reload() native;
+
+  void replace(String url) native;
+
+  String get origin {
+    if (JS('bool', '("origin" in #)', this)) {
+      return JS('String', '#.origin', this);
+    }
+    return '${this.protocol}//${this.host}';
+  }
+
+  String toString() => JS('String', 'String(#)', this);
+}
+// Copyright (c) 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.
+
+@Native("Magnetometer")
+class Magnetometer extends Sensor {
+  // To suppress missing implicit constructor warnings.
+  factory Magnetometer._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory Magnetometer([Map sensorOptions]) {
+    if (sensorOptions != null) {
+      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
+      return Magnetometer._create_1(sensorOptions_1);
+    }
+    return Magnetometer._create_2();
+  }
+  static Magnetometer _create_1(sensorOptions) =>
+      JS('Magnetometer', 'new Magnetometer(#)', sensorOptions);
+  static Magnetometer _create_2() => JS('Magnetometer', 'new Magnetometer()');
+
+  final num x;
+
+  final num y;
+
+  final num z;
+}
+// Copyright (c) 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.
+
+@Native("HTMLMapElement")
+class MapElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory MapElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MapElement() => JS('returns:MapElement;creates:MapElement;new:true',
+      '#.createElement(#)', document, "map");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MapElement.created() : super.created();
+
+  @Returns('HtmlCollection|Null')
+  @Creates('HtmlCollection')
+  final List<Node> areas;
+
+  String name;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("MediaCapabilities")
+class MediaCapabilities extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory MediaCapabilities._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Future<MediaCapabilitiesInfo> decodingInfo(Map configuration) {
+    var configuration_dict = convertDartToNative_Dictionary(configuration);
+    return promiseToFuture<MediaCapabilitiesInfo>(
+        JS("", "#.decodingInfo(#)", this, configuration_dict));
+  }
+
+  Future<MediaCapabilitiesInfo> encodingInfo(Map configuration) {
+    var configuration_dict = convertDartToNative_Dictionary(configuration);
+    return promiseToFuture<MediaCapabilitiesInfo>(
+        JS("", "#.encodingInfo(#)", this, configuration_dict));
+  }
+}
+// Copyright (c) 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.
+
+@Native("MediaCapabilitiesInfo")
+class MediaCapabilitiesInfo extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory MediaCapabilitiesInfo._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool powerEfficient;
+
+  final bool smooth;
+
+  final bool supported;
+}
+// Copyright (c) 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.
+
+@Native("MediaDeviceInfo")
+class MediaDeviceInfo extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory MediaDeviceInfo._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String deviceId;
+
+  final String groupId;
+
+  final String kind;
+
+  final String label;
+}
+// Copyright (c) 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.
+
+@Native("MediaDevices")
+class MediaDevices extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory MediaDevices._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Future<List<MediaDeviceInfo>> enumerateDevices() =>
+      promiseToFuture<List<MediaDeviceInfo>>(
+          JS("", "#.enumerateDevices()", this));
+
+  Map getSupportedConstraints() {
+    return convertNativeToDart_Dictionary(_getSupportedConstraints_1());
+  }
+
+  @JSName('getSupportedConstraints')
+  _getSupportedConstraints_1() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("HTMLMediaElement")
+class MediaElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory MediaElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MediaElement.created() : super.created();
+
+  static const int HAVE_CURRENT_DATA = 2;
+
+  static const int HAVE_ENOUGH_DATA = 4;
+
+  static const int HAVE_FUTURE_DATA = 3;
+
+  static const int HAVE_METADATA = 1;
+
+  static const int HAVE_NOTHING = 0;
+
+  static const int NETWORK_EMPTY = 0;
+
+  static const int NETWORK_IDLE = 1;
+
+  static const int NETWORK_LOADING = 2;
+
+  static const int NETWORK_NO_SOURCE = 3;
+
+  final AudioTrackList audioTracks;
+
+  bool autoplay;
+
+  final TimeRanges buffered;
+
+  bool controls;
+
+  final DomTokenList controlsList;
+
+  String crossOrigin;
+
+  final String currentSrc;
+
+  num currentTime;
+
+  bool defaultMuted;
+
+  num defaultPlaybackRate;
+
+  bool disableRemotePlayback;
+
+  final num duration;
+
+  final bool ended;
+
+  final MediaError error;
+
+  bool loop;
+
+  final MediaKeys mediaKeys;
+
+  bool muted;
+
+  final int networkState;
+
+  final bool paused;
+
+  num playbackRate;
+
+  final TimeRanges played;
+
+  String preload;
+
+  final int readyState;
+
+  final RemotePlayback remote;
+
+  final TimeRanges seekable;
+
+  final bool seeking;
+
+  final String sinkId;
+
+  String src;
+
+  MediaStream srcObject;
+
+  final TextTrackList textTracks;
+
+  final VideoTrackList videoTracks;
+
+  num volume;
+
+  @JSName('webkitAudioDecodedByteCount')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  final int audioDecodedByteCount;
+
+  @JSName('webkitVideoDecodedByteCount')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  final int videoDecodedByteCount;
+
+  TextTrack addTextTrack(String kind, [String label, String language]) native;
+
+  @Unstable()
+  String canPlayType(String type, [String keySystem]) native;
+
+  MediaStream captureStream() native;
+
+  void load() native;
+
+  void pause() native;
+
+  Future play() => promiseToFuture(JS("", "#.play()", this));
+
+  Future setMediaKeys(MediaKeys mediaKeys) =>
+      promiseToFuture(JS("", "#.setMediaKeys(#)", this, mediaKeys));
+
+  Future setSinkId(String sinkId) =>
+      promiseToFuture(JS("", "#.setSinkId(#)", this, sinkId));
+}
+// Copyright (c) 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.
+
+@Native("MediaEncryptedEvent")
+class MediaEncryptedEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory MediaEncryptedEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MediaEncryptedEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return MediaEncryptedEvent._create_1(type, eventInitDict_1);
+    }
+    return MediaEncryptedEvent._create_2(type);
+  }
+  static MediaEncryptedEvent _create_1(type, eventInitDict) => JS(
+      'MediaEncryptedEvent',
+      'new MediaEncryptedEvent(#,#)',
+      type,
+      eventInitDict);
+  static MediaEncryptedEvent _create_2(type) =>
+      JS('MediaEncryptedEvent', 'new MediaEncryptedEvent(#)', type);
+
+  final ByteBuffer initData;
+
+  final String initDataType;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("MediaError")
+class MediaError extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory MediaError._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int MEDIA_ERR_ABORTED = 1;
+
+  static const int MEDIA_ERR_DECODE = 3;
+
+  static const int MEDIA_ERR_NETWORK = 2;
+
+  static const int MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
+
+  final int code;
+
+  final String message;
+}
+// Copyright (c) 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.
+
+@Native("MediaKeyMessageEvent")
+class MediaKeyMessageEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory MediaKeyMessageEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MediaKeyMessageEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return MediaKeyMessageEvent._create_1(type, eventInitDict_1);
+  }
+  static MediaKeyMessageEvent _create_1(type, eventInitDict) => JS(
+      'MediaKeyMessageEvent',
+      'new MediaKeyMessageEvent(#,#)',
+      type,
+      eventInitDict);
+
+  final ByteBuffer message;
+
+  final String messageType;
+}
+// Copyright (c) 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.
+
+@Native("MediaKeySession")
+class MediaKeySession extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory MediaKeySession._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<MessageEvent> messageEvent =
+      const EventStreamProvider<MessageEvent>('message');
+
+  Future<void> get closed => promiseToFuture<void>(JS("", "#.closed", this));
+
+  final num expiration;
+
+  final MediaKeyStatusMap keyStatuses;
+
+  final String sessionId;
+
+  Future close() => promiseToFuture(JS("", "#.close()", this));
+
+  Future generateRequest(String initDataType, /*BufferSource*/ initData) =>
+      promiseToFuture(
+          JS("", "#.generateRequest(#, #)", this, initDataType, initData));
+
+  Future load(String sessionId) =>
+      promiseToFuture(JS("", "#.load(#)", this, sessionId));
+
+  Future remove() => promiseToFuture(JS("", "#.remove()", this));
+
+  @JSName('update')
+  Future _update(/*BufferSource*/ response) native;
+
+  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("MediaKeyStatusMap")
+class MediaKeyStatusMap extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory MediaKeyStatusMap._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int size;
+
+  Object get(/*BufferSource*/ keyId) native;
+
+  bool has(/*BufferSource*/ keyId) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("MediaKeySystemAccess")
+class MediaKeySystemAccess extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory MediaKeySystemAccess._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String keySystem;
+
+  Future createMediaKeys() =>
+      promiseToFuture(JS("", "#.createMediaKeys()", this));
+
+  Map getConfiguration() {
+    return convertNativeToDart_Dictionary(_getConfiguration_1());
+  }
+
+  @JSName('getConfiguration')
+  _getConfiguration_1() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("MediaKeys")
+class MediaKeys extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory MediaKeys._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('createSession')
+  MediaKeySession _createSession([String sessionType]) native;
+
+  Future getStatusForPolicy(MediaKeysPolicy policy) =>
+      promiseToFuture(JS("", "#.getStatusForPolicy(#)", this, policy));
+
+  Future setServerCertificate(/*BufferSource*/ serverCertificate) =>
+      promiseToFuture(
+          JS("", "#.setServerCertificate(#)", this, serverCertificate));
+}
+// Copyright (c) 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.
+
+@Native("MediaKeysPolicy")
+class MediaKeysPolicy extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory MediaKeysPolicy._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MediaKeysPolicy(Map init) {
+    var init_1 = convertDartToNative_Dictionary(init);
+    return MediaKeysPolicy._create_1(init_1);
+  }
+  static MediaKeysPolicy _create_1(init) =>
+      JS('MediaKeysPolicy', 'new MediaKeysPolicy(#)', init);
+
+  final String minHdcpVersion;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("MediaList")
+class MediaList extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory MediaList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int length;
+
+  String mediaText;
+
+  void appendMedium(String medium) native;
+
+  void deleteMedium(String medium) native;
+
+  String item(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("MediaMetadata")
+class MediaMetadata extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory MediaMetadata._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MediaMetadata([Map metadata]) {
+    if (metadata != null) {
+      var metadata_1 = convertDartToNative_Dictionary(metadata);
+      return MediaMetadata._create_1(metadata_1);
+    }
+    return MediaMetadata._create_2();
+  }
+  static MediaMetadata _create_1(metadata) =>
+      JS('MediaMetadata', 'new MediaMetadata(#)', metadata);
+  static MediaMetadata _create_2() =>
+      JS('MediaMetadata', 'new MediaMetadata()');
+
+  String album;
+
+  String artist;
+
+  List artwork;
+
+  String title;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("MediaQueryList")
+class MediaQueryList extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory MediaQueryList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> changeEvent =
+      const EventStreamProvider<Event>('change');
+
+  final bool matches;
+
+  final String media;
+
+  void addListener(EventListener listener) native;
+
+  void removeListener(EventListener listener) native;
+
+  Stream<Event> get onChange => changeEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("MediaQueryListEvent")
+class MediaQueryListEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory MediaQueryListEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MediaQueryListEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return MediaQueryListEvent._create_1(type, eventInitDict_1);
+    }
+    return MediaQueryListEvent._create_2(type);
+  }
+  static MediaQueryListEvent _create_1(type, eventInitDict) => JS(
+      'MediaQueryListEvent',
+      'new MediaQueryListEvent(#,#)',
+      type,
+      eventInitDict);
+  static MediaQueryListEvent _create_2(type) =>
+      JS('MediaQueryListEvent', 'new MediaQueryListEvent(#)', type);
+
+  final bool matches;
+
+  final String media;
+}
+// Copyright (c) 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.
+
+@Native("MediaRecorder")
+class MediaRecorder extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory MediaRecorder._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  static const EventStreamProvider<Event> pauseEvent =
+      const EventStreamProvider<Event>('pause');
+
+  factory MediaRecorder(MediaStream stream, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return MediaRecorder._create_1(stream, options_1);
+    }
+    return MediaRecorder._create_2(stream);
+  }
+  static MediaRecorder _create_1(stream, options) =>
+      JS('MediaRecorder', 'new MediaRecorder(#,#)', stream, options);
+  static MediaRecorder _create_2(stream) =>
+      JS('MediaRecorder', 'new MediaRecorder(#)', stream);
+
+  final int audioBitsPerSecond;
+
+  final String mimeType;
+
+  final String state;
+
+  final MediaStream stream;
+
+  final int videoBitsPerSecond;
+
+  static bool isTypeSupported(String type) native;
+
+  void pause() native;
+
+  void requestData() native;
+
+  void resume() native;
+
+  void start([int timeslice]) native;
+
+  void stop() native;
+
+  Stream<Event> get onError => errorEvent.forTarget(this);
+
+  Stream<Event> get onPause => pauseEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("MediaSession")
+class MediaSession extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory MediaSession._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  MediaMetadata metadata;
+
+  String playbackState;
+
+  void setActionHandler(String action, MediaSessionActionHandler handler)
+      native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void MediaSessionActionHandler();
+// Copyright (c) 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.
+
+@Native("MediaSettingsRange")
+class MediaSettingsRange extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory MediaSettingsRange._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num max;
+
+  final num min;
+
+  final num step;
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.IE, '11')
+@Native("MediaSource")
+class MediaSource extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory MediaSource._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MediaSource() {
+    return MediaSource._create_1();
+  }
+  static MediaSource _create_1() => JS('MediaSource', 'new MediaSource()');
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(window.MediaSource)');
+
+  final SourceBufferList activeSourceBuffers;
+
+  num duration;
+
+  final String readyState;
+
+  final SourceBufferList sourceBuffers;
+
+  SourceBuffer addSourceBuffer(String type) native;
+
+  void clearLiveSeekableRange() native;
+
+  void endOfStream([String error]) native;
+
+  static bool isTypeSupported(String type) native;
+
+  void removeSourceBuffer(SourceBuffer buffer) native;
+
+  void setLiveSeekableRange(num start, num end) native;
+}
+// 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@Native("MediaStream")
+class MediaStream extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory MediaStream._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `addtrack` events to event
+   * handlers that are not necessarily instances of [MediaStream].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> addTrackEvent =
+      const EventStreamProvider<Event>('addtrack');
+
+  /**
+   * Static factory designed to expose `removetrack` events to event
+   * handlers that are not necessarily instances of [MediaStream].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> removeTrackEvent =
+      const EventStreamProvider<Event>('removetrack');
+
+  factory MediaStream([stream_OR_tracks]) {
+    if (stream_OR_tracks == null) {
+      return MediaStream._create_1();
+    }
+    if ((stream_OR_tracks is MediaStream)) {
+      return MediaStream._create_2(stream_OR_tracks);
+    }
+    if ((stream_OR_tracks is List<MediaStreamTrack>)) {
+      return MediaStream._create_3(stream_OR_tracks);
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+  static MediaStream _create_1() => JS('MediaStream', 'new MediaStream()');
+  static MediaStream _create_2(stream_OR_tracks) =>
+      JS('MediaStream', 'new MediaStream(#)', stream_OR_tracks);
+  static MediaStream _create_3(stream_OR_tracks) =>
+      JS('MediaStream', 'new MediaStream(#)', stream_OR_tracks);
+
+  final bool active;
+
+  final String id;
+
+  void addTrack(MediaStreamTrack track) native;
+
+  MediaStream clone() native;
+
+  @Creates('JSExtendableArray|MediaStreamTrack')
+  @Returns('JSExtendableArray')
+  List<MediaStreamTrack> getAudioTracks() native;
+
+  MediaStreamTrack getTrackById(String trackId) native;
+
+  List<MediaStreamTrack> getTracks() native;
+
+  @Creates('JSExtendableArray|MediaStreamTrack')
+  @Returns('JSExtendableArray')
+  List<MediaStreamTrack> getVideoTracks() native;
+
+  void removeTrack(MediaStreamTrack track) native;
+
+  /// Stream of `addtrack` events handled by this [MediaStream].
+  Stream<Event> get onAddTrack => addTrackEvent.forTarget(this);
+
+  /// Stream of `removetrack` events handled by this [MediaStream].
+  Stream<Event> get onRemoveTrack => removeTrackEvent.forTarget(this);
+
+  /**
+   * Checks if the MediaStream APIs are supported on the current platform.
+   *
+   * See also:
+   *
+   * * [Navigator.getUserMedia]
+   */
+  static bool get supported => JS(
+      'bool',
+      '''!!(#.getUserMedia || #.webkitGetUserMedia ||
+        #.mozGetUserMedia || #.msGetUserMedia)''',
+      window.navigator,
+      window.navigator,
+      window.navigator,
+      window.navigator);
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@Native("MediaStreamEvent")
+class MediaStreamEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory MediaStreamEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MediaStreamEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return MediaStreamEvent._create_1(type, eventInitDict_1);
+    }
+    return MediaStreamEvent._create_2(type);
+  }
+  static MediaStreamEvent _create_1(type, eventInitDict) =>
+      JS('MediaStreamEvent', 'new MediaStreamEvent(#,#)', type, eventInitDict);
+  static MediaStreamEvent _create_2(type) =>
+      JS('MediaStreamEvent', 'new MediaStreamEvent(#)', type);
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => Device.isEventTypeSupported('MediaStreamEvent');
+
+  final MediaStream stream;
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@Native("MediaStreamTrack")
+class MediaStreamTrack extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory MediaStreamTrack._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `ended` events to event
+   * handlers that are not necessarily instances of [MediaStreamTrack].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> endedEvent =
+      const EventStreamProvider<Event>('ended');
+
+  /**
+   * Static factory designed to expose `mute` events to event
+   * handlers that are not necessarily instances of [MediaStreamTrack].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> muteEvent =
+      const EventStreamProvider<Event>('mute');
+
+  /**
+   * Static factory designed to expose `unmute` events to event
+   * handlers that are not necessarily instances of [MediaStreamTrack].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> unmuteEvent =
+      const EventStreamProvider<Event>('unmute');
+
+  String contentHint;
+
+  bool enabled;
+
+  final String id;
+
+  final String kind;
+
+  final String label;
+
+  final bool muted;
+
+  final String readyState;
+
+  Future applyConstraints([Map constraints]) {
+    var constraints_dict = null;
+    if (constraints != null) {
+      constraints_dict = convertDartToNative_Dictionary(constraints);
+    }
+    return promiseToFuture(
+        JS("", "#.applyConstraints(#)", this, constraints_dict));
+  }
+
+  MediaStreamTrack clone() native;
+
+  Map getCapabilities() {
+    return convertNativeToDart_Dictionary(_getCapabilities_1());
+  }
+
+  @JSName('getCapabilities')
+  _getCapabilities_1() native;
+
+  Map getConstraints() {
+    return convertNativeToDart_Dictionary(_getConstraints_1());
+  }
+
+  @JSName('getConstraints')
+  _getConstraints_1() native;
+
+  Map getSettings() {
+    return convertNativeToDart_Dictionary(_getSettings_1());
+  }
+
+  @JSName('getSettings')
+  _getSettings_1() native;
+
+  void stop() native;
+
+  /// Stream of `ended` events handled by this [MediaStreamTrack].
+  Stream<Event> get onEnded => endedEvent.forTarget(this);
+
+  /// Stream of `mute` events handled by this [MediaStreamTrack].
+  Stream<Event> get onMute => muteEvent.forTarget(this);
+
+  /// Stream of `unmute` events handled by this [MediaStreamTrack].
+  Stream<Event> get onUnmute => unmuteEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@Native("MediaStreamTrackEvent")
+class MediaStreamTrackEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory MediaStreamTrackEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MediaStreamTrackEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return MediaStreamTrackEvent._create_1(type, eventInitDict_1);
+  }
+  static MediaStreamTrackEvent _create_1(type, eventInitDict) => JS(
+      'MediaStreamTrackEvent',
+      'new MediaStreamTrackEvent(#,#)',
+      type,
+      eventInitDict);
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      Device.isEventTypeSupported('MediaStreamTrackEvent');
+
+  final MediaStreamTrack track;
+}
+// Copyright (c) 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.
+
+@Native("MemoryInfo")
+class MemoryInfo extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory MemoryInfo._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int jsHeapSizeLimit;
+
+  final int totalJSHeapSize;
+
+  final int usedJSHeapSize;
+}
+// Copyright (c) 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.
+
+/**
+ * An HTML <menu> element.
+ *
+ * A <menu> element represents an unordered list of menu commands.
+ *
+ * See also:
+ *
+ *  * [Menu Element](https://developer.mozilla.org/en-US/docs/HTML/Element/menu) from MDN.
+ *  * [Menu Element](http://www.w3.org/TR/html5/the-menu-element.html#the-menu-element) from the W3C.
+ */
+@Native("HTMLMenuElement")
+class MenuElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory MenuElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MenuElement() => JS(
+      'returns:MenuElement;creates:MenuElement;new:true',
+      '#.createElement(#)',
+      document,
+      "menu");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MenuElement.created() : super.created();
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void MessageCallback(Map message);
+// Copyright (c) 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.
+
+@Unstable()
+@Native("MessageChannel")
+class MessageChannel extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory MessageChannel._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MessageChannel() {
+    return MessageChannel._create_1();
+  }
+  static MessageChannel _create_1() =>
+      JS('MessageChannel', 'new MessageChannel()');
+
+  final MessagePort port1;
+
+  final MessagePort port2;
+}
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@Native("MessageEvent")
+class MessageEvent extends Event {
+  factory MessageEvent(String type,
+      {bool canBubble: false,
+      bool cancelable: false,
+      Object data,
+      String origin,
+      String lastEventId,
+      Window source,
+      List<MessagePort> messagePorts: const []}) {
+    if (source == null) {
+      source = window;
+    }
+    if (!Device.isIE) {
+      // TODO: This if check should be removed once IE
+      // implements the constructor.
+      return JS(
+          'MessageEvent',
+          'new MessageEvent(#, {bubbles: #, cancelable: #, data: #, origin: #, lastEventId: #, source: #, ports: #})',
+          type,
+          canBubble,
+          cancelable,
+          data,
+          origin,
+          lastEventId,
+          source,
+          messagePorts);
+    }
+    MessageEvent event = document._createEvent("MessageEvent");
+    event._initMessageEvent(type, canBubble, cancelable, data, origin,
+        lastEventId, source, messagePorts);
+    return event;
+  }
+
+  // TODO(alanknight): This really should be generated by the
+  // _OutputConversion in the systemnative.py script, but that doesn't
+  // use those conversions right now, so do this as a one-off.
+  dynamic get data => convertNativeToDart_SerializedScriptValue(this._get_data);
+
+  @JSName('data')
+  @annotation_Creates_SerializedScriptValue
+  @annotation_Returns_SerializedScriptValue
+  final dynamic _get_data;
+
+  factory MessageEvent._(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return MessageEvent._create_1(type, eventInitDict_1);
+    }
+    return MessageEvent._create_2(type);
+  }
+  static MessageEvent _create_1(type, eventInitDict) =>
+      JS('MessageEvent', 'new MessageEvent(#,#)', type, eventInitDict);
+  static MessageEvent _create_2(type) =>
+      JS('MessageEvent', 'new MessageEvent(#)', type);
+
+  @Unstable()
+  final String lastEventId;
+
+  final String origin;
+
+  @Unstable()
+  @Creates('JSExtendableArray')
+  final List<MessagePort> ports;
+
+  EventTarget get source => _convertNativeToDart_EventTarget(this._get_source);
+  @JSName('source')
+  @Creates('Null')
+  @Returns('EventTarget|=Object')
+  final dynamic _get_source;
+
+  final String suborigin;
+
+  void _initMessageEvent(
+      String typeArg,
+      bool canBubbleArg,
+      bool cancelableArg,
+      Object dataArg,
+      String originArg,
+      String lastEventIdArg,
+      EventTarget sourceArg,
+      List<MessagePort> portsArg) {
+    var sourceArg_1 = _convertDartToNative_EventTarget(sourceArg);
+    _initMessageEvent_1(typeArg, canBubbleArg, cancelableArg, dataArg,
+        originArg, lastEventIdArg, sourceArg_1, portsArg);
+    return;
+  }
+
+  @JSName('initMessageEvent')
+  void _initMessageEvent_1(typeArg, canBubbleArg, cancelableArg, dataArg,
+      originArg, lastEventIdArg, sourceArg, List<MessagePort> portsArg) native;
+}
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@Unstable()
+@Native("MessagePort")
+class MessagePort extends EventTarget {
+  void addEventListener(String type, EventListener listener,
+      [bool useCapture]) {
+    // Messages posted to ports are initially paused, allowing listeners to be
+    // setup, start() needs to be explicitly invoked to begin handling messages.
+    if (type == 'message') {
+      _start();
+    }
+
+    super.addEventListener(type, listener, useCapture);
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory MessagePort._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `message` events to event
+   * handlers that are not necessarily instances of [MessagePort].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MessageEvent> messageEvent =
+      const EventStreamProvider<MessageEvent>('message');
+
+  void close() native;
+
+  void postMessage(/*any*/ message, [List<Object> transfer]) {
+    if (transfer != null) {
+      var message_1 = convertDartToNative_SerializedScriptValue(message);
+      _postMessage_1(message_1, transfer);
+      return;
+    }
+    var message_1 = convertDartToNative_SerializedScriptValue(message);
+    _postMessage_2(message_1);
+    return;
+  }
+
+  @JSName('postMessage')
+  void _postMessage_1(message, List<Object> transfer) native;
+  @JSName('postMessage')
+  void _postMessage_2(message) native;
+
+  @JSName('start')
+  void _start() native;
+
+  /// Stream of `message` events handled by this [MessagePort].
+  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
+}
+
+// Copyright (c) 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.
+
+@Native("HTMLMetaElement")
+class MetaElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory MetaElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MetaElement() => JS(
+      'returns:MetaElement;creates:MetaElement;new:true',
+      '#.createElement(#)',
+      document,
+      "meta");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MetaElement.created() : super.created();
+
+  String content;
+
+  String httpEquiv;
+
+  String name;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("Metadata")
+class Metadata extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Metadata._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  DateTime get modificationTime =>
+      convertNativeToDart_DateTime(this._get_modificationTime);
+  @JSName('modificationTime')
+  @Creates('Null')
+  final dynamic _get_modificationTime;
+
+  final int size;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void MetadataCallback(Metadata metadata);
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("HTMLMeterElement")
+class MeterElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory MeterElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MeterElement() => document.createElement("meter");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MeterElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => Element.isTagSupported('meter');
+
+  num high;
+
+  @Unstable()
+  @Returns('NodeList|Null')
+  @Creates('NodeList')
+  final List<Node> labels;
+
+  num low;
+
+  num max;
+
+  num min;
+
+  num optimum;
+
+  num value;
+}
+// Copyright (c) 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.
+
+@Native("MIDIAccess")
+class MidiAccess extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory MidiAccess._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final MidiInputMap inputs;
+
+  final MidiOutputMap outputs;
+
+  final bool sysexEnabled;
+}
+// Copyright (c) 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.
+
+@Native("MIDIConnectionEvent")
+class MidiConnectionEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory MidiConnectionEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MidiConnectionEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return MidiConnectionEvent._create_1(type, eventInitDict_1);
+    }
+    return MidiConnectionEvent._create_2(type);
+  }
+  static MidiConnectionEvent _create_1(type, eventInitDict) => JS(
+      'MidiConnectionEvent',
+      'new MIDIConnectionEvent(#,#)',
+      type,
+      eventInitDict);
+  static MidiConnectionEvent _create_2(type) =>
+      JS('MidiConnectionEvent', 'new MIDIConnectionEvent(#)', type);
+
+  final MidiPort port;
+}
+// Copyright (c) 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.
+
+@Native("MIDIInput")
+class MidiInput extends MidiPort {
+  // To suppress missing implicit constructor warnings.
+  factory MidiInput._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `midimessage` events to event
+   * handlers that are not necessarily instances of [MidiInput].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MidiMessageEvent> midiMessageEvent =
+      const EventStreamProvider<MidiMessageEvent>('midimessage');
+
+  /// Stream of `midimessage` events handled by this [MidiInput].
+  Stream<MidiMessageEvent> get onMidiMessage =>
+      midiMessageEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("MIDIInputMap")
+class MidiInputMap extends Interceptor with MapMixin<String, dynamic> {
+  // To suppress missing implicit constructor warnings.
+  factory MidiInputMap._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Map _getItem(String key) =>
+      convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key));
+
+  void addAll(Map<String, dynamic> other) {
+    throw new UnsupportedError("Not supported");
+  }
+
+  bool containsValue(dynamic value) => values.any((e) => e == value);
+
+  bool containsKey(dynamic key) => _getItem(key) != null;
+
+  Map operator [](dynamic key) => _getItem(key);
+
+  void forEach(void f(String key, dynamic value)) {
+    var entries = JS('', '#.entries()', this);
+    while (true) {
+      var entry = JS('', '#.next()', entries);
+      if (JS('bool', '#.done', entry)) return;
+      f(JS('String', '#.value[0]', entry),
+          convertNativeToDart_Dictionary(JS('', '#.value[1]', entry)));
+    }
+  }
+
+  Iterable<String> get keys {
+    final keys = <String>[];
+    forEach((k, v) => keys.add(k));
+    return keys;
+  }
+
+  Iterable<Map> get values {
+    final values = <Map>[];
+    forEach((k, v) => values.add(v));
+    return values;
+  }
+
+  int get length => JS('int', '#.size', this);
+
+  bool get isEmpty => length == 0;
+
+  bool get isNotEmpty => !isEmpty;
+
+  void operator []=(String key, dynamic value) {
+    throw new UnsupportedError("Not supported");
+  }
+
+  dynamic putIfAbsent(String key, dynamic ifAbsent()) {
+    throw new UnsupportedError("Not supported");
+  }
+
+  String remove(dynamic key) {
+    throw new UnsupportedError("Not supported");
+  }
+
+  void clear() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("MIDIMessageEvent")
+class MidiMessageEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory MidiMessageEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MidiMessageEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return MidiMessageEvent._create_1(type, eventInitDict_1);
+    }
+    return MidiMessageEvent._create_2(type);
+  }
+  static MidiMessageEvent _create_1(type, eventInitDict) =>
+      JS('MidiMessageEvent', 'new MIDIMessageEvent(#,#)', type, eventInitDict);
+  static MidiMessageEvent _create_2(type) =>
+      JS('MidiMessageEvent', 'new MIDIMessageEvent(#)', type);
+
+  final Uint8List data;
+}
+// Copyright (c) 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.
+
+@Native("MIDIOutput")
+class MidiOutput extends MidiPort {
+  // To suppress missing implicit constructor warnings.
+  factory MidiOutput._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  void send(Uint8List data, [num timestamp]) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("MIDIOutputMap")
+class MidiOutputMap extends Interceptor with MapMixin<String, dynamic> {
+  // To suppress missing implicit constructor warnings.
+  factory MidiOutputMap._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Map _getItem(String key) =>
+      convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key));
+
+  void addAll(Map<String, dynamic> other) {
+    throw new UnsupportedError("Not supported");
+  }
+
+  bool containsValue(dynamic value) => values.any((e) => e == value);
+
+  bool containsKey(dynamic key) => _getItem(key) != null;
+
+  Map operator [](dynamic key) => _getItem(key);
+
+  void forEach(void f(String key, dynamic value)) {
+    var entries = JS('', '#.entries()', this);
+    while (true) {
+      var entry = JS('', '#.next()', entries);
+      if (JS('bool', '#.done', entry)) return;
+      f(JS('String', '#.value[0]', entry),
+          convertNativeToDart_Dictionary(JS('', '#.value[1]', entry)));
+    }
+  }
+
+  Iterable<String> get keys {
+    final keys = <String>[];
+    forEach((k, v) => keys.add(k));
+    return keys;
+  }
+
+  Iterable<Map> get values {
+    final values = <Map>[];
+    forEach((k, v) => values.add(v));
+    return values;
+  }
+
+  int get length => JS('int', '#.size', this);
+
+  bool get isEmpty => length == 0;
+
+  bool get isNotEmpty => !isEmpty;
+
+  void operator []=(String key, dynamic value) {
+    throw new UnsupportedError("Not supported");
+  }
+
+  dynamic putIfAbsent(String key, dynamic ifAbsent()) {
+    throw new UnsupportedError("Not supported");
+  }
+
+  String remove(dynamic key) {
+    throw new UnsupportedError("Not supported");
+  }
+
+  void clear() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("MIDIPort")
+class MidiPort extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory MidiPort._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String connection;
+
+  final String id;
+
+  final String manufacturer;
+
+  final String name;
+
+  final String state;
+
+  final String type;
+
+  final String version;
+
+  Future close() => promiseToFuture(JS("", "#.close()", this));
+
+  Future open() => promiseToFuture(JS("", "#.open()", this));
+}
+// Copyright (c) 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.
+
+@Native("MimeType")
+class MimeType extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory MimeType._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String description;
+
+  final Plugin enabledPlugin;
+
+  final String suffixes;
+
+  final String type;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("MimeTypeArray")
+class MimeTypeArray extends Interceptor
+    with ListMixin<MimeType>, ImmutableListMixin<MimeType>
+    implements List<MimeType>, JavaScriptIndexingBehavior<MimeType> {
+  // To suppress missing implicit constructor warnings.
+  factory MimeTypeArray._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  MimeType operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return JS("MimeType", "#[#]", this, index);
+  }
+
+  void operator []=(int index, MimeType value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<MimeType> mixins.
+  // MimeType is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  MimeType get first {
+    if (this.length > 0) {
+      return JS('MimeType', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  MimeType get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('MimeType', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  MimeType get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('MimeType', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  MimeType elementAt(int index) => this[index];
+  // -- end List<MimeType> mixins.
+
+  MimeType item(int index) native;
+
+  MimeType namedItem(String name) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("HTMLModElement")
+class ModElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory ModElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ModElement.created() : super.created();
+
+  String cite;
+
+  String dateTime;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void MojoWatchCallback(int result);
+// Copyright (c) 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.
+
+@Native("MouseEvent,DragEvent")
+class MouseEvent extends UIEvent {
+  factory MouseEvent(String type,
+      {Window view,
+      int detail: 0,
+      int screenX: 0,
+      int screenY: 0,
+      int clientX: 0,
+      int clientY: 0,
+      int button: 0,
+      bool canBubble: true,
+      bool cancelable: true,
+      bool ctrlKey: false,
+      bool altKey: false,
+      bool shiftKey: false,
+      bool metaKey: false,
+      EventTarget relatedTarget}) {
+    if (view == null) {
+      view = window;
+    }
+    MouseEvent event = document._createEvent('MouseEvent');
+    event._initMouseEvent(
+        type,
+        canBubble,
+        cancelable,
+        view,
+        detail,
+        screenX,
+        screenY,
+        clientX,
+        clientY,
+        ctrlKey,
+        altKey,
+        shiftKey,
+        metaKey,
+        button,
+        relatedTarget);
+    return event;
+  }
+
+  factory MouseEvent._(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return MouseEvent._create_1(type, eventInitDict_1);
+    }
+    return MouseEvent._create_2(type);
+  }
+  static MouseEvent _create_1(type, eventInitDict) =>
+      JS('MouseEvent', 'new MouseEvent(#,#)', type, eventInitDict);
+  static MouseEvent _create_2(type) =>
+      JS('MouseEvent', 'new MouseEvent(#)', type);
+
+  final bool altKey;
+
+  final int button;
+
+  final int buttons;
+
+  @JSName('clientX')
+  final num _clientX;
+
+  @JSName('clientY')
+  final num _clientY;
+
+  final bool ctrlKey;
+
+  /**
+   * The nonstandard way to access the element that the mouse comes
+   * from in the case of a `mouseover` event.
+   *
+   * This member is deprecated and not cross-browser compatible; use
+   * relatedTarget to get the same information in the standard way.
+   */
+  @deprecated
+  final Node fromElement;
+
+  @JSName('layerX')
+  final int _layerX;
+
+  @JSName('layerY')
+  final int _layerY;
+
+  final bool metaKey;
+
+  @JSName('movementX')
+  final int _movementX;
+
+  @JSName('movementY')
+  final int _movementY;
+
+  @JSName('pageX')
+  final num _pageX;
+
+  @JSName('pageY')
+  final num _pageY;
+
+  final String region;
+
+  EventTarget get relatedTarget =>
+      _convertNativeToDart_EventTarget(this._get_relatedTarget);
+  @JSName('relatedTarget')
+  @Creates('Node')
+  @Returns('EventTarget|=Object|Null')
+  final dynamic _get_relatedTarget;
+
+  @JSName('screenX')
+  final num _screenX;
+
+  @JSName('screenY')
+  final num _screenY;
+
+  final bool shiftKey;
+
+  /**
+   * The nonstandard way to access the element that the mouse goes
+   * to in the case of a `mouseout` event.
+   *
+   * This member is deprecated and not cross-browser compatible; use
+   * relatedTarget to get the same information in the standard way.
+   */
+  @deprecated
+  final Node toElement;
+
+  bool getModifierState(String keyArg) native;
+
+  void _initMouseEvent(
+      String type,
+      bool bubbles,
+      bool cancelable,
+      Window view,
+      int detail,
+      int screenX,
+      int screenY,
+      int clientX,
+      int clientY,
+      bool ctrlKey,
+      bool altKey,
+      bool shiftKey,
+      bool metaKey,
+      int button,
+      EventTarget relatedTarget) {
+    var relatedTarget_1 = _convertDartToNative_EventTarget(relatedTarget);
+    _initMouseEvent_1(
+        type,
+        bubbles,
+        cancelable,
+        view,
+        detail,
+        screenX,
+        screenY,
+        clientX,
+        clientY,
+        ctrlKey,
+        altKey,
+        shiftKey,
+        metaKey,
+        button,
+        relatedTarget_1);
+    return;
+  }
+
+  @JSName('initMouseEvent')
+  void _initMouseEvent_1(
+      type,
+      bubbles,
+      cancelable,
+      Window view,
+      detail,
+      screenX,
+      screenY,
+      clientX,
+      clientY,
+      ctrlKey,
+      altKey,
+      shiftKey,
+      metaKey,
+      button,
+      relatedTarget) native;
+
+  Point get client => new Point(_clientX, _clientY);
+
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  Point get movement => new Point(_movementX, _movementY);
+
+  /**
+   * The coordinates of the mouse pointer in target node coordinates.
+   *
+   * This value may vary between platforms if the target node moves
+   * after the event has fired or if the element has CSS transforms affecting
+   * it.
+   */
+  Point get offset {
+    if (JS('bool', '!!#.offsetX', this)) {
+      var x = JS('int', '#.offsetX', this);
+      var y = JS('int', '#.offsetY', this);
+      return new Point(x, y);
+    } else {
+      // Firefox does not support offsetX.
+      if (!(this.target is Element)) {
+        throw new UnsupportedError('offsetX is only supported on elements');
+      }
+      Element target = this.target;
+      var point = (this.client - target.getBoundingClientRect().topLeft);
+      return new Point(point.x.toInt(), point.y.toInt());
+    }
+  }
+
+  Point get screen => new Point(_screenX, _screenY);
+
+  Point get layer => new Point(_layerX, _layerY);
+
+  Point get page => new Point(_pageX, _pageY);
+
+  DataTransfer get dataTransfer =>
+      JS('DataTransfer', "#['dataTransfer']", this);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void MutationCallback(List mutations, MutationObserver observer);
+// Copyright (c) 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.
+
+// http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents
+@deprecated
+@Native("MutationEvent")
+class MutationEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory MutationEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int ADDITION = 2;
+
+  static const int MODIFICATION = 1;
+
+  static const int REMOVAL = 3;
+
+  final int attrChange;
+
+  final String attrName;
+
+  final String newValue;
+
+  final String prevValue;
+
+  final Node relatedNode;
+
+  void initMutationEvent(
+      String type,
+      bool bubbles,
+      bool cancelable,
+      Node relatedNode,
+      String prevValue,
+      String newValue,
+      String attrName,
+      int attrChange) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Native("MutationObserver,WebKitMutationObserver")
+class MutationObserver extends Interceptor {
+  void disconnect() native;
+
+  void _observe(Node target, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      _observe_1(target, options_1);
+      return;
+    }
+    _observe_2(target);
+    return;
+  }
+
+  @JSName('observe')
+  void _observe_1(Node target, options) native;
+  @JSName('observe')
+  void _observe_2(Node target) native;
+
+  List<MutationRecord> takeRecords() native;
+
+  /**
+   * Checks to see if the mutation observer API is supported on the current
+   * platform.
+   */
+  static bool get supported {
+    return JS(
+        'bool', '!!(window.MutationObserver || window.WebKitMutationObserver)');
+  }
+
+  /**
+   * Observes the target for the specified changes.
+   *
+   * Some requirements for the optional parameters:
+   *
+   * * Either childList, attributes or characterData must be true.
+   * * If attributeOldValue is true then attributes must also be true.
+   * * If attributeFilter is specified then attributes must be true.
+   * * If characterDataOldValue is true then characterData must be true.
+   */
+  void observe(Node target,
+      {bool childList,
+      bool attributes,
+      bool characterData,
+      bool subtree,
+      bool attributeOldValue,
+      bool characterDataOldValue,
+      List<String> attributeFilter}) {
+    // Parse options into map of known type.
+    var parsedOptions = _createDict();
+
+    // Override options passed in the map with named optional arguments.
+    override(key, value) {
+      if (value != null) _add(parsedOptions, key, value);
+    }
+
+    override('childList', childList);
+    override('attributes', attributes);
+    override('characterData', characterData);
+    override('subtree', subtree);
+    override('attributeOldValue', attributeOldValue);
+    override('characterDataOldValue', characterDataOldValue);
+    if (attributeFilter != null) {
+      override('attributeFilter', _fixupList(attributeFilter));
+    }
+
+    _call(target, parsedOptions);
+  }
+
+  // TODO: Change to a set when const Sets are available.
+  static final _boolKeys = const {
+    'childList': true,
+    'attributes': true,
+    'characterData': true,
+    'subtree': true,
+    'attributeOldValue': true,
+    'characterDataOldValue': true
+  };
+
+  static _createDict() => JS('var', '{}');
+  static _add(m, String key, value) {
+    JS('void', '#[#] = #', m, key, value);
+  }
+
+  static _fixupList(list) => list; // TODO: Ensure is a JavaScript Array.
+
+  // Call native function with no conversions.
+  @JSName('observe')
+  void _call(target, options) native;
+
+  factory MutationObserver(MutationCallback callback) {
+    // Dummy statement to mark types as instantiated.
+    JS('MutationObserver|MutationRecord', '0');
+
+    return JS(
+        'MutationObserver',
+        'new(window.MutationObserver||window.WebKitMutationObserver||'
+            'window.MozMutationObserver)(#)',
+        convertDartClosureToJS(_wrapBinaryZone(callback), 2));
+  }
+}
+// Copyright (c) 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.
+
+@Native("MutationRecord")
+class MutationRecord extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory MutationRecord._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @Returns('NodeList|Null')
+  @Creates('NodeList')
+  final List<Node> addedNodes;
+
+  final String attributeName;
+
+  final String attributeNamespace;
+
+  final Node nextSibling;
+
+  final String oldValue;
+
+  final Node previousSibling;
+
+  @Returns('NodeList|Null')
+  @Creates('NodeList')
+  final List<Node> removedNodes;
+
+  final Node target;
+
+  final String type;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("NavigationPreloadManager")
+class NavigationPreloadManager extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory NavigationPreloadManager._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Future disable() => promiseToFuture(JS("", "#.disable()", this));
+
+  Future enable() => promiseToFuture(JS("", "#.enable()", this));
+
+  Future<Map<String, dynamic>> getState() =>
+      promiseToFutureAsMap(JS("", "#.getState()", this));
+}
+// Copyright (c) 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.
+
+@Native("Navigator")
+class Navigator extends NavigatorConcurrentHardware
+    implements
+        NavigatorCookies,
+        NavigatorLanguage,
+        NavigatorOnLine,
+        NavigatorAutomationInformation,
+        NavigatorID {
+  List<Gamepad> getGamepads() {
+    var gamepadList = _getGamepads();
+
+    // If no prototype we need one for the world to hookup to the proper Dart class.
+    var jsProto = JS('', '#.prototype', gamepadList);
+    if (jsProto == null) {
+      JS('', '#.prototype = Object.create(null)', gamepadList);
+    }
+
+    applyExtension('GamepadList', gamepadList);
+    return gamepadList;
+  }
+
+  String get language =>
+      JS('String', '#.language || #.userLanguage', this, this);
+
+  /**
+   * Gets a stream (video and or audio) from the local computer.
+   *
+   * Use [MediaStream.supported] to check if this is supported by the current
+   * platform. The arguments `audio` and `video` default to `false` (stream does
+   * not use audio or video, respectively).
+   *
+   * Simple example usage:
+   *
+   *     window.navigator.getUserMedia(audio: true, video: true).then((stream) {
+   *       var video = new VideoElement()
+   *         ..autoplay = true
+   *         ..src = Url.createObjectUrlFromStream(stream);
+   *       document.body.append(video);
+   *     });
+   *
+   * The user can also pass in Maps to the audio or video parameters to specify
+   * mandatory and optional constraints for the media stream. Not passing in a
+   * map, but passing in `true` will provide a MediaStream with audio or
+   * video capabilities, but without any additional constraints. The particular
+   * constraint names for audio and video are still in flux, but as of this
+   * writing, here is an example providing more constraints.
+   *
+   *     window.navigator.getUserMedia(
+   *         audio: true,
+   *         video: {'mandatory':
+   *                    { 'minAspectRatio': 1.333, 'maxAspectRatio': 1.334 },
+   *                 'optional':
+   *                    [{ 'minFrameRate': 60 },
+   *                     { 'maxWidth': 640 }]
+   *     });
+   *
+   * See also:
+   * * [MediaStream.supported]
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  Future<MediaStream> getUserMedia({audio: false, video: false}) {
+    var completer = new Completer<MediaStream>();
+    var options = {'audio': audio, 'video': video};
+    _ensureGetUserMedia();
+    this._getUserMedia(convertDartToNative_SerializedScriptValue(options),
+        (stream) {
+      completer.complete(stream);
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+
+  _ensureGetUserMedia() {
+    if (JS('bool', '!(#.getUserMedia)', this)) {
+      JS(
+          'void',
+          '#.getUserMedia = '
+              '(#.getUserMedia || #.webkitGetUserMedia || #.mozGetUserMedia ||'
+              '#.msGetUserMedia)',
+          this,
+          this,
+          this,
+          this,
+          this);
+    }
+  }
+
+  @JSName('getUserMedia')
+  void _getUserMedia(options, _NavigatorUserMediaSuccessCallback success,
+      _NavigatorUserMediaErrorCallback error) native;
+
+  // To suppress missing implicit constructor warnings.
+  factory Navigator._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final _BudgetService budget;
+
+  final _Clipboard clipboard;
+
+  final NetworkInformation connection;
+
+  final CredentialsContainer credentials;
+
+  final num deviceMemory;
+
+  final String doNotTrack;
+
+  @Unstable()
+  final Geolocation geolocation;
+
+  final int maxTouchPoints;
+
+  final MediaCapabilities mediaCapabilities;
+
+  final MediaDevices mediaDevices;
+
+  final MediaSession mediaSession;
+
+  final MimeTypeArray mimeTypes;
+
+  final _NFC nfc;
+
+  final Permissions permissions;
+
+  final Presentation presentation;
+
+  @Unstable()
+  final String productSub;
+
+  final ServiceWorkerContainer serviceWorker;
+
+  final StorageManager storage;
+
+  @Unstable()
+  final String vendor;
+
+  @Unstable()
+  final String vendorSub;
+
+  final VR vr;
+
+  @JSName('webkitPersistentStorage')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  final DeprecatedStorageQuota persistentStorage;
+
+  @JSName('webkitTemporaryStorage')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  final DeprecatedStorageQuota temporaryStorage;
+
+  void cancelKeyboardLock() native;
+
+  Future getBattery() => promiseToFuture(JS("", "#.getBattery()", this));
+
+  @JSName('getGamepads')
+  @Returns('_GamepadList|Null')
+  @Creates('_GamepadList')
+  List<Gamepad> _getGamepads() native;
+
+  Future<RelatedApplication> getInstalledRelatedApps() =>
+      promiseToFuture<RelatedApplication>(
+          JS("", "#.getInstalledRelatedApps()", this));
+
+  Future getVRDisplays() => promiseToFuture(JS("", "#.getVRDisplays()", this));
+
+  @Unstable()
+  void registerProtocolHandler(String scheme, String url, String title) native;
+
+  Future requestKeyboardLock([List<String> keyCodes]) {
+    if (keyCodes != null) {
+      List keyCodes_1 = convertDartToNative_StringArray(keyCodes);
+      return _requestKeyboardLock_1(keyCodes_1);
+    }
+    return _requestKeyboardLock_2();
+  }
+
+  @JSName('requestKeyboardLock')
+  Future _requestKeyboardLock_1(List keyCodes) =>
+      promiseToFuture(JS("", "#.requestKeyboardLock(#)", this, keyCodes));
+  @JSName('requestKeyboardLock')
+  Future _requestKeyboardLock_2() =>
+      promiseToFuture(JS("", "#.requestKeyboardLock()", this));
+
+  @JSName('requestMIDIAccess')
+  Future requestMidiAccess([Map options]) {
+    var options_dict = null;
+    if (options != null) {
+      options_dict = convertDartToNative_Dictionary(options);
+    }
+    return promiseToFuture(
+        JS("", "#.requestMidiAccess(#)", this, options_dict));
+  }
+
+  Future requestMediaKeySystemAccess(
+          String keySystem, List<Map> supportedConfigurations) =>
+      promiseToFuture(JS("", "#.requestMediaKeySystemAccess(#, #)", this,
+          keySystem, supportedConfigurations));
+
+  bool sendBeacon(String url, Object data) native;
+
+  Future share([Map data]) {
+    var data_dict = null;
+    if (data != null) {
+      data_dict = convertDartToNative_Dictionary(data);
+    }
+    return promiseToFuture(JS("", "#.share(#)", this, data_dict));
+  }
+
+  // From NavigatorAutomationInformation
+
+  final bool webdriver;
+
+  // From NavigatorCookies
+
+  @Unstable()
+  final bool cookieEnabled;
+
+  // From NavigatorID
+
+  final String appCodeName;
+
+  final String appName;
+
+  final String appVersion;
+
+  final bool dartEnabled;
+
+  final String platform;
+
+  @Unstable()
+  final String product;
+
+  final String userAgent;
+
+  // From NavigatorLanguage
+
+  final List<String> languages;
+
+  // From NavigatorOnLine
+
+  @Unstable()
+  final bool onLine;
+}
+// Copyright (c) 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.
+
+@Native("NavigatorAutomationInformation")
+class NavigatorAutomationInformation extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory NavigatorAutomationInformation._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool webdriver;
+}
+// Copyright (c) 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.
+
+@Native("NavigatorConcurrentHardware")
+class NavigatorConcurrentHardware extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory NavigatorConcurrentHardware._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int hardwareConcurrency;
+}
+// Copyright (c) 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.
+
+@Native("NavigatorCookies")
+class NavigatorCookies extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory NavigatorCookies._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool cookieEnabled;
+}
+// Copyright (c) 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.
+
+abstract class NavigatorID extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory NavigatorID._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String appCodeName;
+
+  final String appName;
+
+  final String appVersion;
+
+  final bool dartEnabled;
+
+  final String platform;
+
+  final String product;
+
+  final String userAgent;
+}
+// Copyright (c) 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.
+
+abstract class NavigatorLanguage extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory NavigatorLanguage._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String language;
+
+  final List<String> languages;
+}
+// Copyright (c) 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.
+
+abstract class NavigatorOnLine extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory NavigatorOnLine._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool onLine;
+}
+// Copyright (c) 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.
+
+@Native("NavigatorUserMediaError")
+class NavigatorUserMediaError extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory NavigatorUserMediaError._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String constraintName;
+
+  final String message;
+
+  final String name;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void _NavigatorUserMediaErrorCallback(NavigatorUserMediaError error);
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void _NavigatorUserMediaSuccessCallback(MediaStream stream);
+// Copyright (c) 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.
+
+@Native("NetworkInformation")
+class NetworkInformation extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory NetworkInformation._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> changeEvent =
+      const EventStreamProvider<Event>('change');
+
+  final num downlink;
+
+  final num downlinkMax;
+
+  final String effectiveType;
+
+  final int rtt;
+
+  final String type;
+
+  Stream<Event> get onChange => changeEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+/**
+ * Lazy implementation of the child nodes of an element that does not request
+ * the actual child nodes of an element until strictly necessary greatly
+ * improving performance for the typical cases where it is not required.
+ */
+class _ChildNodeListLazy extends ListBase<Node> implements NodeListWrapper {
+  final Node _this;
+
+  _ChildNodeListLazy(this._this);
+
+  Node get first {
+    Node result = JS('Node|Null', '#.firstChild', _this);
+    if (result == null) throw new StateError("No elements");
+    return result;
+  }
+
+  Node get last {
+    Node result = JS('Node|Null', '#.lastChild', _this);
+    if (result == null) throw new StateError("No elements");
+    return result;
+  }
+
+  Node get single {
+    int l = this.length;
+    if (l == 0) throw new StateError("No elements");
+    if (l > 1) throw new StateError("More than one element");
+    return JS('Node|Null', '#.firstChild', _this);
+  }
+
+  void add(Node value) {
+    _this.append(value);
+  }
+
+  void addAll(Iterable<Node> iterable) {
+    if (iterable is _ChildNodeListLazy) {
+      _ChildNodeListLazy otherList = iterable;
+      if (!identical(otherList._this, _this)) {
+        // Optimized route for copying between nodes.
+        for (var i = 0, len = otherList.length; i < len; ++i) {
+          _this.append(otherList._this.firstChild);
+        }
+      }
+      return;
+    }
+    for (Node node in iterable) {
+      _this.append(node);
+    }
+  }
+
+  void insert(int index, Node node) {
+    if (index < 0 || index > length) {
+      throw new RangeError.range(index, 0, length);
+    }
+    if (index == length) {
+      _this.append(node);
+    } else {
+      _this.insertBefore(node, this[index]);
+    }
+  }
+
+  void insertAll(int index, Iterable<Node> iterable) {
+    if (index == length) {
+      addAll(iterable);
+    } else {
+      var item = this[index];
+      _this.insertAllBefore(iterable, item);
+    }
+  }
+
+  void setAll(int index, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot setAll on Node list");
+  }
+
+  Node removeLast() {
+    final result = last;
+    if (result != null) {
+      _this._removeChild(result);
+    }
+    return result;
+  }
+
+  Node removeAt(int index) {
+    var result = this[index];
+    if (result != null) {
+      _this._removeChild(result);
+    }
+    return result;
+  }
+
+  bool remove(Object object) {
+    if (object is! Node) return false;
+    Node node = object;
+    if (!identical(_this, node.parentNode)) return false;
+    _this._removeChild(node);
+    return true;
+  }
+
+  void _filter(bool test(Node node), bool removeMatching) {
+    // This implementation of removeWhere/retainWhere is more efficient
+    // than the default in ListBase. Child nodes can be removed in constant
+    // time.
+    Node child = _this.firstChild;
+    while (child != null) {
+      Node nextChild = child.nextNode;
+      if (test(child) == removeMatching) {
+        _this._removeChild(child);
+      }
+      child = nextChild;
+    }
+  }
+
+  void removeWhere(bool test(Node node)) {
+    _filter(test, true);
+  }
+
+  void retainWhere(bool test(Node node)) {
+    _filter(test, false);
+  }
+
+  void clear() {
+    _this._clearChildren();
+  }
+
+  void operator []=(int index, Node value) {
+    _this._replaceChild(value, this[index]);
+  }
+
+  Iterator<Node> get iterator => _this.childNodes.iterator;
+
+  // From List<Node>:
+
+  // TODO(jacobr): this could be implemented for child node lists.
+  // The exception we throw here is misleading.
+  void sort([Comparator<Node> compare]) {
+    throw new UnsupportedError("Cannot sort Node list");
+  }
+
+  void shuffle([Random random]) {
+    throw new UnsupportedError("Cannot shuffle Node list");
+  }
+
+  // FIXME: implement these.
+  void setRange(int start, int end, Iterable<Node> iterable,
+      [int skipCount = 0]) {
+    throw new UnsupportedError("Cannot setRange on Node list");
+  }
+
+  void fillRange(int start, int end, [Node fill]) {
+    throw new UnsupportedError("Cannot fillRange on Node list");
+  }
+
+  void removeRange(int start, int end) {
+    throw new UnsupportedError("Cannot removeRange on Node list");
+  }
+  // -- end List<Node> mixins.
+
+  // TODO(jacobr): benchmark whether this is more efficient or whether caching
+  // a local copy of childNodes is more efficient.
+  int get length => _this.childNodes.length;
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot set length on immutable List.");
+  }
+
+  Node operator [](int index) => _this.childNodes[index];
+
+  List<Node> get rawList => _this.childNodes;
+}
+
+@Native("Node")
+class Node extends EventTarget {
+  // Custom element created callback.
+  Node._created() : super._created();
+
+  /**
+   * A modifiable list of this node's children.
+   */
+  List<Node> get nodes {
+    return new _ChildNodeListLazy(this);
+  }
+
+  set nodes(Iterable<Node> value) {
+    // Copy list first since we don't want liveness during iteration.
+    // TODO(jacobr): there is a better way to do this.
+    var copy = value.toList();
+    text = '';
+    for (Node node in copy) {
+      append(node);
+    }
+  }
+
+  /**
+   * Removes this node from the DOM.
+   */
+  void remove() {
+    // TODO(jacobr): should we throw an exception if parent is already null?
+    // TODO(vsm): Use the native remove when available.
+    if (this.parentNode != null) {
+      final Node parent = this.parentNode;
+      parentNode._removeChild(this);
+    }
+  }
+
+  /**
+   * Replaces this node with another node.
+   */
+  Node replaceWith(Node otherNode) {
+    try {
+      final Node parent = this.parentNode;
+      parent._replaceChild(otherNode, this);
+    } catch (e) {}
+    ;
+    return this;
+  }
+
+  /**
+   * Inserts all of the nodes into this node directly before refChild.
+   *
+   * See also:
+   *
+   * * [insertBefore]
+   */
+  Node insertAllBefore(Iterable<Node> newNodes, Node refChild) {
+    if (newNodes is _ChildNodeListLazy) {
+      _ChildNodeListLazy otherList = newNodes;
+      if (identical(otherList._this, this)) {
+        throw new ArgumentError(newNodes);
+      }
+
+      // Optimized route for copying between nodes.
+      for (var i = 0, len = otherList.length; i < len; ++i) {
+        this.insertBefore(otherList._this.firstChild, refChild);
+      }
+    } else {
+      for (var node in newNodes) {
+        this.insertBefore(node, refChild);
+      }
+    }
+  }
+
+  void _clearChildren() {
+    while (firstChild != null) {
+      _removeChild(firstChild);
+    }
+  }
+
+  /**
+   * Print out a String representation of this Node.
+   */
+  String toString() {
+    String value = nodeValue; // Fetch DOM Node property once.
+    return value == null ? super.toString() : value;
+  }
+
+  /**
+   * A list of this node's children.
+   *
+   * ## Other resources
+   *
+   * * [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
+   *   from MDN.
+   */
+  @Returns('NodeList')
+  @Creates('NodeList')
+  final List<Node> childNodes;
+
+  // To suppress missing implicit constructor warnings.
+  factory Node._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int ATTRIBUTE_NODE = 2;
+
+  static const int CDATA_SECTION_NODE = 4;
+
+  static const int COMMENT_NODE = 8;
+
+  static const int DOCUMENT_FRAGMENT_NODE = 11;
+
+  static const int DOCUMENT_NODE = 9;
+
+  static const int DOCUMENT_TYPE_NODE = 10;
+
+  static const int ELEMENT_NODE = 1;
+
+  static const int ENTITY_NODE = 6;
+
+  static const int ENTITY_REFERENCE_NODE = 5;
+
+  static const int NOTATION_NODE = 12;
+
+  static const int PROCESSING_INSTRUCTION_NODE = 7;
+
+  static const int TEXT_NODE = 3;
+
+  @JSName('baseURI')
+  final String baseUri;
+
+  /**
+   * The first child of this node.
+   *
+   * ## Other resources
+   *
+   * * [Node.firstChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)
+   *   from MDN.
+   */
+  final Node firstChild;
+
+  final bool isConnected;
+
+  /**
+   * The last child of this node.
+   *
+   * ## Other resources
+   *
+   * * [Node.lastChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)
+   *   from MDN.
+   */
+  final Node lastChild;
+
+  @JSName('nextSibling')
+  /**
+   * The next sibling node.
+   *
+   * ## Other resources
+   *
+   * * [Node.nextSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling)
+   *   from MDN.
+   */
+  final Node nextNode;
+
+  /**
+   * The name of this node.
+   *
+   * This varies by this node's [nodeType].
+   *
+   * ## Other resources
+   *
+   * * [Node.nodeName](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeName)
+   *   from MDN. This page contains a table of [nodeName] values for each
+   *   [nodeType].
+   */
+  final String nodeName;
+
+  /**
+   * The type of node.
+   *
+   * This value is one of:
+   *
+   * * [ATTRIBUTE_NODE] if this node is an attribute.
+   * * [CDATA_SECTION_NODE] if this node is a [CDataSection].
+   * * [COMMENT_NODE] if this node is a [Comment].
+   * * [DOCUMENT_FRAGMENT_NODE] if this node is a [DocumentFragment].
+   * * [DOCUMENT_NODE] if this node is a [Document].
+   * * [DOCUMENT_TYPE_NODE] if this node is a [DocumentType] node.
+   * * [ELEMENT_NODE] if this node is an [Element].
+   * * [ENTITY_NODE] if this node is an entity.
+   * * [ENTITY_REFERENCE_NODE] if this node is an entity reference.
+   * * [NOTATION_NODE] if this node is a notation.
+   * * [PROCESSING_INSTRUCTION_NODE] if this node is a [ProcessingInstruction].
+   * * [TEXT_NODE] if this node is a [Text] node.
+   *
+   * ## Other resources
+   *
+   * * [Node.nodeType](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType)
+   *   from MDN.
+   */
+  final int nodeType;
+
+  /**
+   * The value of this node.
+   *
+   * This varies by this type's [nodeType].
+   *
+   * ## Other resources
+   *
+   * * [Node.nodeValue](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeValue)
+   *   from MDN. This page contains a table of [nodeValue] values for each
+   *   [nodeType].
+   */
+  final String nodeValue;
+
+  /**
+   * The document this node belongs to.
+   *
+   * Returns null if this node does not belong to any document.
+   *
+   * ## Other resources
+   *
+   * * [Node.ownerDocument](https://developer.mozilla.org/en-US/docs/Web/API/Node.ownerDocument)
+   *   from MDN.
+   */
+  final Document ownerDocument;
+
+  @JSName('parentElement')
+  /**
+   * The parent element of this node.
+   *
+   * Returns null if this node either does not have a parent or its parent is
+   * not an element.
+   *
+   * ## Other resources
+   *
+   * * [Node.parentElement](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentElement)
+   *   from W3C.
+   */
+  final Element parent;
+
+  /**
+   * The parent node of this node.
+   *
+   * ## Other resources
+   *
+   * * [Node.parentNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode)
+   *   from MDN.
+   */
+  final Node parentNode;
+
+  @JSName('previousSibling')
+  /**
+   * The previous sibling node.
+   *
+   * ## Other resources
+   *
+   * * [Node.previousSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.previousSibling)
+   *   from MDN.
+   */
+  final Node previousNode;
+
+  @JSName('textContent')
+  /**
+   * All text within this node and its descendents.
+   *
+   * ## Other resources
+   *
+   * * [Node.textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent)
+   *   from MDN.
+   */
+  String text;
+
+  @JSName('appendChild')
+  /**
+   * Adds a node to the end of the child [nodes] list of this node.
+   *
+   * If the node already exists in this document, it will be removed from its
+   * current parent node, then added to this node.
+   *
+   * This method is more efficient than `nodes.add`, and is the preferred
+   * way of appending a child node.
+   */
+  Node append(Node node) native;
+
+  @JSName('cloneNode')
+  /**
+   * Returns a copy of this node.
+   *
+   * If [deep] is `true`, then all of this node's children and descendents are
+   * copied as well. If [deep] is `false`, then only this node is copied.
+   *
+   * ## Other resources
+   *
+   * * [Node.cloneNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode)
+   *   from MDN.
+   */
+  Node clone(bool deep) native;
+
+  /**
+   * Returns true if this node contains the specified node.
+   *
+   * ## Other resources
+   *
+   * * [Node.contains](https://developer.mozilla.org/en-US/docs/Web/API/Node.contains)
+   *   from MDN.
+   */
+  bool contains(Node other) native;
+
+  Node getRootNode([Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return _getRootNode_1(options_1);
+    }
+    return _getRootNode_2();
+  }
+
+  @JSName('getRootNode')
+  Node _getRootNode_1(options) native;
+  @JSName('getRootNode')
+  Node _getRootNode_2() native;
+
+  /**
+   * Returns true if this node has any children.
+   *
+   * ## Other resources
+   *
+   * * [Node.hasChildNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.hasChildNodes)
+   *   from MDN.
+   */
+  bool hasChildNodes() native;
+
+  /**
+   * Inserts all of the nodes into this node directly before refChild.
+   *
+   * ## Other resources
+   *
+   * * [Node.insertBefore](https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore)
+   *   from MDN.
+   */
+  Node insertBefore(Node node, Node child) native;
+
+  @JSName('removeChild')
+  Node _removeChild(Node child) native;
+
+  @JSName('replaceChild')
+  Node _replaceChild(Node node, Node child) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("NodeFilter")
+class NodeFilter extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory NodeFilter._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int FILTER_ACCEPT = 1;
+
+  static const int FILTER_REJECT = 2;
+
+  static const int FILTER_SKIP = 3;
+
+  static const int SHOW_ALL = 0xFFFFFFFF;
+
+  static const int SHOW_COMMENT = 0x80;
+
+  static const int SHOW_DOCUMENT = 0x100;
+
+  static const int SHOW_DOCUMENT_FRAGMENT = 0x400;
+
+  static const int SHOW_DOCUMENT_TYPE = 0x200;
+
+  static const int SHOW_ELEMENT = 0x1;
+
+  static const int SHOW_PROCESSING_INSTRUCTION = 0x40;
+
+  static const int SHOW_TEXT = 0x4;
+}
+// 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.
+
+@Unstable()
+@Native("NodeIterator")
+class NodeIterator extends Interceptor {
+  factory NodeIterator(Node root, int whatToShow) {
+    return document._createNodeIterator(root, whatToShow, null);
+  }
+  // To suppress missing implicit constructor warnings.
+  factory NodeIterator._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool pointerBeforeReferenceNode;
+
+  final Node referenceNode;
+
+  final Node root;
+
+  final int whatToShow;
+
+  void detach() native;
+
+  Node nextNode() native;
+
+  Node previousNode() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("NodeList,RadioNodeList")
+class NodeList extends Interceptor
+    with ListMixin<Node>, ImmutableListMixin<Node>
+    implements JavaScriptIndexingBehavior<Node>, List<Node> {
+  // To suppress missing implicit constructor warnings.
+  factory NodeList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  Node operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return JS("Node", "#[#]", this, index);
+  }
+
+  void operator []=(int index, Node value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<Node> mixins.
+  // Node is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  Node get first {
+    if (this.length > 0) {
+      return JS('Node', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  Node get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('Node', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  Node get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('Node', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  Node elementAt(int index) => this[index];
+  // -- end List<Node> mixins.
+
+  @JSName('item')
+  Node _item(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("NonDocumentTypeChildNode")
+class NonDocumentTypeChildNode extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory NonDocumentTypeChildNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final Element nextElementSibling;
+
+  final Element previousElementSibling;
+}
+// Copyright (c) 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.
+
+@Native("NonElementParentNode")
+class NonElementParentNode extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory NonElementParentNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Element getElementById(String elementId) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("NoncedElement")
+class NoncedElement extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory NoncedElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  String nonce;
+}
+// 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.
+
+@Native("Notification")
+class Notification extends EventTarget {
+  factory Notification(String title,
+      {String dir: null,
+      String body: null,
+      String lang: null,
+      String tag: null,
+      String icon: null}) {
+    var parsedOptions = {};
+    if (dir != null) parsedOptions['dir'] = dir;
+    if (body != null) parsedOptions['body'] = body;
+    if (lang != null) parsedOptions['lang'] = lang;
+    if (tag != null) parsedOptions['tag'] = tag;
+    if (icon != null) parsedOptions['icon'] = icon;
+    return Notification._factoryNotification(title, parsedOptions);
+  }
+  // To suppress missing implicit constructor warnings.
+  factory Notification._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `click` events to event
+   * handlers that are not necessarily instances of [Notification].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> clickEvent =
+      const EventStreamProvider<Event>('click');
+
+  /**
+   * Static factory designed to expose `close` events to event
+   * handlers that are not necessarily instances of [Notification].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> closeEvent =
+      const EventStreamProvider<Event>('close');
+
+  /**
+   * Static factory designed to expose `error` events to event
+   * handlers that are not necessarily instances of [Notification].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  /**
+   * Static factory designed to expose `show` events to event
+   * handlers that are not necessarily instances of [Notification].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> showEvent =
+      const EventStreamProvider<Event>('show');
+
+  static Notification _factoryNotification(String title, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return Notification._create_1(title, options_1);
+    }
+    return Notification._create_2(title);
+  }
+
+  static Notification _create_1(title, options) =>
+      JS('Notification', 'new Notification(#,#)', title, options);
+  static Notification _create_2(title) =>
+      JS('Notification', 'new Notification(#)', title);
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(window.Notification)');
+
+  final List actions;
+
+  final String badge;
+
+  final String body;
+
+  @annotation_Creates_SerializedScriptValue
+  @annotation_Returns_SerializedScriptValue
+  final Object data;
+
+  final String dir;
+
+  final String icon;
+
+  final String image;
+
+  final String lang;
+
+  static final int maxActions;
+
+  static final String permission;
+
+  final bool renotify;
+
+  final bool requireInteraction;
+
+  final bool silent;
+
+  final String tag;
+
+  final int timestamp;
+
+  final String title;
+
+  final List<int> vibrate;
+
+  void close() native;
+
+  @JSName('requestPermission')
+  static Future _requestPermission(
+      [_NotificationPermissionCallback deprecatedCallback]) native;
+
+  @JSName('requestPermission')
+  static Future<String> requestPermission() {
+    var completer = new Completer<String>();
+    _requestPermission((value) {
+      completer.complete(value);
+    });
+    return completer.future;
+  }
+
+  /// Stream of `click` events handled by this [Notification].
+  Stream<Event> get onClick => clickEvent.forTarget(this);
+
+  /// Stream of `close` events handled by this [Notification].
+  Stream<Event> get onClose => closeEvent.forTarget(this);
+
+  /// Stream of `error` events handled by this [Notification].
+  Stream<Event> get onError => errorEvent.forTarget(this);
+
+  /// Stream of `show` events handled by this [Notification].
+  Stream<Event> get onShow => showEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("NotificationEvent")
+class NotificationEvent extends ExtendableEvent {
+  // To suppress missing implicit constructor warnings.
+  factory NotificationEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory NotificationEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return NotificationEvent._create_1(type, eventInitDict_1);
+  }
+  static NotificationEvent _create_1(type, eventInitDict) => JS(
+      'NotificationEvent', 'new NotificationEvent(#,#)', type, eventInitDict);
+
+  final String action;
+
+  final Notification notification;
+
+  final String reply;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void _NotificationPermissionCallback(String permission);
+// Copyright (c) 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.
+
+@Native("HTMLOListElement")
+class OListElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory OListElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory OListElement() => JS(
+      'returns:OListElement;creates:OListElement;new:true',
+      '#.createElement(#)',
+      document,
+      "ol");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  OListElement.created() : super.created();
+
+  bool reversed;
+
+  int start;
+
+  String type;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.IE)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("HTMLObjectElement")
+class ObjectElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory ObjectElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ObjectElement() => document.createElement("object");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ObjectElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => Element.isTagSupported('object');
+
+  WindowBase get contentWindow =>
+      _convertNativeToDart_Window(this._get_contentWindow);
+  @JSName('contentWindow')
+  @Creates('Window|=Object')
+  @Returns('Window|=Object')
+  final dynamic _get_contentWindow;
+
+  String data;
+
+  final FormElement form;
+
+  String height;
+
+  String name;
+
+  String type;
+
+  String useMap;
+
+  final String validationMessage;
+
+  final ValidityState validity;
+
+  String width;
+
+  final bool willValidate;
+
+  Node __getter__(String name) native;
+
+  void __setter__(String name, Node value) native;
+
+  bool checkValidity() native;
+
+  bool reportValidity() native;
+
+  void setCustomValidity(String error) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("OffscreenCanvas")
+class OffscreenCanvas extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory OffscreenCanvas._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory OffscreenCanvas(int width, int height) {
+    return OffscreenCanvas._create_1(width, height);
+  }
+  static OffscreenCanvas _create_1(width, height) =>
+      JS('OffscreenCanvas', 'new OffscreenCanvas(#,#)', width, height);
+
+  int height;
+
+  int width;
+
+  Future<Blob> convertToBlob([Map options]) {
+    var options_dict = null;
+    if (options != null) {
+      options_dict = convertDartToNative_Dictionary(options);
+    }
+    return promiseToFuture<Blob>(
+        JS("", "#.convertToBlob(#)", this, options_dict));
+  }
+
+  Object getContext(String contextType, [Map attributes]) {
+    if (attributes != null) {
+      var attributes_1 = convertDartToNative_Dictionary(attributes);
+      return _getContext_1(contextType, attributes_1);
+    }
+    return _getContext_2(contextType);
+  }
+
+  @JSName('getContext')
+  Object _getContext_1(contextType, attributes) native;
+  @JSName('getContext')
+  Object _getContext_2(contextType) native;
+
+  ImageBitmap transferToImageBitmap() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("OffscreenCanvasRenderingContext2D")
+class OffscreenCanvasRenderingContext2D extends Interceptor
+    implements _CanvasPath {
+  // To suppress missing implicit constructor warnings.
+  factory OffscreenCanvasRenderingContext2D._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final OffscreenCanvas canvas;
+
+  String direction;
+
+  Object fillStyle;
+
+  String filter;
+
+  String font;
+
+  num globalAlpha;
+
+  String globalCompositeOperation;
+
+  bool imageSmoothingEnabled;
+
+  String imageSmoothingQuality;
+
+  String lineCap;
+
+  num lineDashOffset;
+
+  String lineJoin;
+
+  num lineWidth;
+
+  num miterLimit;
+
+  num shadowBlur;
+
+  String shadowColor;
+
+  num shadowOffsetX;
+
+  num shadowOffsetY;
+
+  Object strokeStyle;
+
+  String textAlign;
+
+  String textBaseline;
+
+  void beginPath() native;
+
+  void clearRect(num x, num y, num width, num height) native;
+
+  void clip([Path2D path]) native;
+
+  Future commit() => promiseToFuture(JS("", "#.commit()", this));
+
+  ImageData createImageData(data_OR_imagedata_OR_sw,
+      [int sh_OR_sw,
+      imageDataColorSettings_OR_sh,
+      Map imageDataColorSettings]) {
+    if ((data_OR_imagedata_OR_sw is ImageData) &&
+        sh_OR_sw == null &&
+        imageDataColorSettings_OR_sh == null &&
+        imageDataColorSettings == null) {
+      var imagedata_1 = convertDartToNative_ImageData(data_OR_imagedata_OR_sw);
+      return convertNativeToDart_ImageData(_createImageData_1(imagedata_1));
+    }
+    if (sh_OR_sw != null &&
+        (data_OR_imagedata_OR_sw is int) &&
+        imageDataColorSettings_OR_sh == null &&
+        imageDataColorSettings == null) {
+      return convertNativeToDart_ImageData(
+          _createImageData_2(data_OR_imagedata_OR_sw, sh_OR_sw));
+    }
+    if ((imageDataColorSettings_OR_sh is Map) &&
+        sh_OR_sw != null &&
+        (data_OR_imagedata_OR_sw is int) &&
+        imageDataColorSettings == null) {
+      var imageDataColorSettings_1 =
+          convertDartToNative_Dictionary(imageDataColorSettings_OR_sh);
+      return convertNativeToDart_ImageData(_createImageData_3(
+          data_OR_imagedata_OR_sw, sh_OR_sw, imageDataColorSettings_1));
+    }
+    if (imageDataColorSettings != null &&
+        (imageDataColorSettings_OR_sh is int) &&
+        sh_OR_sw != null &&
+        data_OR_imagedata_OR_sw != null) {
+      var imageDataColorSettings_1 =
+          convertDartToNative_Dictionary(imageDataColorSettings);
+      return convertNativeToDart_ImageData(_createImageData_4(
+          data_OR_imagedata_OR_sw,
+          sh_OR_sw,
+          imageDataColorSettings_OR_sh,
+          imageDataColorSettings_1));
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('createImageData')
+  _createImageData_1(imagedata) native;
+  @JSName('createImageData')
+  _createImageData_2(int sw, sh) native;
+  @JSName('createImageData')
+  _createImageData_3(int sw, sh, imageDataColorSettings) native;
+  @JSName('createImageData')
+  _createImageData_4(data, sw, int sh, imageDataColorSettings) native;
+
+  CanvasGradient createLinearGradient(num x0, num y0, num x1, num y1) native;
+
+  CanvasPattern createPattern(
+      /*CanvasImageSource*/ image, String repetitionType) native;
+
+  CanvasGradient createRadialGradient(
+      num x0, num y0, num r0, num x1, num y1, num r1) native;
+
+  void drawImage(/*CanvasImageSource*/ image, num sx_OR_x, num sy_OR_y,
+      [num sw_OR_width,
+      num height_OR_sh,
+      num dx,
+      num dy,
+      num dw,
+      num dh]) native;
+
+  void fill([path_OR_winding, String winding]) native;
+
+  void fillRect(num x, num y, num width, num height) native;
+
+  void fillText(String text, num x, num y, [num maxWidth]) native;
+
+  ImageData getImageData(int sx, int sy, int sw, int sh) {
+    return convertNativeToDart_ImageData(_getImageData_1(sx, sy, sw, sh));
+  }
+
+  @JSName('getImageData')
+  _getImageData_1(sx, sy, sw, sh) native;
+
+  List<num> getLineDash() native;
+
+  bool isPointInPath(path_OR_x, num x_OR_y, [winding_OR_y, String winding])
+      native;
+
+  bool isPointInStroke(path_OR_x, num x_OR_y, [num y]) native;
+
+  TextMetrics measureText(String text) native;
+
+  void putImageData(ImageData imagedata, int dx, int dy,
+      [int dirtyX, int dirtyY, int dirtyWidth, int dirtyHeight]) {
+    if (dirtyX == null &&
+        dirtyY == null &&
+        dirtyWidth == null &&
+        dirtyHeight == null) {
+      var imagedata_1 = convertDartToNative_ImageData(imagedata);
+      _putImageData_1(imagedata_1, dx, dy);
+      return;
+    }
+    if (dirtyHeight != null &&
+        dirtyWidth != null &&
+        dirtyY != null &&
+        dirtyX != null) {
+      var imagedata_1 = convertDartToNative_ImageData(imagedata);
+      _putImageData_2(
+          imagedata_1, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
+      return;
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('putImageData')
+  void _putImageData_1(imagedata, dx, dy) native;
+  @JSName('putImageData')
+  void _putImageData_2(
+      imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) native;
+
+  void resetTransform() native;
+
+  void restore() native;
+
+  void rotate(num angle) native;
+
+  void save() native;
+
+  void scale(num x, num y) native;
+
+  void setLineDash(List<num> dash) native;
+
+  void setTransform(num a, num b, num c, num d, num e, num f) native;
+
+  void stroke([Path2D path]) native;
+
+  void strokeRect(num x, num y, num width, num height) native;
+
+  void strokeText(String text, num x, num y, [num maxWidth]) native;
+
+  void transform(num a, num b, num c, num d, num e, num f) native;
+
+  void translate(num x, num y) native;
+
+  // From CanvasPath
+
+  void arc(num x, num y, num radius, num startAngle, num endAngle,
+      bool anticlockwise) native;
+
+  void arcTo(num x1, num y1, num x2, num y2, num radius) native;
+
+  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y)
+      native;
+
+  void closePath() native;
+
+  void ellipse(num x, num y, num radiusX, num radiusY, num rotation,
+      num startAngle, num endAngle, bool anticlockwise) native;
+
+  void lineTo(num x, num y) native;
+
+  void moveTo(num x, num y) native;
+
+  void quadraticCurveTo(num cpx, num cpy, num x, num y) native;
+
+  void rect(num x, num y, num width, num height) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("HTMLOptGroupElement")
+class OptGroupElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory OptGroupElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory OptGroupElement() => JS(
+      'returns:OptGroupElement;creates:OptGroupElement;new:true',
+      '#.createElement(#)',
+      document,
+      "optgroup");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  OptGroupElement.created() : super.created();
+
+  bool disabled;
+
+  String label;
+}
+// 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.
+
+@Native("HTMLOptionElement")
+class OptionElement extends HtmlElement {
+  factory OptionElement(
+      {String data: '', String value: '', bool selected: false}) {
+    return new OptionElement._(data, value, null, selected);
+  }
+
+  factory OptionElement._(
+      [String data, String value, bool defaultSelected, bool selected]) {
+    if (selected != null) {
+      return OptionElement._create_1(data, value, defaultSelected, selected);
+    }
+    if (defaultSelected != null) {
+      return OptionElement._create_2(data, value, defaultSelected);
+    }
+    if (value != null) {
+      return OptionElement._create_3(data, value);
+    }
+    if (data != null) {
+      return OptionElement._create_4(data);
+    }
+    return OptionElement._create_5();
+  }
+  static OptionElement _create_1(data, value, defaultSelected, selected) => JS(
+      'OptionElement',
+      'new Option(#,#,#,#)',
+      data,
+      value,
+      defaultSelected,
+      selected);
+  static OptionElement _create_2(data, value, defaultSelected) =>
+      JS('OptionElement', 'new Option(#,#,#)', data, value, defaultSelected);
+  static OptionElement _create_3(data, value) =>
+      JS('OptionElement', 'new Option(#,#)', data, value);
+  static OptionElement _create_4(data) =>
+      JS('OptionElement', 'new Option(#)', data);
+  static OptionElement _create_5() => JS('OptionElement', 'new Option()');
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  OptionElement.created() : super.created();
+
+  bool defaultSelected;
+
+  bool disabled;
+
+  final FormElement form;
+
+  final int index;
+
+  String label;
+
+  bool selected;
+
+  String value;
+}
+// Copyright (c) 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.
+
+@Native("OrientationSensor")
+class OrientationSensor extends Sensor {
+  // To suppress missing implicit constructor warnings.
+  factory OrientationSensor._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final List<num> quaternion;
+
+  void populateMatrix(Object targetBuffer) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Native("HTMLOutputElement")
+class OutputElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory OutputElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory OutputElement() => document.createElement("output");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  OutputElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => Element.isTagSupported('output');
+
+  String defaultValue;
+
+  final FormElement form;
+
+  final DomTokenList htmlFor;
+
+  @Unstable()
+  @Returns('NodeList|Null')
+  @Creates('NodeList')
+  final List<Node> labels;
+
+  String name;
+
+  final String type;
+
+  final String validationMessage;
+
+  final ValidityState validity;
+
+  String value;
+
+  final bool willValidate;
+
+  bool checkValidity() native;
+
+  bool reportValidity() native;
+
+  void setCustomValidity(String error) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("OverconstrainedError")
+class OverconstrainedError extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory OverconstrainedError._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory OverconstrainedError(String constraint, String message) {
+    return OverconstrainedError._create_1(constraint, message);
+  }
+  static OverconstrainedError _create_1(constraint, message) => JS(
+      'OverconstrainedError',
+      'new OverconstrainedError(#,#)',
+      constraint,
+      message);
+
+  final String constraint;
+
+  final String message;
+
+  final String name;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("PageTransitionEvent")
+class PageTransitionEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory PageTransitionEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PageTransitionEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return PageTransitionEvent._create_1(type, eventInitDict_1);
+    }
+    return PageTransitionEvent._create_2(type);
+  }
+  static PageTransitionEvent _create_1(type, eventInitDict) => JS(
+      'PageTransitionEvent',
+      'new PageTransitionEvent(#,#)',
+      type,
+      eventInitDict);
+  static PageTransitionEvent _create_2(type) =>
+      JS('PageTransitionEvent', 'new PageTransitionEvent(#)', type);
+
+  final bool persisted;
+}
+// Copyright (c) 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.
+
+@Native("PaintRenderingContext2D")
+class PaintRenderingContext2D extends Interceptor implements _CanvasPath {
+  // To suppress missing implicit constructor warnings.
+  factory PaintRenderingContext2D._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Matrix currentTransform;
+
+  Object fillStyle;
+
+  String filter;
+
+  num globalAlpha;
+
+  String globalCompositeOperation;
+
+  bool imageSmoothingEnabled;
+
+  String imageSmoothingQuality;
+
+  String lineCap;
+
+  num lineDashOffset;
+
+  String lineJoin;
+
+  num lineWidth;
+
+  num miterLimit;
+
+  num shadowBlur;
+
+  String shadowColor;
+
+  num shadowOffsetX;
+
+  num shadowOffsetY;
+
+  Object strokeStyle;
+
+  void beginPath() native;
+
+  void clearRect(num x, num y, num width, num height) native;
+
+  void clip([path_OR_winding, String winding]) native;
+
+  CanvasGradient createLinearGradient(num x0, num y0, num x1, num y1) native;
+
+  CanvasPattern createPattern(
+      /*CanvasImageSource*/ image, String repetitionType) native;
+
+  CanvasGradient createRadialGradient(
+      num x0, num y0, num r0, num x1, num y1, num r1) native;
+
+  void drawImage(/*CanvasImageSource*/ image, num sx_OR_x, num sy_OR_y,
+      [num sw_OR_width,
+      num height_OR_sh,
+      num dx,
+      num dy,
+      num dw,
+      num dh]) native;
+
+  void fill([path_OR_winding, String winding]) native;
+
+  void fillRect(num x, num y, num width, num height) native;
+
+  List<num> getLineDash() native;
+
+  bool isPointInPath(path_OR_x, num x_OR_y, [winding_OR_y, String winding])
+      native;
+
+  bool isPointInStroke(path_OR_x, num x_OR_y, [num y]) native;
+
+  void resetTransform() native;
+
+  void restore() native;
+
+  void rotate(num angle) native;
+
+  void save() native;
+
+  void scale(num x, num y) native;
+
+  void setLineDash(List<num> dash) native;
+
+  void setTransform(num a, num b, num c, num d, num e, num f) native;
+
+  void stroke([Path2D path]) native;
+
+  void strokeRect(num x, num y, num width, num height) native;
+
+  void transform(num a, num b, num c, num d, num e, num f) native;
+
+  void translate(num x, num y) native;
+
+  // From CanvasPath
+
+  void arc(num x, num y, num radius, num startAngle, num endAngle,
+      bool anticlockwise) native;
+
+  void arcTo(num x1, num y1, num x2, num y2, num radius) native;
+
+  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y)
+      native;
+
+  void closePath() native;
+
+  void ellipse(num x, num y, num radiusX, num radiusY, num rotation,
+      num startAngle, num endAngle, bool anticlockwise) native;
+
+  void lineTo(num x, num y) native;
+
+  void moveTo(num x, num y) native;
+
+  void quadraticCurveTo(num cpx, num cpy, num x, num y) native;
+
+  void rect(num x, num y, num width, num height) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("PaintSize")
+class PaintSize extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PaintSize._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num height;
+
+  final num width;
+}
+// Copyright (c) 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.
+
+@Native("PaintWorkletGlobalScope")
+class PaintWorkletGlobalScope extends WorkletGlobalScope {
+  // To suppress missing implicit constructor warnings.
+  factory PaintWorkletGlobalScope._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num devicePixelRatio;
+
+  void registerPaint(String name, Object paintCtor) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("HTMLParagraphElement")
+class ParagraphElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory ParagraphElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ParagraphElement() => JS(
+      'returns:ParagraphElement;creates:ParagraphElement;new:true',
+      '#.createElement(#)',
+      document,
+      "p");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ParagraphElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("HTMLParamElement")
+class ParamElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory ParamElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ParamElement() => JS(
+      'returns:ParamElement;creates:ParamElement;new:true',
+      '#.createElement(#)',
+      document,
+      "param");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ParamElement.created() : super.created();
+
+  String name;
+
+  String value;
+}
+// Copyright (c) 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.
+
+abstract class ParentNode extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ParentNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int _childElementCount;
+
+  final List<Node> _children;
+
+  final Element _firstElementChild;
+
+  final Element _lastElementChild;
+
+  Element querySelector(String selectors);
+
+  List<Node> _querySelectorAll(String selectors);
+}
+// Copyright (c) 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.
+
+@Native("PasswordCredential")
+class PasswordCredential extends Credential implements CredentialUserData {
+  // To suppress missing implicit constructor warnings.
+  factory PasswordCredential._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PasswordCredential(data_OR_form) {
+    if ((data_OR_form is Map)) {
+      var data_1 = convertDartToNative_Dictionary(data_OR_form);
+      return PasswordCredential._create_1(data_1);
+    }
+    if ((data_OR_form is FormElement)) {
+      return PasswordCredential._create_2(data_OR_form);
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+  static PasswordCredential _create_1(data_OR_form) =>
+      JS('PasswordCredential', 'new PasswordCredential(#)', data_OR_form);
+  static PasswordCredential _create_2(data_OR_form) =>
+      JS('PasswordCredential', 'new PasswordCredential(#)', data_OR_form);
+
+  Object additionalData;
+
+  String idName;
+
+  final String password;
+
+  String passwordName;
+
+  // From CredentialUserData
+
+  @JSName('iconURL')
+  final String iconUrl;
+
+  final String name;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("Path2D")
+class Path2D extends Interceptor implements _CanvasPath {
+  // To suppress missing implicit constructor warnings.
+  factory Path2D._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory Path2D([path_OR_text]) {
+    if (path_OR_text == null) {
+      return Path2D._create_1();
+    }
+    if ((path_OR_text is Path2D)) {
+      return Path2D._create_2(path_OR_text);
+    }
+    if ((path_OR_text is String)) {
+      return Path2D._create_3(path_OR_text);
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+  static Path2D _create_1() => JS('Path2D', 'new Path2D()');
+  static Path2D _create_2(path_OR_text) =>
+      JS('Path2D', 'new Path2D(#)', path_OR_text);
+  static Path2D _create_3(path_OR_text) =>
+      JS('Path2D', 'new Path2D(#)', path_OR_text);
+
+  void addPath(Path2D path, [Matrix transform]) native;
+
+  // From CanvasPath
+
+  void arc(num x, num y, num radius, num startAngle, num endAngle,
+      bool anticlockwise) native;
+
+  void arcTo(num x1, num y1, num x2, num y2, num radius) native;
+
+  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y)
+      native;
+
+  void closePath() native;
+
+  void ellipse(num x, num y, num radiusX, num radiusY, num rotation,
+      num startAngle, num endAngle, bool anticlockwise) native;
+
+  void lineTo(num x, num y) native;
+
+  void moveTo(num x, num y) native;
+
+  void quadraticCurveTo(num cpx, num cpy, num x, num y) native;
+
+  void rect(num x, num y, num width, num height) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("PaymentAddress")
+class PaymentAddress extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PaymentAddress._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final List<String> addressLine;
+
+  final String city;
+
+  final String country;
+
+  final String dependentLocality;
+
+  final String languageCode;
+
+  final String organization;
+
+  final String phone;
+
+  final String postalCode;
+
+  final String recipient;
+
+  final String region;
+
+  final String sortingCode;
+}
+// Copyright (c) 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.
+
+@Native("PaymentInstruments")
+class PaymentInstruments extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PaymentInstruments._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Future clear() => promiseToFuture(JS("", "#.clear()", this));
+
+  Future<bool> delete(String instrumentKey) =>
+      promiseToFuture<bool>(JS("", "#.delete(#)", this, instrumentKey));
+
+  Future<Map<String, dynamic>> get(String instrumentKey) =>
+      promiseToFutureAsMap(JS("", "#.get(#)", this, instrumentKey));
+
+  Future has(String instrumentKey) =>
+      promiseToFuture(JS("", "#.has(#)", this, instrumentKey));
+
+  Future<List<String>> keys() =>
+      promiseToFuture<List<String>>(JS("", "#.keys()", this));
+
+  Future set(String instrumentKey, Map details) {
+    var details_dict = convertDartToNative_Dictionary(details);
+    return promiseToFuture(
+        JS("", "#.set(#, #)", this, instrumentKey, details_dict));
+  }
+}
+// Copyright (c) 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.
+
+@Native("PaymentManager")
+class PaymentManager extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PaymentManager._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final PaymentInstruments instruments;
+
+  String userHint;
+}
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("PaymentRequest")
+class PaymentRequest extends EventTarget {
+  factory PaymentRequest(List<Map> methodData, Map details, [Map options]) {
+    var methodData_1 = [];
+    for (var i in methodData) {
+      methodData_1.add(convertDartToNative_Dictionary(i));
+    }
+    if (options != null) {
+      var details_1 = convertDartToNative_Dictionary(details);
+      var options_2 = convertDartToNative_Dictionary(options);
+      return PaymentRequest._create_1(methodData_1, details_1, options_2);
+    }
+    var details_1 = convertDartToNative_Dictionary(details);
+    return PaymentRequest._create_2(methodData_1, details_1);
+  }
+
+  static PaymentRequest _create_1(methodData, details, options) => JS(
+      'PaymentRequest',
+      'new PaymentRequest(#,#,#)',
+      methodData,
+      details,
+      options);
+  static PaymentRequest _create_2(methodData, details) =>
+      JS('PaymentRequest', 'new PaymentRequest(#,#)', methodData, details);
+
+  // To suppress missing implicit constructor warnings.
+  factory PaymentRequest._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String id;
+
+  final PaymentAddress shippingAddress;
+
+  final String shippingOption;
+
+  final String shippingType;
+
+  Future abort() => promiseToFuture(JS("", "#.abort()", this));
+
+  Future<bool> canMakePayment() =>
+      promiseToFuture<bool>(JS("", "#.canMakePayment()", this));
+
+  Future<PaymentResponse> show() =>
+      promiseToFuture<PaymentResponse>(JS("", "#.show()", this));
+}
+
+// Copyright (c) 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.
+
+@Native("PaymentRequestEvent")
+class PaymentRequestEvent extends ExtendableEvent {
+  // To suppress missing implicit constructor warnings.
+  factory PaymentRequestEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PaymentRequestEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return PaymentRequestEvent._create_1(type, eventInitDict_1);
+  }
+  static PaymentRequestEvent _create_1(type, eventInitDict) => JS(
+      'PaymentRequestEvent',
+      'new PaymentRequestEvent(#,#)',
+      type,
+      eventInitDict);
+
+  final String instrumentKey;
+
+  final List methodData;
+
+  final List modifiers;
+
+  final String paymentRequestId;
+
+  final String paymentRequestOrigin;
+
+  final String topLevelOrigin;
+
+  final Object total;
+
+  Future<WindowClient> openWindow(String url) =>
+      promiseToFuture<WindowClient>(JS("", "#.openWindow(#)", this, url));
+
+  void respondWith(Future response) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("PaymentRequestUpdateEvent")
+class PaymentRequestUpdateEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory PaymentRequestUpdateEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PaymentRequestUpdateEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return PaymentRequestUpdateEvent._create_1(type, eventInitDict_1);
+    }
+    return PaymentRequestUpdateEvent._create_2(type);
+  }
+  static PaymentRequestUpdateEvent _create_1(type, eventInitDict) => JS(
+      'PaymentRequestUpdateEvent',
+      'new PaymentRequestUpdateEvent(#,#)',
+      type,
+      eventInitDict);
+  static PaymentRequestUpdateEvent _create_2(type) =>
+      JS('PaymentRequestUpdateEvent', 'new PaymentRequestUpdateEvent(#)', type);
+
+  void updateWith(Future detailsPromise) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("PaymentResponse")
+class PaymentResponse extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PaymentResponse._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final Object details;
+
+  final String methodName;
+
+  final String payerEmail;
+
+  final String payerName;
+
+  final String payerPhone;
+
+  final String requestId;
+
+  final PaymentAddress shippingAddress;
+
+  final String shippingOption;
+
+  Future complete([String paymentResult]) =>
+      promiseToFuture(JS("", "#.complete(#)", this, paymentResult));
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE)
+@Native("Performance")
+class Performance extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory Performance._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(window.performance)');
+
+  final MemoryInfo memory;
+
+  final PerformanceNavigation navigation;
+
+  final num timeOrigin;
+
+  final PerformanceTiming timing;
+
+  void clearMarks(String markName) native;
+
+  void clearMeasures(String measureName) native;
+
+  void clearResourceTimings() native;
+
+  List<PerformanceEntry> getEntries() native;
+
+  List<PerformanceEntry> getEntriesByName(String name, String entryType) native;
+
+  List<PerformanceEntry> getEntriesByType(String entryType) native;
+
+  void mark(String markName) native;
+
+  void measure(String measureName, String startMark, String endMark) native;
+
+  double now() native;
+
+  void setResourceTimingBufferSize(int maxSize) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("PerformanceEntry")
+class PerformanceEntry extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PerformanceEntry._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num duration;
+
+  final String entryType;
+
+  final String name;
+
+  final num startTime;
+}
+// Copyright (c) 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.
+
+@Native("PerformanceLongTaskTiming")
+class PerformanceLongTaskTiming extends PerformanceEntry {
+  // To suppress missing implicit constructor warnings.
+  factory PerformanceLongTaskTiming._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final List<TaskAttributionTiming> attribution;
+}
+// Copyright (c) 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.
+
+@Native("PerformanceMark")
+class PerformanceMark extends PerformanceEntry {
+  // To suppress missing implicit constructor warnings.
+  factory PerformanceMark._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("PerformanceMeasure")
+class PerformanceMeasure extends PerformanceEntry {
+  // To suppress missing implicit constructor warnings.
+  factory PerformanceMeasure._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("PerformanceNavigation")
+class PerformanceNavigation extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PerformanceNavigation._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int TYPE_BACK_FORWARD = 2;
+
+  static const int TYPE_NAVIGATE = 0;
+
+  static const int TYPE_RELOAD = 1;
+
+  static const int TYPE_RESERVED = 255;
+
+  final int redirectCount;
+
+  final int type;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("PerformanceNavigationTiming")
+class PerformanceNavigationTiming extends PerformanceResourceTiming {
+  // To suppress missing implicit constructor warnings.
+  factory PerformanceNavigationTiming._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num domComplete;
+
+  final num domContentLoadedEventEnd;
+
+  final num domContentLoadedEventStart;
+
+  final num domInteractive;
+
+  final num loadEventEnd;
+
+  final num loadEventStart;
+
+  final int redirectCount;
+
+  final String type;
+
+  final num unloadEventEnd;
+
+  final num unloadEventStart;
+}
+// Copyright (c) 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.
+
+@Native("PerformanceObserver")
+class PerformanceObserver extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PerformanceObserver._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PerformanceObserver(PerformanceObserverCallback callback) {
+    var callback_1 = convertDartClosureToJS(callback, 2);
+    return PerformanceObserver._create_1(callback_1);
+  }
+  static PerformanceObserver _create_1(callback) =>
+      JS('PerformanceObserver', 'new PerformanceObserver(#)', callback);
+
+  void disconnect() native;
+
+  void observe(Map options) {
+    var options_1 = convertDartToNative_Dictionary(options);
+    _observe_1(options_1);
+    return;
+  }
+
+  @JSName('observe')
+  void _observe_1(options) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void PerformanceObserverCallback(
+    PerformanceObserverEntryList entries, PerformanceObserver observer);
+// Copyright (c) 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.
+
+@Native("PerformanceObserverEntryList")
+class PerformanceObserverEntryList extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PerformanceObserverEntryList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  List<PerformanceEntry> getEntries() native;
+
+  List<PerformanceEntry> getEntriesByName(String name, String entryType) native;
+
+  List<PerformanceEntry> getEntriesByType(String entryType) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("PerformancePaintTiming")
+class PerformancePaintTiming extends PerformanceEntry {
+  // To suppress missing implicit constructor warnings.
+  factory PerformancePaintTiming._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("PerformanceResourceTiming")
+class PerformanceResourceTiming extends PerformanceEntry {
+  // To suppress missing implicit constructor warnings.
+  factory PerformanceResourceTiming._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num connectEnd;
+
+  final num connectStart;
+
+  final int decodedBodySize;
+
+  final num domainLookupEnd;
+
+  final num domainLookupStart;
+
+  final int encodedBodySize;
+
+  final num fetchStart;
+
+  final String initiatorType;
+
+  final String nextHopProtocol;
+
+  final num redirectEnd;
+
+  final num redirectStart;
+
+  final num requestStart;
+
+  final num responseEnd;
+
+  final num responseStart;
+
+  final num secureConnectionStart;
+
+  final List<PerformanceServerTiming> serverTiming;
+
+  final int transferSize;
+
+  final num workerStart;
+}
+// Copyright (c) 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.
+
+@Native("PerformanceServerTiming")
+class PerformanceServerTiming extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PerformanceServerTiming._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String description;
+
+  final num duration;
+
+  final String name;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("PerformanceTiming")
+class PerformanceTiming extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PerformanceTiming._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int connectEnd;
+
+  final int connectStart;
+
+  final int domComplete;
+
+  final int domContentLoadedEventEnd;
+
+  final int domContentLoadedEventStart;
+
+  final int domInteractive;
+
+  final int domLoading;
+
+  final int domainLookupEnd;
+
+  final int domainLookupStart;
+
+  final int fetchStart;
+
+  final int loadEventEnd;
+
+  final int loadEventStart;
+
+  final int navigationStart;
+
+  final int redirectEnd;
+
+  final int redirectStart;
+
+  final int requestStart;
+
+  final int responseEnd;
+
+  final int responseStart;
+
+  final int secureConnectionStart;
+
+  final int unloadEventEnd;
+
+  final int unloadEventStart;
+}
+// Copyright (c) 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.
+
+@Native("PermissionStatus")
+class PermissionStatus extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory PermissionStatus._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> changeEvent =
+      const EventStreamProvider<Event>('change');
+
+  final String state;
+
+  Stream<Event> get onChange => changeEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("Permissions")
+class Permissions extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Permissions._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Future<PermissionStatus> query(Map permission) {
+    var permission_dict = convertDartToNative_Dictionary(permission);
+    return promiseToFuture<PermissionStatus>(
+        JS("", "#.query(#)", this, permission_dict));
+  }
+
+  Future<PermissionStatus> request(Map permissions) {
+    var permissions_dict = convertDartToNative_Dictionary(permissions);
+    return promiseToFuture<PermissionStatus>(
+        JS("", "#.request(#)", this, permissions_dict));
+  }
+
+  Future<PermissionStatus> requestAll(List<Map> permissions) =>
+      promiseToFuture<PermissionStatus>(
+          JS("", "#.requestAll(#)", this, permissions));
+
+  Future<PermissionStatus> revoke(Map permission) {
+    var permission_dict = convertDartToNative_Dictionary(permission);
+    return promiseToFuture<PermissionStatus>(
+        JS("", "#.revoke(#)", this, permission_dict));
+  }
+}
+// Copyright (c) 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.
+
+@Native("PhotoCapabilities")
+class PhotoCapabilities extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PhotoCapabilities._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final List fillLightMode;
+
+  final MediaSettingsRange imageHeight;
+
+  final MediaSettingsRange imageWidth;
+
+  final String redEyeReduction;
+}
+// Copyright (c) 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.
+
+@Native("HTMLPictureElement")
+class PictureElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory PictureElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  PictureElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Native("Plugin")
+class Plugin extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Plugin._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String description;
+
+  final String filename;
+
+  final int length;
+
+  final String name;
+
+  MimeType item(int index) native;
+
+  MimeType namedItem(String name) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("PluginArray")
+class PluginArray extends Interceptor
+    with ListMixin<Plugin>, ImmutableListMixin<Plugin>
+    implements JavaScriptIndexingBehavior<Plugin>, List<Plugin> {
+  // To suppress missing implicit constructor warnings.
+  factory PluginArray._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  Plugin operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return JS("Plugin", "#[#]", this, index);
+  }
+
+  void operator []=(int index, Plugin value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<Plugin> mixins.
+  // Plugin is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  Plugin get first {
+    if (this.length > 0) {
+      return JS('Plugin', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  Plugin get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('Plugin', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  Plugin get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('Plugin', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  Plugin elementAt(int index) => this[index];
+  // -- end List<Plugin> mixins.
+
+  Plugin item(int index) native;
+
+  Plugin namedItem(String name) native;
+
+  void refresh(bool reload) native;
+}
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@Native("PointerEvent")
+class PointerEvent extends MouseEvent {
+  // To suppress missing implicit constructor warnings.
+  factory PointerEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PointerEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return PointerEvent._create_1(type, eventInitDict_1);
+    }
+    return PointerEvent._create_2(type);
+  }
+  static PointerEvent _create_1(type, eventInitDict) =>
+      JS('PointerEvent', 'new PointerEvent(#,#)', type, eventInitDict);
+  static PointerEvent _create_2(type) =>
+      JS('PointerEvent', 'new PointerEvent(#)', type);
+
+  final num height;
+
+  final bool isPrimary;
+
+  final int pointerId;
+
+  final String pointerType;
+
+  final num pressure;
+
+  final num tangentialPressure;
+
+  final int tiltX;
+
+  final int tiltY;
+
+  final int twist;
+
+  final num width;
+
+  List<PointerEvent> getCoalescedEvents() native;
+
+  /**
+   * PointerEvent used for both touch and mouse.  To check if touch is supported
+   * call the property TouchEvent.supported
+   */
+  static bool get supported {
+    try {
+      return PointerEvent('pointerover') is PointerEvent;
+    } catch (_) {}
+    return false;
+  }
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Native("PopStateEvent")
+class PopStateEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory PopStateEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PopStateEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return PopStateEvent._create_1(type, eventInitDict_1);
+    }
+    return PopStateEvent._create_2(type);
+  }
+  static PopStateEvent _create_1(type, eventInitDict) =>
+      JS('PopStateEvent', 'new PopStateEvent(#,#)', type, eventInitDict);
+  static PopStateEvent _create_2(type) =>
+      JS('PopStateEvent', 'new PopStateEvent(#)', type);
+
+  dynamic get state =>
+      convertNativeToDart_SerializedScriptValue(this._get_state);
+  @JSName('state')
+  @annotation_Creates_SerializedScriptValue
+  @annotation_Returns_SerializedScriptValue
+  final dynamic _get_state;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@Unstable()
+typedef void _PositionCallback(Geoposition position);
+// Copyright (c) 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.
+
+@Unstable()
+@Native("PositionError")
+class PositionError extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PositionError._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int PERMISSION_DENIED = 1;
+
+  static const int POSITION_UNAVAILABLE = 2;
+
+  static const int TIMEOUT = 3;
+
+  final int code;
+
+  final String message;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@Unstable()
+typedef void _PositionErrorCallback(PositionError error);
+// Copyright (c) 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.
+
+@Native("HTMLPreElement")
+class PreElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory PreElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PreElement() => JS('returns:PreElement;creates:PreElement;new:true',
+      '#.createElement(#)', document, "pre");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  PreElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Native("Presentation")
+class Presentation extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Presentation._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  PresentationRequest defaultRequest;
+
+  final PresentationReceiver receiver;
+}
+// Copyright (c) 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.
+
+@Native("PresentationAvailability")
+class PresentationAvailability extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory PresentationAvailability._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> changeEvent =
+      const EventStreamProvider<Event>('change');
+
+  final bool value;
+
+  Stream<Event> get onChange => changeEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("PresentationConnection")
+class PresentationConnection extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory PresentationConnection._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<MessageEvent> messageEvent =
+      const EventStreamProvider<MessageEvent>('message');
+
+  String binaryType;
+
+  final String id;
+
+  final String state;
+
+  final String url;
+
+  void close() native;
+
+  void send(data_OR_message) native;
+
+  void terminate() native;
+
+  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("PresentationConnectionAvailableEvent")
+class PresentationConnectionAvailableEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory PresentationConnectionAvailableEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PresentationConnectionAvailableEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return PresentationConnectionAvailableEvent._create_1(
+        type, eventInitDict_1);
+  }
+  static PresentationConnectionAvailableEvent _create_1(type, eventInitDict) =>
+      JS('PresentationConnectionAvailableEvent',
+          'new PresentationConnectionAvailableEvent(#,#)', type, eventInitDict);
+
+  final PresentationConnection connection;
+}
+// Copyright (c) 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.
+
+@Native("PresentationConnectionCloseEvent")
+class PresentationConnectionCloseEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory PresentationConnectionCloseEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PresentationConnectionCloseEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return PresentationConnectionCloseEvent._create_1(type, eventInitDict_1);
+  }
+  static PresentationConnectionCloseEvent _create_1(type, eventInitDict) => JS(
+      'PresentationConnectionCloseEvent',
+      'new PresentationConnectionCloseEvent(#,#)',
+      type,
+      eventInitDict);
+
+  final String message;
+
+  final String reason;
+}
+// Copyright (c) 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.
+
+@Native("PresentationConnectionList")
+class PresentationConnectionList extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory PresentationConnectionList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final List<PresentationConnection> connections;
+}
+// Copyright (c) 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.
+
+@Native("PresentationReceiver")
+class PresentationReceiver extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PresentationReceiver._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Future<PresentationConnectionList> get connectionList =>
+      promiseToFuture<PresentationConnectionList>(
+          JS("", "#.connectionList", this));
+}
+// Copyright (c) 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.
+
+@Native("PresentationRequest")
+class PresentationRequest extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory PresentationRequest._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PresentationRequest(url_OR_urls) {
+    if ((url_OR_urls is String)) {
+      return PresentationRequest._create_1(url_OR_urls);
+    }
+    if ((url_OR_urls is List<String>)) {
+      List urls_1 = convertDartToNative_StringArray(url_OR_urls);
+      return PresentationRequest._create_2(urls_1);
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+  static PresentationRequest _create_1(url_OR_urls) =>
+      JS('PresentationRequest', 'new PresentationRequest(#)', url_OR_urls);
+  static PresentationRequest _create_2(url_OR_urls) =>
+      JS('PresentationRequest', 'new PresentationRequest(#)', url_OR_urls);
+
+  Future<PresentationAvailability> getAvailability() =>
+      promiseToFuture<PresentationAvailability>(
+          JS("", "#.getAvailability()", this));
+
+  Future<PresentationConnection> reconnect(String id) =>
+      promiseToFuture<PresentationConnection>(
+          JS("", "#.reconnect(#)", this, id));
+
+  Future<PresentationConnection> start() =>
+      promiseToFuture<PresentationConnection>(JS("", "#.start()", this));
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("ProcessingInstruction")
+class ProcessingInstruction extends CharacterData {
+  // To suppress missing implicit constructor warnings.
+  factory ProcessingInstruction._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final StyleSheet sheet;
+
+  final String target;
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Native("HTMLProgressElement")
+class ProgressElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory ProgressElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ProgressElement() => document.createElement("progress");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ProgressElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => Element.isTagSupported('progress');
+
+  @Unstable()
+  @Returns('NodeList|Null')
+  @Creates('NodeList')
+  final List<Node> labels;
+
+  num max;
+
+  final num position;
+
+  num value;
+}
+// Copyright (c) 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.
+
+@Native("ProgressEvent")
+class ProgressEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory ProgressEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ProgressEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return ProgressEvent._create_1(type, eventInitDict_1);
+    }
+    return ProgressEvent._create_2(type);
+  }
+  static ProgressEvent _create_1(type, eventInitDict) =>
+      JS('ProgressEvent', 'new ProgressEvent(#,#)', type, eventInitDict);
+  static ProgressEvent _create_2(type) =>
+      JS('ProgressEvent', 'new ProgressEvent(#)', type);
+
+  final bool lengthComputable;
+
+  final int loaded;
+
+  final int total;
+}
+// Copyright (c) 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.
+
+@Native("PromiseRejectionEvent")
+class PromiseRejectionEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory PromiseRejectionEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PromiseRejectionEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return PromiseRejectionEvent._create_1(type, eventInitDict_1);
+  }
+  static PromiseRejectionEvent _create_1(type, eventInitDict) => JS(
+      'PromiseRejectionEvent',
+      'new PromiseRejectionEvent(#,#)',
+      type,
+      eventInitDict);
+
+  Future get promise => promiseToFuture(JS("", "#.promise", this));
+
+  final Object reason;
+}
+// Copyright (c) 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.
+
+@Native("PublicKeyCredential")
+class PublicKeyCredential extends Credential {
+  // To suppress missing implicit constructor warnings.
+  factory PublicKeyCredential._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final ByteBuffer rawId;
+
+  final AuthenticatorResponse response;
+}
+// Copyright (c) 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.
+
+@Native("PushEvent")
+class PushEvent extends ExtendableEvent {
+  // To suppress missing implicit constructor warnings.
+  factory PushEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PushEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return PushEvent._create_1(type, eventInitDict_1);
+    }
+    return PushEvent._create_2(type);
+  }
+  static PushEvent _create_1(type, eventInitDict) =>
+      JS('PushEvent', 'new PushEvent(#,#)', type, eventInitDict);
+  static PushEvent _create_2(type) => JS('PushEvent', 'new PushEvent(#)', type);
+
+  final PushMessageData data;
+}
+// Copyright (c) 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.
+
+@Native("PushManager")
+class PushManager extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PushManager._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static final List<String> supportedContentEncodings;
+
+  Future<PushSubscription> getSubscription() =>
+      promiseToFuture<PushSubscription>(JS("", "#.getSubscription()", this));
+
+  Future permissionState([Map options]) {
+    var options_dict = null;
+    if (options != null) {
+      options_dict = convertDartToNative_Dictionary(options);
+    }
+    return promiseToFuture(JS("", "#.permissionState(#)", this, options_dict));
+  }
+
+  Future<PushSubscription> subscribe([Map options]) {
+    var options_dict = null;
+    if (options != null) {
+      options_dict = convertDartToNative_Dictionary(options);
+    }
+    return promiseToFuture<PushSubscription>(
+        JS("", "#.subscribe(#)", this, options_dict));
+  }
+}
+// Copyright (c) 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.
+
+@Native("PushMessageData")
+class PushMessageData extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PushMessageData._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  ByteBuffer arrayBuffer() native;
+
+  Blob blob() native;
+
+  Object json() native;
+
+  String text() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("PushSubscription")
+class PushSubscription extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PushSubscription._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String endpoint;
+
+  final int expirationTime;
+
+  final PushSubscriptionOptions options;
+
+  ByteBuffer getKey(String name) native;
+
+  Future<bool> unsubscribe() =>
+      promiseToFuture<bool>(JS("", "#.unsubscribe()", this));
+}
+// Copyright (c) 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.
+
+@Native("PushSubscriptionOptions")
+class PushSubscriptionOptions extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PushSubscriptionOptions._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final ByteBuffer applicationServerKey;
+
+  final bool userVisibleOnly;
+}
+// Copyright (c) 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.
+
+@Native("HTMLQuoteElement")
+class QuoteElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory QuoteElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory QuoteElement() => JS(
+      'returns:QuoteElement;creates:QuoteElement;new:true',
+      '#.createElement(#)',
+      document,
+      "q");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  QuoteElement.created() : super.created();
+
+  String cite;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void RtcPeerConnectionErrorCallback(DomException exception);
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void _RtcSessionDescriptionCallback(RtcSessionDescription sdp);
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void RtcStatsCallback(RtcStatsResponse response);
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@Unstable()
+@Native("Range")
+class Range extends Interceptor {
+  factory Range() => document.createRange();
+
+  factory Range.fromPoint(Point point) =>
+      document._caretRangeFromPoint(point.x, point.y);
+  // To suppress missing implicit constructor warnings.
+  factory Range._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int END_TO_END = 2;
+
+  static const int END_TO_START = 3;
+
+  static const int START_TO_END = 1;
+
+  static const int START_TO_START = 0;
+
+  final bool collapsed;
+
+  final Node commonAncestorContainer;
+
+  final Node endContainer;
+
+  final int endOffset;
+
+  final Node startContainer;
+
+  final int startOffset;
+
+  DocumentFragment cloneContents() native;
+
+  Range cloneRange() native;
+
+  void collapse([bool toStart]) native;
+
+  int compareBoundaryPoints(int how, Range sourceRange) native;
+
+  int comparePoint(Node node, int offset) native;
+
+  DocumentFragment createContextualFragment(String fragment) native;
+
+  void deleteContents() native;
+
+  void detach() native;
+
+  void expand(String unit) native;
+
+  DocumentFragment extractContents() native;
+
+  Rectangle getBoundingClientRect() native;
+
+  @JSName('getClientRects')
+  @Returns('DomRectList|Null')
+  @Creates('DomRectList')
+  List<Rectangle> _getClientRects() native;
+
+  void insertNode(Node node) native;
+
+  bool isPointInRange(Node node, int offset) native;
+
+  void selectNode(Node node) native;
+
+  void selectNodeContents(Node node) native;
+
+  void setEnd(Node node, int offset) native;
+
+  void setEndAfter(Node node) native;
+
+  void setEndBefore(Node node) native;
+
+  void setStart(Node node, int offset) native;
+
+  void setStartAfter(Node node) native;
+
+  void setStartBefore(Node node) native;
+
+  void surroundContents(Node newParent) native;
+
+  List<Rectangle> getClientRects() {
+    var value = _getClientRects();
+
+    // If no prototype we need one for the world to hookup to the proper Dart class.
+    var jsProto = JS('', '#.prototype', value);
+    if (jsProto == null) {
+      JS('', '#.prototype = Object.create(null)', value);
+    }
+
+    applyExtension('DOMRectList', value);
+
+    return value;
+  }
+
+  /**
+   * Checks if createContextualFragment is supported.
+   *
+   * See also:
+   *
+   * * [createContextualFragment]
+   */
+  static bool get supportsCreateContextualFragment =>
+      JS('bool', '("createContextualFragment" in window.Range.prototype)');
+}
+// Copyright (c) 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.
+
+@Native("RelatedApplication")
+class RelatedApplication extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory RelatedApplication._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String id;
+
+  final String platform;
+
+  final String url;
+}
+// Copyright (c) 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.
+
+@Native("RelativeOrientationSensor")
+class RelativeOrientationSensor extends OrientationSensor {
+  // To suppress missing implicit constructor warnings.
+  factory RelativeOrientationSensor._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory RelativeOrientationSensor([Map sensorOptions]) {
+    if (sensorOptions != null) {
+      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
+      return RelativeOrientationSensor._create_1(sensorOptions_1);
+    }
+    return RelativeOrientationSensor._create_2();
+  }
+  static RelativeOrientationSensor _create_1(sensorOptions) => JS(
+      'RelativeOrientationSensor',
+      'new RelativeOrientationSensor(#)',
+      sensorOptions);
+  static RelativeOrientationSensor _create_2() =>
+      JS('RelativeOrientationSensor', 'new RelativeOrientationSensor()');
+}
+// Copyright (c) 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.
+
+@Native("RemotePlayback")
+class RemotePlayback extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory RemotePlayback._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String state;
+
+  Future cancelWatchAvailability([int id]) =>
+      promiseToFuture(JS("", "#.cancelWatchAvailability(#)", this, id));
+
+  Future prompt() => promiseToFuture(JS("", "#.prompt()", this));
+
+  Future<int> watchAvailability(RemotePlaybackAvailabilityCallback callback) =>
+      promiseToFuture<int>(JS("", "#.watchAvailability(#)", this, callback));
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void RemotePlaybackAvailabilityCallback(bool available);
+// Copyright (c) 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.
+
+@Native("ReportBody")
+class ReportBody extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ReportBody._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("ReportingObserver")
+class ReportingObserver extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ReportingObserver._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ReportingObserver(ReportingObserverCallback callback) {
+    var callback_1 = convertDartClosureToJS(callback, 2);
+    return ReportingObserver._create_1(callback_1);
+  }
+  static ReportingObserver _create_1(callback) =>
+      JS('ReportingObserver', 'new ReportingObserver(#)', callback);
+
+  void disconnect() native;
+
+  void observe() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void ReportingObserverCallback(
+    List reports, ReportingObserver observer);
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void RequestAnimationFrameCallback(num highResTime);
+// Copyright (c) 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.
+
+@Native("ResizeObserver")
+class ResizeObserver extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ResizeObserver._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ResizeObserver(ResizeObserverCallback callback) {
+    var callback_1 = convertDartClosureToJS(callback, 2);
+    return ResizeObserver._create_1(callback_1);
+  }
+  static ResizeObserver _create_1(callback) =>
+      JS('ResizeObserver', 'new ResizeObserver(#)', callback);
+
+  void disconnect() native;
+
+  void observe(Element target) native;
+
+  void unobserve(Element target) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void ResizeObserverCallback(
+    List<ResizeObserverEntry> entries, ResizeObserver observer);
+// Copyright (c) 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.
+
+@Native("ResizeObserverEntry")
+class ResizeObserverEntry extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ResizeObserverEntry._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final DomRectReadOnly contentRect;
+
+  final Element target;
+}
+// Copyright (c) 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.
+
+@Native("RTCCertificate")
+class RtcCertificate extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory RtcCertificate._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int expires;
+
+  List<Map> getFingerprints() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("RTCDataChannel,DataChannel")
+class RtcDataChannel extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory RtcDataChannel._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `close` events to event
+   * handlers that are not necessarily instances of [RtcDataChannel].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> closeEvent =
+      const EventStreamProvider<Event>('close');
+
+  /**
+   * Static factory designed to expose `error` events to event
+   * handlers that are not necessarily instances of [RtcDataChannel].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  /**
+   * Static factory designed to expose `message` events to event
+   * handlers that are not necessarily instances of [RtcDataChannel].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MessageEvent> messageEvent =
+      const EventStreamProvider<MessageEvent>('message');
+
+  /**
+   * Static factory designed to expose `open` events to event
+   * handlers that are not necessarily instances of [RtcDataChannel].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> openEvent =
+      const EventStreamProvider<Event>('open');
+
+  String binaryType;
+
+  final int bufferedAmount;
+
+  int bufferedAmountLowThreshold;
+
+  final int id;
+
+  final String label;
+
+  final int maxRetransmitTime;
+
+  final int maxRetransmits;
+
+  final bool negotiated;
+
+  final bool ordered;
+
+  final String protocol;
+
+  final String readyState;
+
+  final bool reliable;
+
+  void close() native;
+
+  void send(data) native;
+
+  @JSName('send')
+  void sendBlob(Blob data) native;
+
+  @JSName('send')
+  void sendByteBuffer(ByteBuffer data) native;
+
+  @JSName('send')
+  void sendString(String data) native;
+
+  @JSName('send')
+  void sendTypedData(TypedData data) native;
+
+  /// Stream of `close` events handled by this [RtcDataChannel].
+  Stream<Event> get onClose => closeEvent.forTarget(this);
+
+  /// Stream of `error` events handled by this [RtcDataChannel].
+  Stream<Event> get onError => errorEvent.forTarget(this);
+
+  /// Stream of `message` events handled by this [RtcDataChannel].
+  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
+
+  /// Stream of `open` events handled by this [RtcDataChannel].
+  Stream<Event> get onOpen => openEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("RTCDataChannelEvent")
+class RtcDataChannelEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory RtcDataChannelEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory RtcDataChannelEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return RtcDataChannelEvent._create_1(type, eventInitDict_1);
+  }
+  static RtcDataChannelEvent _create_1(type, eventInitDict) => JS(
+      'RtcDataChannelEvent',
+      'new RTCDataChannelEvent(#,#)',
+      type,
+      eventInitDict);
+
+  final RtcDataChannel channel;
+}
+// Copyright (c) 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.
+
+@Native("RTCDTMFSender")
+class RtcDtmfSender extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory RtcDtmfSender._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `tonechange` events to event
+   * handlers that are not necessarily instances of [RtcDtmfSender].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<RtcDtmfToneChangeEvent> toneChangeEvent =
+      const EventStreamProvider<RtcDtmfToneChangeEvent>('tonechange');
+
+  @JSName('canInsertDTMF')
+  final bool canInsertDtmf;
+
+  final int duration;
+
+  final int interToneGap;
+
+  final String toneBuffer;
+
+  final MediaStreamTrack track;
+
+  @JSName('insertDTMF')
+  void insertDtmf(String tones, [int duration, int interToneGap]) native;
+
+  /// Stream of `tonechange` events handled by this [RtcDtmfSender].
+  Stream<RtcDtmfToneChangeEvent> get onToneChange =>
+      toneChangeEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("RTCDTMFToneChangeEvent")
+class RtcDtmfToneChangeEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory RtcDtmfToneChangeEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory RtcDtmfToneChangeEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return RtcDtmfToneChangeEvent._create_1(type, eventInitDict_1);
+  }
+  static RtcDtmfToneChangeEvent _create_1(type, eventInitDict) => JS(
+      'RtcDtmfToneChangeEvent',
+      'new RTCDTMFToneChangeEvent(#,#)',
+      type,
+      eventInitDict);
+
+  final String tone;
+}
+// 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@Native("RTCIceCandidate,mozRTCIceCandidate")
+class RtcIceCandidate extends Interceptor {
+  factory RtcIceCandidate(Map dictionary) {
+    // TODO(efortuna): Remove this check if when you can actually construct with
+    // the unprefixed RTCIceCandidate in Firefox (currently both are defined,
+    // but one can't be used as a constructor).
+    var constructorName = JS(
+        '',
+        'window[#]',
+        Device.isFirefox
+            ? '${Device.propertyPrefix}RTCIceCandidate'
+            : 'RTCIceCandidate');
+    return JS('RtcIceCandidate', 'new #(#)', constructorName,
+        convertDartToNative_SerializedScriptValue(dictionary));
+  }
+  // To suppress missing implicit constructor warnings.
+  factory RtcIceCandidate._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  String candidate;
+
+  int sdpMLineIndex;
+
+  String sdpMid;
+}
+// Copyright (c) 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.
+
+@Native("RTCLegacyStatsReport")
+class RtcLegacyStatsReport extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory RtcLegacyStatsReport._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String id;
+
+  DateTime get timestamp => convertNativeToDart_DateTime(this._get_timestamp);
+  @JSName('timestamp')
+  final dynamic _get_timestamp;
+
+  final String type;
+
+  List<String> names() native;
+
+  String stat(String name) native;
+}
+// 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@Native("RTCPeerConnection,webkitRTCPeerConnection,mozRTCPeerConnection")
+class RtcPeerConnection extends EventTarget {
+  factory RtcPeerConnection(Map rtcIceServers, [Map mediaConstraints]) {
+    var constructorName = JS('RtcPeerConnection', 'window[#]',
+        '${Device.propertyPrefix}RTCPeerConnection');
+    if (mediaConstraints != null) {
+      return JS(
+          'RtcPeerConnection',
+          'new #(#,#)',
+          constructorName,
+          convertDartToNative_SerializedScriptValue(rtcIceServers),
+          convertDartToNative_SerializedScriptValue(mediaConstraints));
+    } else {
+      return JS('RtcPeerConnection', 'new #(#)', constructorName,
+          convertDartToNative_SerializedScriptValue(rtcIceServers));
+    }
+  }
+
+  /**
+   * Checks if Real Time Communication (RTC) APIs are supported and enabled on
+   * the current platform.
+   */
+  static bool get supported {
+    // Currently in Firefox some of the RTC elements are defined but throw an
+    // error unless the user has specifically enabled them in their
+    // about:config. So we have to construct an element to actually test if RTC
+    // is supported at the given time.
+    try {
+      new RtcPeerConnection({
+        "iceServers": [
+          {"url": "stun:localhost"}
+        ]
+      });
+      return true;
+    } catch (_) {
+      return false;
+    }
+    return false;
+  }
+
+  /**
+  * Temporarily exposes _getStats and old getStats as getLegacyStats until Chrome fully supports
+  * new getStats API.
+  */
+  Future<RtcStatsResponse> getLegacyStats([MediaStreamTrack selector]) {
+    var completer = new Completer<RtcStatsResponse>();
+    _getStats((value) {
+      completer.complete(value);
+    }, selector);
+    return completer.future;
+  }
+
+  @JSName('getStats')
+  Future _getStats(
+      [RtcStatsCallback successCallback, MediaStreamTrack selector]) native;
+
+  static Future generateCertificate(/*AlgorithmIdentifier*/ keygenAlgorithm) =>
+      JS('dynamic', 'generateCertificate(#)', keygenAlgorithm);
+
+  // To suppress missing implicit constructor warnings.
+  factory RtcPeerConnection._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `addstream` events to event
+   * handlers that are not necessarily instances of [RtcPeerConnection].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MediaStreamEvent> addStreamEvent =
+      const EventStreamProvider<MediaStreamEvent>('addstream');
+
+  /**
+   * Static factory designed to expose `datachannel` events to event
+   * handlers that are not necessarily instances of [RtcPeerConnection].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<RtcDataChannelEvent> dataChannelEvent =
+      const EventStreamProvider<RtcDataChannelEvent>('datachannel');
+
+  /**
+   * Static factory designed to expose `icecandidate` events to event
+   * handlers that are not necessarily instances of [RtcPeerConnection].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<RtcPeerConnectionIceEvent>
+      iceCandidateEvent =
+      const EventStreamProvider<RtcPeerConnectionIceEvent>('icecandidate');
+
+  /**
+   * Static factory designed to expose `iceconnectionstatechange` events to event
+   * handlers that are not necessarily instances of [RtcPeerConnection].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> iceConnectionStateChangeEvent =
+      const EventStreamProvider<Event>('iceconnectionstatechange');
+
+  /**
+   * Static factory designed to expose `negotiationneeded` events to event
+   * handlers that are not necessarily instances of [RtcPeerConnection].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> negotiationNeededEvent =
+      const EventStreamProvider<Event>('negotiationneeded');
+
+  /**
+   * Static factory designed to expose `removestream` events to event
+   * handlers that are not necessarily instances of [RtcPeerConnection].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MediaStreamEvent> removeStreamEvent =
+      const EventStreamProvider<MediaStreamEvent>('removestream');
+
+  /**
+   * Static factory designed to expose `signalingstatechange` events to event
+   * handlers that are not necessarily instances of [RtcPeerConnection].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> signalingStateChangeEvent =
+      const EventStreamProvider<Event>('signalingstatechange');
+
+  final String iceConnectionState;
+
+  final String iceGatheringState;
+
+  final RtcSessionDescription localDescription;
+
+  final RtcSessionDescription remoteDescription;
+
+  final String signalingState;
+
+  Future addIceCandidate(Object candidate,
+          [VoidCallback successCallback,
+          RtcPeerConnectionErrorCallback failureCallback]) =>
+      promiseToFuture(JS("", "#.addIceCandidate(#, #, #)", this, candidate,
+          successCallback, failureCallback));
+
+  void addStream(MediaStream stream, [Map mediaConstraints]) {
+    if (mediaConstraints != null) {
+      var mediaConstraints_1 = convertDartToNative_Dictionary(mediaConstraints);
+      _addStream_1(stream, mediaConstraints_1);
+      return;
+    }
+    _addStream_2(stream);
+    return;
+  }
+
+  @JSName('addStream')
+  void _addStream_1(MediaStream stream, mediaConstraints) native;
+  @JSName('addStream')
+  void _addStream_2(MediaStream stream) native;
+
+  RtcRtpSender addTrack(MediaStreamTrack track, MediaStream streams) native;
+
+  void close() native;
+
+  Future<RtcSessionDescription> createAnswer([Map options]) {
+    var options_dict = null;
+    if (options != null) {
+      options_dict = convertDartToNative_Dictionary(options);
+    }
+    return promiseToFuture<RtcSessionDescription>(
+        JS("", "#.createAnswer(#)", this, options_dict));
+  }
+
+  @JSName('createDTMFSender')
+  RtcDtmfSender createDtmfSender(MediaStreamTrack track) native;
+
+  RtcDataChannel createDataChannel(String label, [Map dataChannelDict]) {
+    if (dataChannelDict != null) {
+      var dataChannelDict_1 = convertDartToNative_Dictionary(dataChannelDict);
+      return _createDataChannel_1(label, dataChannelDict_1);
+    }
+    return _createDataChannel_2(label);
+  }
+
+  @JSName('createDataChannel')
+  RtcDataChannel _createDataChannel_1(label, dataChannelDict) native;
+  @JSName('createDataChannel')
+  RtcDataChannel _createDataChannel_2(label) native;
+
+  Future<RtcSessionDescription> createOffer([Map options]) {
+    var options_dict = null;
+    if (options != null) {
+      options_dict = convertDartToNative_Dictionary(options);
+    }
+    return promiseToFuture<RtcSessionDescription>(
+        JS("", "#.createOffer(#)", this, options_dict));
+  }
+
+  List<MediaStream> getLocalStreams() native;
+
+  List<RtcRtpReceiver> getReceivers() native;
+
+  List<MediaStream> getRemoteStreams() native;
+
+  List<RtcRtpSender> getSenders() native;
+
+  Future<RtcStatsReport> getStats() =>
+      promiseToFuture<RtcStatsReport>(JS("", "#.getStats()", this));
+
+  void removeStream(MediaStream stream) native;
+
+  void removeTrack(RtcRtpSender sender) native;
+
+  void setConfiguration(Map configuration) {
+    var configuration_1 = convertDartToNative_Dictionary(configuration);
+    _setConfiguration_1(configuration_1);
+    return;
+  }
+
+  @JSName('setConfiguration')
+  void _setConfiguration_1(configuration) native;
+
+  Future setLocalDescription(Map description) {
+    var description_dict = convertDartToNative_Dictionary(description);
+    return promiseToFuture(
+        JS("", "#.setLocalDescription(#)", this, description_dict));
+  }
+
+  Future setRemoteDescription(Map description) {
+    var description_dict = convertDartToNative_Dictionary(description);
+    return promiseToFuture(
+        JS("", "#.setRemoteDescription(#)", this, description_dict));
+  }
+
+  /// Stream of `addstream` events handled by this [RtcPeerConnection].
+  Stream<MediaStreamEvent> get onAddStream => addStreamEvent.forTarget(this);
+
+  /// Stream of `datachannel` events handled by this [RtcPeerConnection].
+  Stream<RtcDataChannelEvent> get onDataChannel =>
+      dataChannelEvent.forTarget(this);
+
+  /// Stream of `icecandidate` events handled by this [RtcPeerConnection].
+  Stream<RtcPeerConnectionIceEvent> get onIceCandidate =>
+      iceCandidateEvent.forTarget(this);
+
+  /// Stream of `iceconnectionstatechange` events handled by this [RtcPeerConnection].
+  Stream<Event> get onIceConnectionStateChange =>
+      iceConnectionStateChangeEvent.forTarget(this);
+
+  /// Stream of `negotiationneeded` events handled by this [RtcPeerConnection].
+  Stream<Event> get onNegotiationNeeded =>
+      negotiationNeededEvent.forTarget(this);
+
+  /// Stream of `removestream` events handled by this [RtcPeerConnection].
+  Stream<MediaStreamEvent> get onRemoveStream =>
+      removeStreamEvent.forTarget(this);
+
+  /// Stream of `signalingstatechange` events handled by this [RtcPeerConnection].
+  Stream<Event> get onSignalingStateChange =>
+      signalingStateChangeEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("RTCPeerConnectionIceEvent")
+class RtcPeerConnectionIceEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory RtcPeerConnectionIceEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory RtcPeerConnectionIceEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return RtcPeerConnectionIceEvent._create_1(type, eventInitDict_1);
+    }
+    return RtcPeerConnectionIceEvent._create_2(type);
+  }
+  static RtcPeerConnectionIceEvent _create_1(type, eventInitDict) => JS(
+      'RtcPeerConnectionIceEvent',
+      'new RTCPeerConnectionIceEvent(#,#)',
+      type,
+      eventInitDict);
+  static RtcPeerConnectionIceEvent _create_2(type) =>
+      JS('RtcPeerConnectionIceEvent', 'new RTCPeerConnectionIceEvent(#)', type);
+
+  final RtcIceCandidate candidate;
+}
+// Copyright (c) 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.
+
+@Native("RTCRtpContributingSource")
+class RtcRtpContributingSource extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory RtcRtpContributingSource._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int source;
+
+  final num timestamp;
+}
+// Copyright (c) 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.
+
+@Native("RTCRtpReceiver")
+class RtcRtpReceiver extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory RtcRtpReceiver._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final MediaStreamTrack track;
+
+  List<RtcRtpContributingSource> getContributingSources() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("RTCRtpSender")
+class RtcRtpSender extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory RtcRtpSender._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final MediaStreamTrack track;
+}
+// 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@Native("RTCSessionDescription,mozRTCSessionDescription")
+class RtcSessionDescription extends Interceptor {
+  factory RtcSessionDescription(Map dictionary) {
+    // TODO(efortuna): Remove this check if when you can actually construct with
+    // the unprefixed RTCIceCandidate in Firefox (currently both are defined,
+    // but one can't be used as a constructor).
+    var constructorName = JS(
+        '',
+        'window[#]',
+        Device.isFirefox
+            ? '${Device.propertyPrefix}RTCSessionDescription'
+            : 'RTCSessionDescription');
+    return JS('RtcSessionDescription', 'new #(#)', constructorName,
+        convertDartToNative_SerializedScriptValue(dictionary));
+  }
+  // To suppress missing implicit constructor warnings.
+  factory RtcSessionDescription._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  String sdp;
+
+  String type;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("RTCStatsReport")
+class RtcStatsReport extends Interceptor with MapMixin<String, dynamic> {
+  // To suppress missing implicit constructor warnings.
+  factory RtcStatsReport._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Map _getItem(String key) =>
+      convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key));
+
+  void addAll(Map<String, dynamic> other) {
+    throw new UnsupportedError("Not supported");
+  }
+
+  bool containsValue(dynamic value) => values.any((e) => e == value);
+
+  bool containsKey(dynamic key) => _getItem(key) != null;
+
+  Map operator [](dynamic key) => _getItem(key);
+
+  void forEach(void f(String key, dynamic value)) {
+    var entries = JS('', '#.entries()', this);
+    while (true) {
+      var entry = JS('', '#.next()', entries);
+      if (JS('bool', '#.done', entry)) return;
+      f(JS('String', '#.value[0]', entry),
+          convertNativeToDart_Dictionary(JS('', '#.value[1]', entry)));
+    }
+  }
+
+  Iterable<String> get keys {
+    final keys = <String>[];
+    forEach((k, v) => keys.add(k));
+    return keys;
+  }
+
+  Iterable<Map> get values {
+    final values = <Map>[];
+    forEach((k, v) => values.add(v));
+    return values;
+  }
+
+  int get length => JS('int', '#.size', this);
+
+  bool get isEmpty => length == 0;
+
+  bool get isNotEmpty => !isEmpty;
+
+  void operator []=(String key, dynamic value) {
+    throw new UnsupportedError("Not supported");
+  }
+
+  dynamic putIfAbsent(String key, dynamic ifAbsent()) {
+    throw new UnsupportedError("Not supported");
+  }
+
+  String remove(dynamic key) {
+    throw new UnsupportedError("Not supported");
+  }
+
+  void clear() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("RTCStatsResponse")
+class RtcStatsResponse extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory RtcStatsResponse._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  RtcLegacyStatsReport namedItem(String name) native;
+
+  List<RtcLegacyStatsReport> result() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("RTCTrackEvent")
+class RtcTrackEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory RtcTrackEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory RtcTrackEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return RtcTrackEvent._create_1(type, eventInitDict_1);
+  }
+  static RtcTrackEvent _create_1(type, eventInitDict) =>
+      JS('RtcTrackEvent', 'new RTCTrackEvent(#,#)', type, eventInitDict);
+
+  final RtcRtpReceiver receiver;
+
+  final List<MediaStream> streams;
+
+  final MediaStreamTrack track;
+}
+// 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.
+
+@Native("Screen")
+class Screen extends Interceptor {
+  Rectangle get available =>
+      new Rectangle(_availLeft, _availTop, _availWidth, _availHeight);
+  // To suppress missing implicit constructor warnings.
+  factory Screen._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('availHeight')
+  final int _availHeight;
+
+  @JSName('availLeft')
+  final int _availLeft;
+
+  @JSName('availTop')
+  final int _availTop;
+
+  @JSName('availWidth')
+  final int _availWidth;
+
+  final int colorDepth;
+
+  final int height;
+
+  bool keepAwake;
+
+  final ScreenOrientation orientation;
+
+  final int pixelDepth;
+
+  final int width;
+}
+// Copyright (c) 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.
+
+@Native("ScreenOrientation")
+class ScreenOrientation extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory ScreenOrientation._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> changeEvent =
+      const EventStreamProvider<Event>('change');
+
+  final int angle;
+
+  final String type;
+
+  Future lock(String orientation) =>
+      promiseToFuture(JS("", "#.lock(#)", this, orientation));
+
+  void unlock() native;
+
+  Stream<Event> get onChange => changeEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("HTMLScriptElement")
+class ScriptElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory ScriptElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ScriptElement() => JS(
+      'returns:ScriptElement;creates:ScriptElement;new:true',
+      '#.createElement(#)',
+      document,
+      "script");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ScriptElement.created() : super.created();
+
+  bool async;
+
+  String charset;
+
+  String crossOrigin;
+
+  bool defer;
+
+  String integrity;
+
+  bool noModule;
+
+  String src;
+
+  String type;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("ScrollState")
+class ScrollState extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ScrollState._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ScrollState([Map scrollStateInit]) {
+    if (scrollStateInit != null) {
+      var scrollStateInit_1 = convertDartToNative_Dictionary(scrollStateInit);
+      return ScrollState._create_1(scrollStateInit_1);
+    }
+    return ScrollState._create_2();
+  }
+  static ScrollState _create_1(scrollStateInit) =>
+      JS('ScrollState', 'new ScrollState(#)', scrollStateInit);
+  static ScrollState _create_2() => JS('ScrollState', 'new ScrollState()');
+
+  final num deltaGranularity;
+
+  final num deltaX;
+
+  final num deltaY;
+
+  final bool fromUserInput;
+
+  final bool inInertialPhase;
+
+  final bool isBeginning;
+
+  final bool isDirectManipulation;
+
+  final bool isEnding;
+
+  final int positionX;
+
+  final int positionY;
+
+  final num velocityX;
+
+  final num velocityY;
+
+  void consumeDelta(num x, num y) native;
+
+  void distributeToScrollChainDescendant() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void ScrollStateCallback(ScrollState scrollState);
+// Copyright (c) 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.
+
+@Native("ScrollTimeline")
+class ScrollTimeline extends AnimationTimeline {
+  // To suppress missing implicit constructor warnings.
+  factory ScrollTimeline._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ScrollTimeline([Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return ScrollTimeline._create_1(options_1);
+    }
+    return ScrollTimeline._create_2();
+  }
+  static ScrollTimeline _create_1(options) =>
+      JS('ScrollTimeline', 'new ScrollTimeline(#)', options);
+  static ScrollTimeline _create_2() =>
+      JS('ScrollTimeline', 'new ScrollTimeline()');
+
+  final String orientation;
+
+  final Element scrollSource;
+
+  final Object timeRange;
+}
+// Copyright (c) 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.
+
+@Native("SecurityPolicyViolationEvent")
+class SecurityPolicyViolationEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory SecurityPolicyViolationEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory SecurityPolicyViolationEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return SecurityPolicyViolationEvent._create_1(type, eventInitDict_1);
+    }
+    return SecurityPolicyViolationEvent._create_2(type);
+  }
+  static SecurityPolicyViolationEvent _create_1(type, eventInitDict) => JS(
+      'SecurityPolicyViolationEvent',
+      'new SecurityPolicyViolationEvent(#,#)',
+      type,
+      eventInitDict);
+  static SecurityPolicyViolationEvent _create_2(type) => JS(
+      'SecurityPolicyViolationEvent',
+      'new SecurityPolicyViolationEvent(#)',
+      type);
+
+  @JSName('blockedURI')
+  final String blockedUri;
+
+  final int columnNumber;
+
+  final String disposition;
+
+  @JSName('documentURI')
+  final String documentUri;
+
+  final String effectiveDirective;
+
+  final int lineNumber;
+
+  final String originalPolicy;
+
+  final String referrer;
+
+  final String sample;
+
+  final String sourceFile;
+
+  final int statusCode;
+
+  final String violatedDirective;
+}
+// Copyright (c) 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.
+
+@Native("HTMLSelectElement")
+class SelectElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory SelectElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory SelectElement() => JS(
+      'returns:SelectElement;creates:SelectElement;new:true',
+      '#.createElement(#)',
+      document,
+      "select");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SelectElement.created() : super.created();
+
+  bool autofocus;
+
+  bool disabled;
+
+  final FormElement form;
+
+  @Unstable()
+  @Returns('NodeList|Null')
+  @Creates('NodeList')
+  final List<Node> labels;
+
+  int length;
+
+  bool multiple;
+
+  String name;
+
+  bool required;
+
+  int selectedIndex;
+
+  int size;
+
+  final String type;
+
+  final String validationMessage;
+
+  final ValidityState validity;
+
+  String value;
+
+  final bool willValidate;
+
+  void __setter__(int index, OptionElement option) native;
+
+  void add(Object element, Object before) native;
+
+  bool checkValidity() native;
+
+  Element item(int index) native;
+
+  OptionElement namedItem(String name) native;
+
+  bool reportValidity() native;
+
+  void setCustomValidity(String error) native;
+
+  // Override default options, since IE returns SelectElement itself and it
+  // does not operate as a List.
+  List<OptionElement> get options {
+    dynamic options = this.querySelectorAll<OptionElement>('option');
+    return new UnmodifiableListView(options.toList());
+  }
+
+  List<OptionElement> get selectedOptions {
+    // IE does not change the selected flag for single-selection items.
+    if (this.multiple) {
+      var options = this.options.where((o) => o.selected).toList();
+      return new UnmodifiableListView(options);
+    } else {
+      return [this.options[this.selectedIndex]];
+    }
+  }
+}
+// Copyright (c) 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.
+
+@Native("Selection")
+class Selection extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Selection._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final Node anchorNode;
+
+  final int anchorOffset;
+
+  final Node baseNode;
+
+  final int baseOffset;
+
+  final Node extentNode;
+
+  final int extentOffset;
+
+  final Node focusNode;
+
+  final int focusOffset;
+
+  final bool isCollapsed;
+
+  final int rangeCount;
+
+  final String type;
+
+  void addRange(Range range) native;
+
+  void collapse(Node node, [int offset]) native;
+
+  void collapseToEnd() native;
+
+  void collapseToStart() native;
+
+  bool containsNode(Node node, [bool allowPartialContainment]) native;
+
+  void deleteFromDocument() native;
+
+  void empty() native;
+
+  void extend(Node node, [int offset]) native;
+
+  Range getRangeAt(int index) native;
+
+  void modify(String alter, String direction, String granularity) native;
+
+  void removeAllRanges() native;
+
+  void removeRange(Range range) native;
+
+  void selectAllChildren(Node node) native;
+
+  void setBaseAndExtent(
+      Node baseNode, int baseOffset, Node extentNode, int extentOffset) native;
+
+  void setPosition(Node node, [int offset]) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("Sensor")
+class Sensor extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory Sensor._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  final bool activated;
+
+  final bool hasReading;
+
+  final num timestamp;
+
+  void start() native;
+
+  void stop() native;
+
+  Stream<Event> get onError => errorEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("SensorErrorEvent")
+class SensorErrorEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory SensorErrorEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory SensorErrorEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return SensorErrorEvent._create_1(type, eventInitDict_1);
+  }
+  static SensorErrorEvent _create_1(type, eventInitDict) =>
+      JS('SensorErrorEvent', 'new SensorErrorEvent(#,#)', type, eventInitDict);
+
+  final DomException error;
+}
+// Copyright (c) 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.
+
+@Native("ServiceWorker")
+class ServiceWorker extends EventTarget implements AbstractWorker {
+  // To suppress missing implicit constructor warnings.
+  factory ServiceWorker._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  @JSName('scriptURL')
+  final String scriptUrl;
+
+  final String state;
+
+  void postMessage(/*any*/ message, [List<Object> transfer]) {
+    if (transfer != null) {
+      var message_1 = convertDartToNative_SerializedScriptValue(message);
+      _postMessage_1(message_1, transfer);
+      return;
+    }
+    var message_1 = convertDartToNative_SerializedScriptValue(message);
+    _postMessage_2(message_1);
+    return;
+  }
+
+  @JSName('postMessage')
+  void _postMessage_1(message, List<Object> transfer) native;
+  @JSName('postMessage')
+  void _postMessage_2(message) native;
+
+  Stream<Event> get onError => errorEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("ServiceWorkerContainer")
+class ServiceWorkerContainer extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory ServiceWorkerContainer._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<MessageEvent> messageEvent =
+      const EventStreamProvider<MessageEvent>('message');
+
+  final ServiceWorker controller;
+
+  Future<ServiceWorkerRegistration> get ready =>
+      promiseToFuture<ServiceWorkerRegistration>(JS("", "#.ready", this));
+
+  Future<ServiceWorkerRegistration> getRegistration([String documentURL]) =>
+      promiseToFuture<ServiceWorkerRegistration>(
+          JS("", "#.getRegistration(#)", this, documentURL));
+
+  Future<List<ServiceWorkerRegistration>> getRegistrations() =>
+      promiseToFuture<List<ServiceWorkerRegistration>>(
+          JS("", "#.getRegistrations()", this));
+
+  Future<ServiceWorkerRegistration> register(String url, [Map options]) {
+    var options_dict = null;
+    if (options != null) {
+      options_dict = convertDartToNative_Dictionary(options);
+    }
+    return promiseToFuture<ServiceWorkerRegistration>(
+        JS("", "#.register(#, #)", this, url, options_dict));
+  }
+
+  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("ServiceWorkerGlobalScope")
+class ServiceWorkerGlobalScope extends WorkerGlobalScope {
+  // To suppress missing implicit constructor warnings.
+  factory ServiceWorkerGlobalScope._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> activateEvent =
+      const EventStreamProvider<Event>('activate');
+
+  static const EventStreamProvider<Event> fetchEvent =
+      const EventStreamProvider<Event>('fetch');
+
+  static const EventStreamProvider<ForeignFetchEvent> foreignfetchEvent =
+      const EventStreamProvider<ForeignFetchEvent>('foreignfetch');
+
+  static const EventStreamProvider<Event> installEvent =
+      const EventStreamProvider<Event>('install');
+
+  static const EventStreamProvider<MessageEvent> messageEvent =
+      const EventStreamProvider<MessageEvent>('message');
+
+  final Clients clients;
+
+  final ServiceWorkerRegistration registration;
+
+  Future skipWaiting() => promiseToFuture(JS("", "#.skipWaiting()", this));
+
+  Stream<Event> get onActivate => activateEvent.forTarget(this);
+
+  Stream<Event> get onFetch => fetchEvent.forTarget(this);
+
+  Stream<ForeignFetchEvent> get onForeignfetch =>
+      foreignfetchEvent.forTarget(this);
+
+  Stream<Event> get onInstall => installEvent.forTarget(this);
+
+  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
+
+  static ServiceWorkerGlobalScope get instance {
+    return _workerSelf as ServiceWorkerGlobalScope;
+  }
+}
+
+// Copyright (c) 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.
+
+@Native("ServiceWorkerRegistration")
+class ServiceWorkerRegistration extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory ServiceWorkerRegistration._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final ServiceWorker active;
+
+  final BackgroundFetchManager backgroundFetch;
+
+  final ServiceWorker installing;
+
+  final NavigationPreloadManager navigationPreload;
+
+  final PaymentManager paymentManager;
+
+  final PushManager pushManager;
+
+  final String scope;
+
+  final SyncManager sync;
+
+  final ServiceWorker waiting;
+
+  Future<List<Notification>> getNotifications([Map filter]) {
+    var filter_dict = null;
+    if (filter != null) {
+      filter_dict = convertDartToNative_Dictionary(filter);
+    }
+    return promiseToFuture<List<Notification>>(
+        JS("", "#.getNotifications(#)", this, filter_dict));
+  }
+
+  Future showNotification(String title, [Map options]) {
+    var options_dict = null;
+    if (options != null) {
+      options_dict = convertDartToNative_Dictionary(options);
+    }
+    return promiseToFuture(
+        JS("", "#.showNotification(#, #)", this, title, options_dict));
+  }
+
+  Future<bool> unregister() =>
+      promiseToFuture<bool>(JS("", "#.unregister()", this));
+
+  Future update() => promiseToFuture(JS("", "#.update()", this));
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME, '26')
+@Native("HTMLShadowElement")
+class ShadowElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory ShadowElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ShadowElement() => document.createElement("shadow");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ShadowElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => Element.isTagSupported('shadow');
+
+  @Returns('NodeList|Null')
+  @Creates('NodeList')
+  List<Node> getDistributedNodes() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@SupportedBrowser(SupportedBrowser.CHROME, '26')
+@Native("ShadowRoot")
+class ShadowRoot extends DocumentFragment implements DocumentOrShadowRoot {
+  // To suppress missing implicit constructor warnings.
+  factory ShadowRoot._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool delegatesFocus;
+
+  final Element host;
+
+  @JSName('innerHTML')
+  String innerHtml;
+
+  final String mode;
+
+  final ShadowRoot olderShadowRoot;
+
+  // From DocumentOrShadowRoot
+
+  final Element activeElement;
+
+  final Element fullscreenElement;
+
+  final Element pointerLockElement;
+
+  @Returns('_StyleSheetList|Null')
+  @Creates('_StyleSheetList')
+  final List<StyleSheet> styleSheets;
+
+  Element elementFromPoint(int x, int y) native;
+
+  List<Element> elementsFromPoint(int x, int y) native;
+
+  Selection getSelection() native;
+
+  static bool get supported => JS(
+      'bool',
+      '!!(Element.prototype.createShadowRoot||'
+          'Element.prototype.webkitCreateShadowRoot)');
+
+  static bool _shadowRootDeprecationReported = false;
+  static void _shadowRootDeprecationReport() {
+    if (!_shadowRootDeprecationReported) {
+      window.console.warn('''
+ShadowRoot.resetStyleInheritance and ShadowRoot.applyAuthorStyles now deprecated in dart:html.
+Please remove them from your code.
+''');
+      _shadowRootDeprecationReported = true;
+    }
+  }
+
+  @deprecated
+  bool get resetStyleInheritance {
+    _shadowRootDeprecationReport();
+    // Default value from when it was specified.
+    return false;
+  }
+
+  @deprecated
+  set resetStyleInheritance(bool value) {
+    _shadowRootDeprecationReport();
+  }
+
+  @deprecated
+  bool get applyAuthorStyles {
+    _shadowRootDeprecationReport();
+    // Default value from when it was specified.
+    return false;
+  }
+
+  @deprecated
+  set applyAuthorStyles(bool value) {
+    _shadowRootDeprecationReport();
+  }
+}
+// Copyright (c) 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.
+
+@Native("SharedArrayBuffer")
+class SharedArrayBuffer extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory SharedArrayBuffer._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int byteLength;
+}
+// Copyright (c) 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.
+
+@Native("SharedWorker")
+class SharedWorker extends EventTarget implements AbstractWorker {
+  // To suppress missing implicit constructor warnings.
+  factory SharedWorker._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  factory SharedWorker(String scriptURL, [String name]) {
+    if (name != null) {
+      return SharedWorker._create_1(scriptURL, name);
+    }
+    return SharedWorker._create_2(scriptURL);
+  }
+  static SharedWorker _create_1(scriptURL, name) =>
+      JS('SharedWorker', 'new SharedWorker(#,#)', scriptURL, name);
+  static SharedWorker _create_2(scriptURL) =>
+      JS('SharedWorker', 'new SharedWorker(#)', scriptURL);
+
+  final MessagePort port;
+
+  Stream<Event> get onError => errorEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("SharedWorkerGlobalScope")
+class SharedWorkerGlobalScope extends WorkerGlobalScope {
+  // To suppress missing implicit constructor warnings.
+  factory SharedWorkerGlobalScope._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `connect` events to event
+   * handlers that are not necessarily instances of [SharedWorkerGlobalScope].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> connectEvent =
+      const EventStreamProvider<Event>('connect');
+
+  static const int PERSISTENT = 1;
+
+  static const int TEMPORARY = 0;
+
+  final String name;
+
+  void close() native;
+
+  @JSName('webkitRequestFileSystem')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void _webkitRequestFileSystem(int type, int size,
+      [_FileSystemCallback successCallback,
+      _ErrorCallback errorCallback]) native;
+
+  @JSName('webkitRequestFileSystemSync')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  _DOMFileSystemSync requestFileSystemSync(int type, int size) native;
+
+  @JSName('webkitResolveLocalFileSystemSyncURL')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  _EntrySync resolveLocalFileSystemSyncUrl(String url) native;
+
+  @JSName('webkitResolveLocalFileSystemURL')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void _webkitResolveLocalFileSystemUrl(
+      String url, _EntryCallback successCallback,
+      [_ErrorCallback errorCallback]) native;
+
+  /// Stream of `connect` events handled by this [SharedWorkerGlobalScope].
+  Stream<Event> get onConnect => connectEvent.forTarget(this);
+
+  static SharedWorkerGlobalScope get instance {
+    return _workerSelf as SharedWorkerGlobalScope;
+  }
+}
+
+// Copyright (c) 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.
+
+@Native("HTMLSlotElement")
+class SlotElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory SlotElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SlotElement.created() : super.created();
+
+  String name;
+
+  List<Node> assignedNodes([Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return _assignedNodes_1(options_1);
+    }
+    return _assignedNodes_2();
+  }
+
+  @JSName('assignedNodes')
+  List<Node> _assignedNodes_1(options) native;
+  @JSName('assignedNodes')
+  List<Node> _assignedNodes_2() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("SourceBuffer")
+class SourceBuffer extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory SourceBuffer._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> abortEvent =
+      const EventStreamProvider<Event>('abort');
+
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  num appendWindowEnd;
+
+  num appendWindowStart;
+
+  final AudioTrackList audioTracks;
+
+  final TimeRanges buffered;
+
+  String mode;
+
+  num timestampOffset;
+
+  TrackDefaultList trackDefaults;
+
+  final bool updating;
+
+  final VideoTrackList videoTracks;
+
+  void abort() native;
+
+  void appendBuffer(ByteBuffer data) native;
+
+  @JSName('appendBuffer')
+  void appendTypedData(TypedData data) native;
+
+  void remove(num start, num end) native;
+
+  Stream<Event> get onAbort => abortEvent.forTarget(this);
+
+  Stream<Event> get onError => errorEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("SourceBufferList")
+class SourceBufferList extends EventTarget
+    with ListMixin<SourceBuffer>, ImmutableListMixin<SourceBuffer>
+    implements JavaScriptIndexingBehavior<SourceBuffer>, List<SourceBuffer> {
+  // To suppress missing implicit constructor warnings.
+  factory SourceBufferList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  SourceBuffer operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return JS("SourceBuffer", "#[#]", this, index);
+  }
+
+  void operator []=(int index, SourceBuffer value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<SourceBuffer> mixins.
+  // SourceBuffer is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  SourceBuffer get first {
+    if (this.length > 0) {
+      return JS('SourceBuffer', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  SourceBuffer get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('SourceBuffer', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  SourceBuffer get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('SourceBuffer', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  SourceBuffer elementAt(int index) => this[index];
+  // -- end List<SourceBuffer> mixins.
+
+  SourceBuffer item(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("HTMLSourceElement")
+class SourceElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory SourceElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory SourceElement() => JS(
+      'returns:SourceElement;creates:SourceElement;new:true',
+      '#.createElement(#)',
+      document,
+      "source");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SourceElement.created() : super.created();
+
+  String media;
+
+  String sizes;
+
+  String src;
+
+  String srcset;
+
+  String type;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("HTMLSpanElement")
+class SpanElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory SpanElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory SpanElement() => JS(
+      'returns:SpanElement;creates:SpanElement;new:true',
+      '#.createElement(#)',
+      document,
+      "span");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SpanElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Native("SpeechGrammar")
+class SpeechGrammar extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory SpeechGrammar._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory SpeechGrammar() {
+    return SpeechGrammar._create_1();
+  }
+  static SpeechGrammar _create_1() =>
+      JS('SpeechGrammar', 'new SpeechGrammar()');
+
+  String src;
+
+  num weight;
+}
+// Copyright (c) 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.
+
+@Native("SpeechGrammarList")
+class SpeechGrammarList extends Interceptor
+    with ListMixin<SpeechGrammar>, ImmutableListMixin<SpeechGrammar>
+    implements JavaScriptIndexingBehavior<SpeechGrammar>, List<SpeechGrammar> {
+  // To suppress missing implicit constructor warnings.
+  factory SpeechGrammarList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory SpeechGrammarList() {
+    return SpeechGrammarList._create_1();
+  }
+  static SpeechGrammarList _create_1() =>
+      JS('SpeechGrammarList', 'new SpeechGrammarList()');
+
+  int get length => JS("int", "#.length", this);
+
+  SpeechGrammar operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return JS("SpeechGrammar", "#[#]", this, index);
+  }
+
+  void operator []=(int index, SpeechGrammar value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<SpeechGrammar> mixins.
+  // SpeechGrammar is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  SpeechGrammar get first {
+    if (this.length > 0) {
+      return JS('SpeechGrammar', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  SpeechGrammar get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('SpeechGrammar', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  SpeechGrammar get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('SpeechGrammar', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  SpeechGrammar elementAt(int index) => this[index];
+  // -- end List<SpeechGrammar> mixins.
+
+  void addFromString(String string, [num weight]) native;
+
+  void addFromUri(String src, [num weight]) native;
+
+  SpeechGrammar item(int index) native;
+}
+// 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Native("SpeechRecognition")
+class SpeechRecognition extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory SpeechRecognition._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `audioend` events to event
+   * handlers that are not necessarily instances of [SpeechRecognition].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> audioEndEvent =
+      const EventStreamProvider<Event>('audioend');
+
+  /**
+   * Static factory designed to expose `audiostart` events to event
+   * handlers that are not necessarily instances of [SpeechRecognition].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> audioStartEvent =
+      const EventStreamProvider<Event>('audiostart');
+
+  /**
+   * Static factory designed to expose `end` events to event
+   * handlers that are not necessarily instances of [SpeechRecognition].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> endEvent =
+      const EventStreamProvider<Event>('end');
+
+  /**
+   * Static factory designed to expose `error` events to event
+   * handlers that are not necessarily instances of [SpeechRecognition].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<SpeechRecognitionError> errorEvent =
+      const EventStreamProvider<SpeechRecognitionError>('error');
+
+  /**
+   * Static factory designed to expose `nomatch` events to event
+   * handlers that are not necessarily instances of [SpeechRecognition].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<SpeechRecognitionEvent> noMatchEvent =
+      const EventStreamProvider<SpeechRecognitionEvent>('nomatch');
+
+  /**
+   * Static factory designed to expose `result` events to event
+   * handlers that are not necessarily instances of [SpeechRecognition].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<SpeechRecognitionEvent> resultEvent =
+      const EventStreamProvider<SpeechRecognitionEvent>('result');
+
+  /**
+   * Static factory designed to expose `soundend` events to event
+   * handlers that are not necessarily instances of [SpeechRecognition].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> soundEndEvent =
+      const EventStreamProvider<Event>('soundend');
+
+  /**
+   * Static factory designed to expose `soundstart` events to event
+   * handlers that are not necessarily instances of [SpeechRecognition].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> soundStartEvent =
+      const EventStreamProvider<Event>('soundstart');
+
+  /**
+   * Static factory designed to expose `speechend` events to event
+   * handlers that are not necessarily instances of [SpeechRecognition].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> speechEndEvent =
+      const EventStreamProvider<Event>('speechend');
+
+  /**
+   * Static factory designed to expose `speechstart` events to event
+   * handlers that are not necessarily instances of [SpeechRecognition].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> speechStartEvent =
+      const EventStreamProvider<Event>('speechstart');
+
+  /**
+   * Static factory designed to expose `start` events to event
+   * handlers that are not necessarily instances of [SpeechRecognition].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> startEvent =
+      const EventStreamProvider<Event>('start');
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS(
+      'bool', '!!(window.SpeechRecognition || window.webkitSpeechRecognition)');
+
+  MediaStreamTrack audioTrack;
+
+  bool continuous;
+
+  SpeechGrammarList grammars;
+
+  bool interimResults;
+
+  String lang;
+
+  int maxAlternatives;
+
+  void abort() native;
+
+  void start() native;
+
+  void stop() native;
+
+  /// Stream of `audioend` events handled by this [SpeechRecognition].
+  Stream<Event> get onAudioEnd => audioEndEvent.forTarget(this);
+
+  /// Stream of `audiostart` events handled by this [SpeechRecognition].
+  Stream<Event> get onAudioStart => audioStartEvent.forTarget(this);
+
+  /// Stream of `end` events handled by this [SpeechRecognition].
+  Stream<Event> get onEnd => endEvent.forTarget(this);
+
+  /// Stream of `error` events handled by this [SpeechRecognition].
+  Stream<SpeechRecognitionError> get onError => errorEvent.forTarget(this);
+
+  /// Stream of `nomatch` events handled by this [SpeechRecognition].
+  Stream<SpeechRecognitionEvent> get onNoMatch => noMatchEvent.forTarget(this);
+
+  /// Stream of `result` events handled by this [SpeechRecognition].
+  Stream<SpeechRecognitionEvent> get onResult => resultEvent.forTarget(this);
+
+  /// Stream of `soundend` events handled by this [SpeechRecognition].
+  Stream<Event> get onSoundEnd => soundEndEvent.forTarget(this);
+
+  /// Stream of `soundstart` events handled by this [SpeechRecognition].
+  Stream<Event> get onSoundStart => soundStartEvent.forTarget(this);
+
+  /// Stream of `speechend` events handled by this [SpeechRecognition].
+  Stream<Event> get onSpeechEnd => speechEndEvent.forTarget(this);
+
+  /// Stream of `speechstart` events handled by this [SpeechRecognition].
+  Stream<Event> get onSpeechStart => speechStartEvent.forTarget(this);
+
+  /// Stream of `start` events handled by this [SpeechRecognition].
+  Stream<Event> get onStart => startEvent.forTarget(this);
+
+  factory SpeechRecognition() {
+    return JS('SpeechRecognition',
+        'new (window.SpeechRecognition || window.webkitSpeechRecognition)()');
+  }
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Native("SpeechRecognitionAlternative")
+class SpeechRecognitionAlternative extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory SpeechRecognitionAlternative._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num confidence;
+
+  final String transcript;
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Native("SpeechRecognitionError")
+class SpeechRecognitionError extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory SpeechRecognitionError._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory SpeechRecognitionError(String type, [Map initDict]) {
+    if (initDict != null) {
+      var initDict_1 = convertDartToNative_Dictionary(initDict);
+      return SpeechRecognitionError._create_1(type, initDict_1);
+    }
+    return SpeechRecognitionError._create_2(type);
+  }
+  static SpeechRecognitionError _create_1(type, initDict) => JS(
+      'SpeechRecognitionError',
+      'new SpeechRecognitionError(#,#)',
+      type,
+      initDict);
+  static SpeechRecognitionError _create_2(type) =>
+      JS('SpeechRecognitionError', 'new SpeechRecognitionError(#)', type);
+
+  final String error;
+
+  final String message;
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Native("SpeechRecognitionEvent")
+class SpeechRecognitionEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory SpeechRecognitionEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory SpeechRecognitionEvent(String type, [Map initDict]) {
+    if (initDict != null) {
+      var initDict_1 = convertDartToNative_Dictionary(initDict);
+      return SpeechRecognitionEvent._create_1(type, initDict_1);
+    }
+    return SpeechRecognitionEvent._create_2(type);
+  }
+  static SpeechRecognitionEvent _create_1(type, initDict) => JS(
+      'SpeechRecognitionEvent',
+      'new SpeechRecognitionEvent(#,#)',
+      type,
+      initDict);
+  static SpeechRecognitionEvent _create_2(type) =>
+      JS('SpeechRecognitionEvent', 'new SpeechRecognitionEvent(#)', type);
+
+  final Document emma;
+
+  final Document interpretation;
+
+  final int resultIndex;
+
+  @Returns('_SpeechRecognitionResultList|Null')
+  @Creates('_SpeechRecognitionResultList')
+  final List<SpeechRecognitionResult> results;
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME, '25')
+@Native("SpeechRecognitionResult")
+class SpeechRecognitionResult extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory SpeechRecognitionResult._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool isFinal;
+
+  final int length;
+
+  SpeechRecognitionAlternative item(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("SpeechSynthesis")
+class SpeechSynthesis extends EventTarget {
+  List<SpeechSynthesisVoice> getVoices() {
+    List<SpeechSynthesisVoice> voices = _getVoices();
+    if (voices.length > 0) applyExtension('SpeechSynthesisVoice', voices[0]);
+    return voices;
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory SpeechSynthesis._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool paused;
+
+  final bool pending;
+
+  final bool speaking;
+
+  void cancel() native;
+
+  @JSName('getVoices')
+  List<SpeechSynthesisVoice> _getVoices() native;
+
+  void pause() native;
+
+  void resume() native;
+
+  void speak(SpeechSynthesisUtterance utterance) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("SpeechSynthesisEvent")
+class SpeechSynthesisEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory SpeechSynthesisEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int charIndex;
+
+  final num elapsedTime;
+
+  final String name;
+
+  final SpeechSynthesisUtterance utterance;
+}
+// Copyright (c) 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.
+
+@Native("SpeechSynthesisUtterance")
+class SpeechSynthesisUtterance extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory SpeechSynthesisUtterance._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `boundary` events to event
+   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<SpeechSynthesisEvent> boundaryEvent =
+      const EventStreamProvider<SpeechSynthesisEvent>('boundary');
+
+  /**
+   * Static factory designed to expose `end` events to event
+   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<SpeechSynthesisEvent> endEvent =
+      const EventStreamProvider<SpeechSynthesisEvent>('end');
+
+  /**
+   * Static factory designed to expose `error` events to event
+   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  /**
+   * Static factory designed to expose `mark` events to event
+   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<SpeechSynthesisEvent> markEvent =
+      const EventStreamProvider<SpeechSynthesisEvent>('mark');
+
+  /**
+   * Static factory designed to expose `pause` events to event
+   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> pauseEvent =
+      const EventStreamProvider<Event>('pause');
+
+  /**
+   * Static factory designed to expose `resume` events to event
+   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<SpeechSynthesisEvent> resumeEvent =
+      const EventStreamProvider<SpeechSynthesisEvent>('resume');
+
+  /**
+   * Static factory designed to expose `start` events to event
+   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<SpeechSynthesisEvent> startEvent =
+      const EventStreamProvider<SpeechSynthesisEvent>('start');
+
+  factory SpeechSynthesisUtterance([String text]) {
+    if (text != null) {
+      return SpeechSynthesisUtterance._create_1(text);
+    }
+    return SpeechSynthesisUtterance._create_2();
+  }
+  static SpeechSynthesisUtterance _create_1(text) =>
+      JS('SpeechSynthesisUtterance', 'new SpeechSynthesisUtterance(#)', text);
+  static SpeechSynthesisUtterance _create_2() =>
+      JS('SpeechSynthesisUtterance', 'new SpeechSynthesisUtterance()');
+
+  String lang;
+
+  num pitch;
+
+  num rate;
+
+  String text;
+
+  SpeechSynthesisVoice voice;
+
+  num volume;
+
+  /// Stream of `boundary` events handled by this [SpeechSynthesisUtterance].
+  Stream<SpeechSynthesisEvent> get onBoundary => boundaryEvent.forTarget(this);
+
+  /// Stream of `end` events handled by this [SpeechSynthesisUtterance].
+  Stream<SpeechSynthesisEvent> get onEnd => endEvent.forTarget(this);
+
+  /// Stream of `error` events handled by this [SpeechSynthesisUtterance].
+  Stream<Event> get onError => errorEvent.forTarget(this);
+
+  /// Stream of `mark` events handled by this [SpeechSynthesisUtterance].
+  Stream<SpeechSynthesisEvent> get onMark => markEvent.forTarget(this);
+
+  /// Stream of `pause` events handled by this [SpeechSynthesisUtterance].
+  Stream<Event> get onPause => pauseEvent.forTarget(this);
+
+  /// Stream of `resume` events handled by this [SpeechSynthesisUtterance].
+  Stream<SpeechSynthesisEvent> get onResume => resumeEvent.forTarget(this);
+
+  /// Stream of `start` events handled by this [SpeechSynthesisUtterance].
+  Stream<SpeechSynthesisEvent> get onStart => startEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("SpeechSynthesisVoice")
+class SpeechSynthesisVoice extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory SpeechSynthesisVoice._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('default')
+  final bool defaultValue;
+
+  final String lang;
+
+  final bool localService;
+
+  final String name;
+
+  @JSName('voiceURI')
+  final String voiceUri;
+}
+// Copyright (c) 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.
+
+@Native("StaticRange")
+class StaticRange extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory StaticRange._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool collapsed;
+
+  final Node endContainer;
+
+  final int endOffset;
+
+  final Node startContainer;
+
+  final int startOffset;
+}
+// Copyright (c) 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.
+
+/**
+ * The type used by the
+ * [Window.localStorage] and [Window.sessionStorage] properties.
+ * Storage is implemented as a Map&lt;String, String>.
+ *
+ * To store and get values, use Dart's built-in map syntax:
+ *
+ *     window.localStorage['key1'] = 'val1';
+ *     window.localStorage['key2'] = 'val2';
+ *     window.localStorage['key3'] = 'val3';
+ *     assert(window.localStorage['key3'] == 'val3');
+ *
+ * You can use [Map](http://api.dartlang.org/dart_core/Map.html) APIs
+ * such as containsValue(), clear(), and length:
+ *
+ *     assert(window.localStorage.containsValue('does not exist') == false);
+ *     window.localStorage.clear();
+ *     assert(window.localStorage.length == 0);
+ *
+ * For more examples of using this API, see
+ * [localstorage_test.dart](http://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/tests/html/localstorage_test.dart).
+ * For details on using the Map API, see the
+ * [Maps](https://www.dartlang.org/guides/libraries/library-tour#maps)
+ * section of the library tour.
+ */
+@Unstable()
+@Native("Storage")
+class Storage extends Interceptor with MapMixin<String, String> {
+  void addAll(Map<String, String> other) {
+    other.forEach((k, v) {
+      this[k] = v;
+    });
+  }
+
+  // TODO(nweiz): update this when maps support lazy iteration
+  bool containsValue(Object value) => values.any((e) => e == value);
+
+  bool containsKey(Object key) => _getItem(key) != null;
+
+  String operator [](Object key) => _getItem(key);
+
+  void operator []=(String key, String value) {
+    _setItem(key, value);
+  }
+
+  String putIfAbsent(String key, String ifAbsent()) {
+    if (!containsKey(key)) this[key] = ifAbsent();
+    return this[key];
+  }
+
+  String remove(Object key) {
+    final value = this[key];
+    _removeItem(key);
+    return value;
+  }
+
+  void clear() => _clear();
+
+  void forEach(void f(String key, String value)) {
+    for (var i = 0; true; i++) {
+      final key = _key(i);
+      if (key == null) return;
+
+      f(key, this[key]);
+    }
+  }
+
+  Iterable<String> get keys {
+    final keys = <String>[];
+    forEach((k, v) => keys.add(k));
+    return keys;
+  }
+
+  Iterable<String> get values {
+    final values = <String>[];
+    forEach((k, v) => values.add(v));
+    return values;
+  }
+
+  int get length => _length;
+
+  bool get isEmpty => _key(0) == null;
+
+  bool get isNotEmpty => !isEmpty;
+  // To suppress missing implicit constructor warnings.
+  factory Storage._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('length')
+  final int _length;
+
+  @JSName('clear')
+  void _clear() native;
+
+  @JSName('getItem')
+  String _getItem(String key) native;
+
+  @JSName('key')
+  String _key(int index) native;
+
+  @JSName('removeItem')
+  void _removeItem(String key) native;
+
+  @JSName('setItem')
+  void _setItem(String key, String value) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void StorageErrorCallback(DomError error);
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@Unstable()
+@Native("StorageEvent")
+class StorageEvent extends Event {
+  factory StorageEvent(String type,
+      {bool canBubble: false,
+      bool cancelable: false,
+      String key,
+      String oldValue,
+      String newValue,
+      String url,
+      Storage storageArea}) {
+    StorageEvent e = document._createEvent("StorageEvent");
+    e._initStorageEvent(
+        type, canBubble, cancelable, key, oldValue, newValue, url, storageArea);
+    return e;
+  }
+
+  factory StorageEvent._(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return StorageEvent._create_1(type, eventInitDict_1);
+    }
+    return StorageEvent._create_2(type);
+  }
+  static StorageEvent _create_1(type, eventInitDict) =>
+      JS('StorageEvent', 'new StorageEvent(#,#)', type, eventInitDict);
+  static StorageEvent _create_2(type) =>
+      JS('StorageEvent', 'new StorageEvent(#)', type);
+
+  final String key;
+
+  final String newValue;
+
+  final String oldValue;
+
+  final Storage storageArea;
+
+  final String url;
+
+  @JSName('initStorageEvent')
+  void _initStorageEvent(
+      String typeArg,
+      bool canBubbleArg,
+      bool cancelableArg,
+      String keyArg,
+      String oldValueArg,
+      String newValueArg,
+      String urlArg,
+      Storage storageAreaArg) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("StorageManager")
+class StorageManager extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory StorageManager._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Future<Map<String, dynamic>> estimate() =>
+      promiseToFutureAsMap(JS("", "#.estimate()", this));
+
+  Future<bool> persist() => promiseToFuture<bool>(JS("", "#.persist()", this));
+
+  Future<bool> persisted() =>
+      promiseToFuture<bool>(JS("", "#.persisted()", this));
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void StorageQuotaCallback(int grantedQuotaInBytes);
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void StorageUsageCallback(
+    int currentUsageInBytes, int currentQuotaInBytes);
+// Copyright (c) 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.
+
+@Native("HTMLStyleElement")
+class StyleElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory StyleElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory StyleElement() => JS(
+      'returns:StyleElement;creates:StyleElement;new:true',
+      '#.createElement(#)',
+      document,
+      "style");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  StyleElement.created() : super.created();
+
+  bool disabled;
+
+  String media;
+
+  final StyleSheet sheet;
+
+  String type;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("StyleMedia")
+class StyleMedia extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory StyleMedia._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String type;
+
+  bool matchMedium(String mediaquery) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("StylePropertyMap")
+class StylePropertyMap extends StylePropertyMapReadonly {
+  // To suppress missing implicit constructor warnings.
+  factory StylePropertyMap._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  void append(String property, Object value) native;
+
+  void delete(String property) native;
+
+  void set(String property, Object value) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("StylePropertyMapReadonly")
+class StylePropertyMapReadonly extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory StylePropertyMapReadonly._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  CssStyleValue get(String property) native;
+
+  List<CssStyleValue> getAll(String property) native;
+
+  List<String> getProperties() native;
+
+  bool has(String property) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("StyleSheet")
+class StyleSheet extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory StyleSheet._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  bool disabled;
+
+  final String href;
+
+  final MediaList media;
+
+  final Node ownerNode;
+
+  final StyleSheet parentStyleSheet;
+
+  final String title;
+
+  final String type;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("SyncEvent")
+class SyncEvent extends ExtendableEvent {
+  // To suppress missing implicit constructor warnings.
+  factory SyncEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory SyncEvent(String type, Map init) {
+    var init_1 = convertDartToNative_Dictionary(init);
+    return SyncEvent._create_1(type, init_1);
+  }
+  static SyncEvent _create_1(type, init) =>
+      JS('SyncEvent', 'new SyncEvent(#,#)', type, init);
+
+  final bool lastChance;
+
+  final String tag;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("SyncManager")
+class SyncManager extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory SyncManager._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Future<List<String>> getTags() =>
+      promiseToFuture<List<String>>(JS("", "#.getTags()", this));
+
+  Future register(String tag) =>
+      promiseToFuture(JS("", "#.register(#)", this, tag));
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("HTMLTableCaptionElement")
+class TableCaptionElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory TableCaptionElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory TableCaptionElement() => JS(
+      'returns:TableCaptionElement;creates:TableCaptionElement;new:true',
+      '#.createElement(#)',
+      document,
+      "caption");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TableCaptionElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Native(
+    "HTMLTableCellElement,HTMLTableDataCellElement,HTMLTableHeaderCellElement")
+class TableCellElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory TableCellElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory TableCellElement() => JS(
+      'returns:TableCellElement;creates:TableCellElement;new:true',
+      '#.createElement(#)',
+      document,
+      "td");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TableCellElement.created() : super.created();
+
+  final int cellIndex;
+
+  int colSpan;
+
+  String headers;
+
+  int rowSpan;
+}
+// Copyright (c) 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.
+
+@Native("HTMLTableColElement")
+class TableColElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory TableColElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory TableColElement() => JS(
+      'returns:TableColElement;creates:TableColElement;new:true',
+      '#.createElement(#)',
+      document,
+      "col");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TableColElement.created() : super.created();
+
+  int span;
+}
+// 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.
+
+@Native("HTMLTableElement")
+class TableElement extends HtmlElement {
+  List<TableSectionElement> get tBodies =>
+      new _WrappedList<TableSectionElement>(_tBodies);
+
+  List<TableRowElement> get rows => new _WrappedList<TableRowElement>(_rows);
+
+  TableRowElement addRow() {
+    return insertRow(-1);
+  }
+
+  TableCaptionElement createCaption() => _createCaption();
+  TableSectionElement createTBody() => _createTBody();
+  TableSectionElement createTFoot() => _createTFoot();
+  TableSectionElement createTHead() => _createTHead();
+  TableRowElement insertRow(int index) => _insertRow(index);
+
+  TableSectionElement _createTBody() {
+    if (JS('bool', '!!#.createTBody', this)) {
+      return this._nativeCreateTBody();
+    }
+    var tbody = new Element.tag('tbody');
+    this.children.add(tbody);
+    return tbody;
+  }
+
+  @JSName('createTBody')
+  TableSectionElement _nativeCreateTBody() native;
+
+  DocumentFragment createFragment(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    if (Range.supportsCreateContextualFragment) {
+      return super.createFragment(html,
+          validator: validator, treeSanitizer: treeSanitizer);
+    }
+    // IE9 workaround which does not support innerHTML on Table elements.
+    var contextualHtml = '<table>$html</table>';
+    var table = new Element.html(contextualHtml,
+        validator: validator, treeSanitizer: treeSanitizer);
+    var fragment = new DocumentFragment();
+    fragment.nodes.addAll(table.nodes);
+
+    return fragment;
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory TableElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory TableElement() => JS(
+      'returns:TableElement;creates:TableElement;new:true',
+      '#.createElement(#)',
+      document,
+      "table");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TableElement.created() : super.created();
+
+  TableCaptionElement caption;
+
+  @JSName('rows')
+  @Returns('HtmlCollection|Null')
+  @Creates('HtmlCollection')
+  final List<Node> _rows;
+
+  @JSName('tBodies')
+  @Returns('HtmlCollection|Null')
+  @Creates('HtmlCollection')
+  final List<Node> _tBodies;
+
+  TableSectionElement tFoot;
+
+  TableSectionElement tHead;
+
+  @JSName('createCaption')
+  TableCaptionElement _createCaption() native;
+
+  @JSName('createTFoot')
+  TableSectionElement _createTFoot() native;
+
+  @JSName('createTHead')
+  TableSectionElement _createTHead() native;
+
+  void deleteCaption() native;
+
+  void deleteRow(int index) native;
+
+  void deleteTFoot() native;
+
+  void deleteTHead() native;
+
+  @JSName('insertRow')
+  TableRowElement _insertRow([int index]) native;
+}
+// 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.
+
+@Native("HTMLTableRowElement")
+class TableRowElement extends HtmlElement {
+  List<TableCellElement> get cells =>
+      new _WrappedList<TableCellElement>(_cells);
+
+  TableCellElement addCell() {
+    return insertCell(-1);
+  }
+
+  TableCellElement insertCell(int index) => _insertCell(index);
+
+  DocumentFragment createFragment(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    if (Range.supportsCreateContextualFragment) {
+      return super.createFragment(html,
+          validator: validator, treeSanitizer: treeSanitizer);
+    }
+    // IE9 workaround which does not support innerHTML on Table elements.
+    var fragment = new DocumentFragment();
+    var section = new TableElement()
+        .createFragment(html,
+            validator: validator, treeSanitizer: treeSanitizer)
+        .nodes
+        .single;
+    var row = section.nodes.single;
+    fragment.nodes.addAll(row.nodes);
+    return fragment;
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory TableRowElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory TableRowElement() => JS(
+      'returns:TableRowElement;creates:TableRowElement;new:true',
+      '#.createElement(#)',
+      document,
+      "tr");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TableRowElement.created() : super.created();
+
+  @JSName('cells')
+  @Returns('HtmlCollection|Null')
+  @Creates('HtmlCollection')
+  final List<Node> _cells;
+
+  final int rowIndex;
+
+  final int sectionRowIndex;
+
+  void deleteCell(int index) native;
+
+  @JSName('insertCell')
+  HtmlElement _insertCell([int index]) native;
+}
+// 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.
+
+@Native("HTMLTableSectionElement")
+class TableSectionElement extends HtmlElement {
+  List<TableRowElement> get rows => new _WrappedList<TableRowElement>(_rows);
+
+  TableRowElement addRow() {
+    return insertRow(-1);
+  }
+
+  TableRowElement insertRow(int index) => _insertRow(index);
+
+  DocumentFragment createFragment(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    if (Range.supportsCreateContextualFragment) {
+      return super.createFragment(html,
+          validator: validator, treeSanitizer: treeSanitizer);
+    }
+    // IE9 workaround which does not support innerHTML on Table elements.
+    var fragment = new DocumentFragment();
+    var section = new TableElement()
+        .createFragment(html,
+            validator: validator, treeSanitizer: treeSanitizer)
+        .nodes
+        .single;
+    fragment.nodes.addAll(section.nodes);
+    return fragment;
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory TableSectionElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TableSectionElement.created() : super.created();
+
+  @JSName('rows')
+  @Returns('HtmlCollection|Null')
+  @Creates('HtmlCollection')
+  final List<Node> _rows;
+
+  void deleteRow(int index) native;
+
+  @JSName('insertRow')
+  HtmlElement _insertRow([int index]) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("TaskAttributionTiming")
+class TaskAttributionTiming extends PerformanceEntry {
+  // To suppress missing implicit constructor warnings.
+  factory TaskAttributionTiming._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String containerId;
+
+  final String containerName;
+
+  final String containerSrc;
+
+  final String containerType;
+
+  @JSName('scriptURL')
+  final String scriptUrl;
+}
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@Native("HTMLTemplateElement")
+class TemplateElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory TemplateElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory TemplateElement() => document.createElement("template");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TemplateElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => Element.isTagSupported('template');
+
+  final DocumentFragment content;
+
+  /**
+   * An override to place the contents into content rather than as child nodes.
+   *
+   * See also:
+   *
+   * * <https://w3c.github.io/DOM-Parsing/#the-innerhtml-mixin>
+   */
+  void setInnerHtml(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    text = null;
+    content.nodes.clear();
+    var fragment = createFragment(html,
+        validator: validator, treeSanitizer: treeSanitizer);
+
+    content.append(fragment);
+  }
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@Native("Text")
+class Text extends CharacterData {
+  factory Text(String data) => JS(
+      'returns:Text;depends:none;effects:none;new:true',
+      '#.createTextNode(#)',
+      document,
+      data);
+  // To suppress missing implicit constructor warnings.
+  factory Text._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final SlotElement assignedSlot;
+
+  final String wholeText;
+
+  @Returns('NodeList|Null')
+  @Creates('NodeList')
+  List<Node> getDestinationInsertionPoints() native;
+
+  Text splitText(int offset) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("HTMLTextAreaElement")
+class TextAreaElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory TextAreaElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory TextAreaElement() => JS(
+      'returns:TextAreaElement;creates:TextAreaElement;new:true',
+      '#.createElement(#)',
+      document,
+      "textarea");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TextAreaElement.created() : super.created();
+
+  String autocapitalize;
+
+  bool autofocus;
+
+  int cols;
+
+  String defaultValue;
+
+  String dirName;
+
+  bool disabled;
+
+  final FormElement form;
+
+  @Unstable()
+  @Returns('NodeList|Null')
+  @Creates('NodeList')
+  final List<Node> labels;
+
+  int maxLength;
+
+  int minLength;
+
+  String name;
+
+  String placeholder;
+
+  bool readOnly;
+
+  bool required;
+
+  int rows;
+
+  String selectionDirection;
+
+  int selectionEnd;
+
+  int selectionStart;
+
+  final int textLength;
+
+  final String type;
+
+  final String validationMessage;
+
+  final ValidityState validity;
+
+  String value;
+
+  final bool willValidate;
+
+  String wrap;
+
+  bool checkValidity() native;
+
+  bool reportValidity() native;
+
+  void select() native;
+
+  void setCustomValidity(String error) native;
+
+  void setRangeText(String replacement,
+      {int start, int end, String selectionMode}) native;
+
+  void setSelectionRange(int start, int end, [String direction]) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("TextDetector")
+class TextDetector extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory TextDetector._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory TextDetector() {
+    return TextDetector._create_1();
+  }
+  static TextDetector _create_1() => JS('TextDetector', 'new TextDetector()');
+
+  Future<List<DetectedText>> detect(/*ImageBitmapSource*/ image) =>
+      promiseToFuture<List<DetectedText>>(JS("", "#.detect(#)", this, image));
+}
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@Unstable()
+@Native("TextEvent")
+class TextEvent extends UIEvent {
+  factory TextEvent(String type,
+      {bool canBubble: false,
+      bool cancelable: false,
+      Window view,
+      String data}) {
+    if (view == null) {
+      view = window;
+    }
+    TextEvent e = document._createEvent("TextEvent");
+    e._initTextEvent(type, canBubble, cancelable, view, data);
+    return e;
+  }
+  // To suppress missing implicit constructor warnings.
+  factory TextEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String data;
+
+  @JSName('initTextEvent')
+  void _initTextEvent(String type, bool bubbles, bool cancelable, Window view,
+      String data) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("TextMetrics")
+class TextMetrics extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory TextMetrics._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num actualBoundingBoxAscent;
+
+  final num actualBoundingBoxDescent;
+
+  final num actualBoundingBoxLeft;
+
+  final num actualBoundingBoxRight;
+
+  final num alphabeticBaseline;
+
+  final num emHeightAscent;
+
+  final num emHeightDescent;
+
+  final num fontBoundingBoxAscent;
+
+  final num fontBoundingBoxDescent;
+
+  final num hangingBaseline;
+
+  final num ideographicBaseline;
+
+  final num width;
+}
+// Copyright (c) 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.
+
+@Native("TextTrack")
+class TextTrack extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory TextTrack._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `cuechange` events to event
+   * handlers that are not necessarily instances of [TextTrack].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> cueChangeEvent =
+      const EventStreamProvider<Event>('cuechange');
+
+  final TextTrackCueList activeCues;
+
+  final TextTrackCueList cues;
+
+  final String id;
+
+  final String kind;
+
+  final String label;
+
+  final String language;
+
+  String mode;
+
+  void addCue(TextTrackCue cue) native;
+
+  void removeCue(TextTrackCue cue) native;
+
+  /// Stream of `cuechange` events handled by this [TextTrack].
+  Stream<Event> get onCueChange => cueChangeEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("TextTrackCue")
+class TextTrackCue extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory TextTrackCue._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `enter` events to event
+   * handlers that are not necessarily instances of [TextTrackCue].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> enterEvent =
+      const EventStreamProvider<Event>('enter');
+
+  /**
+   * Static factory designed to expose `exit` events to event
+   * handlers that are not necessarily instances of [TextTrackCue].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> exitEvent =
+      const EventStreamProvider<Event>('exit');
+
+  num endTime;
+
+  String id;
+
+  bool pauseOnExit;
+
+  num startTime;
+
+  final TextTrack track;
+
+  /// Stream of `enter` events handled by this [TextTrackCue].
+  Stream<Event> get onEnter => enterEvent.forTarget(this);
+
+  /// Stream of `exit` events handled by this [TextTrackCue].
+  Stream<Event> get onExit => exitEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("TextTrackCueList")
+class TextTrackCueList extends Interceptor
+    with ListMixin<TextTrackCue>, ImmutableListMixin<TextTrackCue>
+    implements List<TextTrackCue>, JavaScriptIndexingBehavior<TextTrackCue> {
+  // To suppress missing implicit constructor warnings.
+  factory TextTrackCueList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  TextTrackCue operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return JS("TextTrackCue", "#[#]", this, index);
+  }
+
+  void operator []=(int index, TextTrackCue value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<TextTrackCue> mixins.
+  // TextTrackCue is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  TextTrackCue get first {
+    if (this.length > 0) {
+      return JS('TextTrackCue', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  TextTrackCue get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('TextTrackCue', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  TextTrackCue get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('TextTrackCue', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  TextTrackCue elementAt(int index) => this[index];
+  // -- end List<TextTrackCue> mixins.
+
+  TextTrackCue __getter__(int index) native;
+
+  TextTrackCue getCueById(String id) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("TextTrackList")
+class TextTrackList extends EventTarget
+    with ListMixin<TextTrack>, ImmutableListMixin<TextTrack>
+    implements List<TextTrack>, JavaScriptIndexingBehavior<TextTrack> {
+  // To suppress missing implicit constructor warnings.
+  factory TextTrackList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `addtrack` events to event
+   * handlers that are not necessarily instances of [TextTrackList].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<TrackEvent> addTrackEvent =
+      const EventStreamProvider<TrackEvent>('addtrack');
+
+  static const EventStreamProvider<Event> changeEvent =
+      const EventStreamProvider<Event>('change');
+
+  int get length => JS("int", "#.length", this);
+
+  TextTrack operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return JS("TextTrack", "#[#]", this, index);
+  }
+
+  void operator []=(int index, TextTrack value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<TextTrack> mixins.
+  // TextTrack is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  TextTrack get first {
+    if (this.length > 0) {
+      return JS('TextTrack', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  TextTrack get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('TextTrack', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  TextTrack get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('TextTrack', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  TextTrack elementAt(int index) => this[index];
+  // -- end List<TextTrack> mixins.
+
+  TextTrack __getter__(int index) native;
+
+  TextTrack getTrackById(String id) native;
+
+  /// Stream of `addtrack` events handled by this [TextTrackList].
+  Stream<TrackEvent> get onAddTrack => addTrackEvent.forTarget(this);
+
+  Stream<Event> get onChange => changeEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("HTMLTimeElement")
+class TimeElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory TimeElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TimeElement.created() : super.created();
+
+  String dateTime;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("TimeRanges")
+class TimeRanges extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory TimeRanges._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int length;
+
+  double end(int index) native;
+
+  double start(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void TimeoutHandler();
+// Copyright (c) 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.
+
+@Native("HTMLTitleElement")
+class TitleElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory TitleElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory TitleElement() => JS(
+      'returns:TitleElement;creates:TitleElement;new:true',
+      '#.createElement(#)',
+      document,
+      "title");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TitleElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Native("Touch")
+class Touch extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Touch._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory Touch(Map initDict) {
+    var initDict_1 = convertDartToNative_Dictionary(initDict);
+    return Touch._create_1(initDict_1);
+  }
+  static Touch _create_1(initDict) => JS('Touch', 'new Touch(#)', initDict);
+
+  @JSName('clientX')
+  final num _clientX;
+
+  @JSName('clientY')
+  final num _clientY;
+
+  final num force;
+
+  final int identifier;
+
+  @JSName('pageX')
+  final num _pageX;
+
+  @JSName('pageY')
+  final num _pageY;
+
+  @JSName('radiusX')
+  final num _radiusX;
+
+  @JSName('radiusY')
+  final num _radiusY;
+
+  final String region;
+
+  final num rotationAngle;
+
+  @JSName('screenX')
+  final num _screenX;
+
+  @JSName('screenY')
+  final num _screenY;
+
+  EventTarget get target => _convertNativeToDart_EventTarget(this._get_target);
+  @JSName('target')
+  @Creates('Element|Document')
+  @Returns('Element|Document')
+  final dynamic _get_target;
+
+// As of Chrome 37, these all changed from long to double.  This code
+// preserves backwards compatibility for the time being.
+  int get __clientX => JS<num>('num', '#.clientX', this).round();
+  int get __clientY => JS<num>('num', '#.clientY', this).round();
+  int get __screenX => JS<num>('num', '#.screenX', this).round();
+  int get __screenY => JS<num>('num', '#.screenY', this).round();
+  int get __pageX => JS<num>('num', '#.pageX', this).round();
+  int get __pageY => JS<num>('num', '#.pageY', this).round();
+  int get __radiusX => JS<num>('num', '#.radiusX', this).round();
+  int get __radiusY => JS<num>('num', '#.radiusY', this).round();
+
+  Point get client => new Point(__clientX, __clientY);
+
+  Point get page => new Point(__pageX, __pageY);
+
+  Point get screen => new Point(__screenX, __screenY);
+
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  int get radiusX => __radiusX;
+
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  int get radiusY => __radiusY;
+}
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@Native("TouchEvent")
+class TouchEvent extends UIEvent {
+  // To suppress missing implicit constructor warnings.
+  factory TouchEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory TouchEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return TouchEvent._create_1(type, eventInitDict_1);
+    }
+    return TouchEvent._create_2(type);
+  }
+  static TouchEvent _create_1(type, eventInitDict) =>
+      JS('TouchEvent', 'new TouchEvent(#,#)', type, eventInitDict);
+  static TouchEvent _create_2(type) =>
+      JS('TouchEvent', 'new TouchEvent(#)', type);
+
+  final bool altKey;
+
+  final TouchList changedTouches;
+
+  final bool ctrlKey;
+
+  final bool metaKey;
+
+  final bool shiftKey;
+
+  final TouchList targetTouches;
+
+  final TouchList touches;
+
+  /**
+   * Checks if touch events supported on the current platform.
+   */
+  static bool get supported {
+    try {
+      return TouchEvent('touches') is TouchEvent;
+    } catch (_) {}
+
+    return false;
+  }
+}
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@Native("TouchList")
+class TouchList extends Interceptor
+    with ListMixin<Touch>, ImmutableListMixin<Touch>
+    implements JavaScriptIndexingBehavior<Touch>, List<Touch> {
+  /// NB: This constructor likely does not work as you might expect it to! This
+  /// constructor will simply fail (returning null) if you are not on a device
+  /// with touch enabled. See dartbug.com/8314.
+  // TODO(5760): createTouchList now uses varargs.
+  factory TouchList() => null; //document._createTouchList();
+  // To suppress missing implicit constructor warnings.
+  factory TouchList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!document.createTouchList');
+
+  int get length => JS("int", "#.length", this);
+
+  Touch operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return JS("Touch", "#[#]", this, index);
+  }
+
+  void operator []=(int index, Touch value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<Touch> mixins.
+  // Touch is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  Touch get first {
+    if (this.length > 0) {
+      return JS('Touch', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  Touch get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('Touch', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  Touch get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('Touch', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  Touch elementAt(int index) => this[index];
+  // -- end List<Touch> mixins.
+
+  Touch item(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("TrackDefault")
+class TrackDefault extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory TrackDefault._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory TrackDefault(
+      String type, String language, String label, List<String> kinds,
+      [String byteStreamTrackID]) {
+    if (byteStreamTrackID != null) {
+      List kinds_1 = convertDartToNative_StringArray(kinds);
+      return TrackDefault._create_1(
+          type, language, label, kinds_1, byteStreamTrackID);
+    }
+    List kinds_1 = convertDartToNative_StringArray(kinds);
+    return TrackDefault._create_2(type, language, label, kinds_1);
+  }
+  static TrackDefault _create_1(
+          type, language, label, kinds, byteStreamTrackID) =>
+      JS('TrackDefault', 'new TrackDefault(#,#,#,#,#)', type, language, label,
+          kinds, byteStreamTrackID);
+  static TrackDefault _create_2(type, language, label, kinds) => JS(
+      'TrackDefault',
+      'new TrackDefault(#,#,#,#)',
+      type,
+      language,
+      label,
+      kinds);
+
+  final String byteStreamTrackID;
+
+  final Object kinds;
+
+  final String label;
+
+  final String language;
+
+  final String type;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("TrackDefaultList")
+class TrackDefaultList extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory TrackDefaultList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory TrackDefaultList([List<TrackDefault> trackDefaults]) {
+    if (trackDefaults != null) {
+      return TrackDefaultList._create_1(trackDefaults);
+    }
+    return TrackDefaultList._create_2();
+  }
+  static TrackDefaultList _create_1(trackDefaults) =>
+      JS('TrackDefaultList', 'new TrackDefaultList(#)', trackDefaults);
+  static TrackDefaultList _create_2() =>
+      JS('TrackDefaultList', 'new TrackDefaultList()');
+
+  final int length;
+
+  TrackDefault item(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Native("HTMLTrackElement")
+class TrackElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory TrackElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory TrackElement() => document.createElement("track");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TrackElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => Element.isTagSupported('track');
+
+  static const int ERROR = 3;
+
+  static const int LOADED = 2;
+
+  static const int LOADING = 1;
+
+  static const int NONE = 0;
+
+  @JSName('default')
+  bool defaultValue;
+
+  String kind;
+
+  String label;
+
+  final int readyState;
+
+  String src;
+
+  String srclang;
+
+  final TextTrack track;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("TrackEvent")
+class TrackEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory TrackEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory TrackEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return TrackEvent._create_1(type, eventInitDict_1);
+    }
+    return TrackEvent._create_2(type);
+  }
+  static TrackEvent _create_1(type, eventInitDict) =>
+      JS('TrackEvent', 'new TrackEvent(#,#)', type, eventInitDict);
+  static TrackEvent _create_2(type) =>
+      JS('TrackEvent', 'new TrackEvent(#)', type);
+
+  @Creates('Null')
+  final Object track;
+}
+// Copyright (c) 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.
+
+@Native("TransitionEvent,WebKitTransitionEvent")
+class TransitionEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory TransitionEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory TransitionEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return TransitionEvent._create_1(type, eventInitDict_1);
+    }
+    return TransitionEvent._create_2(type);
+  }
+  static TransitionEvent _create_1(type, eventInitDict) =>
+      JS('TransitionEvent', 'new TransitionEvent(#,#)', type, eventInitDict);
+  static TransitionEvent _create_2(type) =>
+      JS('TransitionEvent', 'new TransitionEvent(#)', type);
+
+  final num elapsedTime;
+
+  final String propertyName;
+
+  final String pseudoElement;
+}
+// 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.
+
+@Unstable()
+@Native("TreeWalker")
+class TreeWalker extends Interceptor {
+  factory TreeWalker(Node root, int whatToShow) {
+    return document._createTreeWalker(root, whatToShow, null);
+  }
+  // To suppress missing implicit constructor warnings.
+  factory TreeWalker._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Node currentNode;
+
+  final NodeFilter filter;
+
+  final Node root;
+
+  final int whatToShow;
+
+  Node firstChild() native;
+
+  Node lastChild() native;
+
+  Node nextNode() native;
+
+  Node nextSibling() native;
+
+  Node parentNode() native;
+
+  Node previousNode() native;
+
+  Node previousSibling() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("TrustedHTML")
+class TrustedHtml extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory TrustedHtml._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static TrustedHtml escape(String html) native;
+
+  static TrustedHtml unsafelyCreate(String html) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("TrustedScriptURL")
+class TrustedScriptUrl extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory TrustedScriptUrl._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static TrustedScriptUrl unsafelyCreate(String url) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("TrustedURL")
+class TrustedUrl extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory TrustedUrl._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static TrustedUrl create(String url) native;
+
+  static TrustedUrl unsafelyCreate(String url) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+@Native("UIEvent")
+class UIEvent extends Event {
+  // In JS, canBubble and cancelable are technically required parameters to
+  // init*Event. In practice, though, if they aren't provided they simply
+  // default to false (since that's Boolean(undefined)).
+  //
+  // Contrary to JS, we default canBubble and cancelable to true, since that's
+  // what people want most of the time anyway.
+  factory UIEvent(String type,
+      {Window view,
+      int detail: 0,
+      bool canBubble: true,
+      bool cancelable: true}) {
+    if (view == null) {
+      view = window;
+    }
+    UIEvent e = document._createEvent("UIEvent");
+    e._initUIEvent(type, canBubble, cancelable, view, detail);
+    return e;
+  }
+
+  factory UIEvent._(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return UIEvent._create_1(type, eventInitDict_1);
+    }
+    return UIEvent._create_2(type);
+  }
+  static UIEvent _create_1(type, eventInitDict) =>
+      JS('UIEvent', 'new UIEvent(#,#)', type, eventInitDict);
+  static UIEvent _create_2(type) => JS('UIEvent', 'new UIEvent(#)', type);
+
+  final int detail;
+
+  final InputDeviceCapabilities sourceCapabilities;
+
+  WindowBase get view => _convertNativeToDart_Window(this._get_view);
+  @JSName('view')
+  @Creates('Window|=Object')
+  @Returns('Window|=Object')
+  final dynamic _get_view;
+
+  @JSName('which')
+  @Unstable()
+  final int _which;
+
+  @JSName('initUIEvent')
+  void _initUIEvent(String type, bool bubbles, bool cancelable, Window view,
+      int detail) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("HTMLUListElement")
+class UListElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory UListElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory UListElement() => JS(
+      'returns:UListElement;creates:UListElement;new:true',
+      '#.createElement(#)',
+      document,
+      "ul");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  UListElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Native("UnderlyingSourceBase")
+class UnderlyingSourceBase extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory UnderlyingSourceBase._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Future cancel(Object reason) =>
+      promiseToFuture(JS("", "#.cancel(#)", this, reason));
+
+  void notifyLockAcquired() native;
+
+  void notifyLockReleased() native;
+
+  Future pull() => promiseToFuture(JS("", "#.pull()", this));
+
+  Future start(Object stream) =>
+      promiseToFuture(JS("", "#.start(#)", this, stream));
+}
+// Copyright (c) 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.
+
+@Native("HTMLUnknownElement")
+class UnknownElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory UnknownElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  UnknownElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Native("URL")
+class Url extends Interceptor {
+  static String createObjectUrl(blob_OR_source_OR_stream) => JS(
+      'String',
+      '(self.URL || self.webkitURL).createObjectURL(#)',
+      blob_OR_source_OR_stream);
+
+  static String createObjectUrlFromSource(MediaSource source) =>
+      JS('String', '(self.URL || self.webkitURL).createObjectURL(#)', source);
+
+  static String createObjectUrlFromStream(MediaStream stream) =>
+      JS('String', '(self.URL || self.webkitURL).createObjectURL(#)', stream);
+
+  static String createObjectUrlFromBlob(Blob blob) =>
+      JS('String', '(self.URL || self.webkitURL).createObjectURL(#)', blob);
+
+  static void revokeObjectUrl(String url) =>
+      JS('void', '(self.URL || self.webkitURL).revokeObjectURL(#)', url);
+
+  String toString() => JS('String', 'String(#)', this);
+
+  // To suppress missing implicit constructor warnings.
+  factory Url._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  String hash;
+
+  String host;
+
+  String hostname;
+
+  String href;
+
+  final String origin;
+
+  String password;
+
+  String pathname;
+
+  String port;
+
+  String protocol;
+
+  String search;
+
+  final UrlSearchParams searchParams;
+
+  String username;
+}
+// Copyright (c) 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.
+
+@Native("URLSearchParams")
+class UrlSearchParams extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory UrlSearchParams._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory UrlSearchParams([Object init]) {
+    if (init != null) {
+      return UrlSearchParams._create_1(init);
+    }
+    return UrlSearchParams._create_2();
+  }
+  static UrlSearchParams _create_1(init) =>
+      JS('UrlSearchParams', 'new URLSearchParams(#)', init);
+  static UrlSearchParams _create_2() =>
+      JS('UrlSearchParams', 'new URLSearchParams()');
+
+  void append(String name, String value) native;
+
+  void delete(String name) native;
+
+  String get(String name) native;
+
+  List<String> getAll(String name) native;
+
+  bool has(String name) native;
+
+  void set(String name, String value) native;
+
+  void sort() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+abstract class UrlUtilsReadOnly extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory UrlUtilsReadOnly._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String hash;
+
+  final String host;
+
+  final String hostname;
+
+  final String href;
+
+  final String origin;
+
+  final String pathname;
+
+  final String port;
+
+  final String protocol;
+
+  final String search;
+}
+// Copyright (c) 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.
+
+@Native("VR")
+class VR extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory VR._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Future getDevices() => promiseToFuture(JS("", "#.getDevices()", this));
+}
+// Copyright (c) 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.
+
+@Native("VRCoordinateSystem")
+class VRCoordinateSystem extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory VRCoordinateSystem._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Float32List getTransformTo(VRCoordinateSystem other) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("VRDevice")
+class VRDevice extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory VRDevice._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String deviceName;
+
+  final bool isExternal;
+
+  Future requestSession([Map options]) {
+    var options_dict = null;
+    if (options != null) {
+      options_dict = convertDartToNative_Dictionary(options);
+    }
+    return promiseToFuture(JS("", "#.requestSession(#)", this, options_dict));
+  }
+
+  Future supportsSession([Map options]) {
+    var options_dict = null;
+    if (options != null) {
+      options_dict = convertDartToNative_Dictionary(options);
+    }
+    return promiseToFuture(JS("", "#.supportsSession(#)", this, options_dict));
+  }
+}
+// Copyright (c) 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.
+
+@Native("VRDeviceEvent")
+class VRDeviceEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory VRDeviceEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory VRDeviceEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return VRDeviceEvent._create_1(type, eventInitDict_1);
+  }
+  static VRDeviceEvent _create_1(type, eventInitDict) =>
+      JS('VRDeviceEvent', 'new VRDeviceEvent(#,#)', type, eventInitDict);
+
+  final VRDevice device;
+}
+// Copyright (c) 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.
+
+@Native("VRDisplay")
+class VRDisplay extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory VRDisplay._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final VRDisplayCapabilities capabilities;
+
+  num depthFar;
+
+  num depthNear;
+
+  final int displayId;
+
+  final String displayName;
+
+  final bool isPresenting;
+
+  final VRStageParameters stageParameters;
+
+  void cancelAnimationFrame(int handle) native;
+
+  Future exitPresent() => promiseToFuture(JS("", "#.exitPresent()", this));
+
+  VREyeParameters getEyeParameters(String whichEye) native;
+
+  bool getFrameData(VRFrameData frameData) native;
+
+  List<Map> getLayers() native;
+
+  int requestAnimationFrame(FrameRequestCallback callback) native;
+
+  Future requestPresent(List<Map> layers) =>
+      promiseToFuture(JS("", "#.requestPresent(#)", this, layers));
+
+  void submitFrame() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("VRDisplayCapabilities")
+class VRDisplayCapabilities extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory VRDisplayCapabilities._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool canPresent;
+
+  final bool hasExternalDisplay;
+
+  final bool hasPosition;
+
+  final int maxLayers;
+}
+// Copyright (c) 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.
+
+@Native("VRDisplayEvent")
+class VRDisplayEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory VRDisplayEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory VRDisplayEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return VRDisplayEvent._create_1(type, eventInitDict_1);
+    }
+    return VRDisplayEvent._create_2(type);
+  }
+  static VRDisplayEvent _create_1(type, eventInitDict) =>
+      JS('VRDisplayEvent', 'new VRDisplayEvent(#,#)', type, eventInitDict);
+  static VRDisplayEvent _create_2(type) =>
+      JS('VRDisplayEvent', 'new VRDisplayEvent(#)', type);
+
+  final VRDisplay display;
+
+  final String reason;
+}
+// Copyright (c) 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.
+
+@Native("VREyeParameters")
+class VREyeParameters extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory VREyeParameters._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final Float32List offset;
+
+  final int renderHeight;
+
+  final int renderWidth;
+}
+// Copyright (c) 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.
+
+@Native("VRFrameData")
+class VRFrameData extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory VRFrameData._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory VRFrameData() {
+    return VRFrameData._create_1();
+  }
+  static VRFrameData _create_1() => JS('VRFrameData', 'new VRFrameData()');
+
+  final Float32List leftProjectionMatrix;
+
+  final Float32List leftViewMatrix;
+
+  final VRPose pose;
+
+  final Float32List rightProjectionMatrix;
+
+  final Float32List rightViewMatrix;
+}
+// Copyright (c) 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.
+
+@Native("VRFrameOfReference")
+class VRFrameOfReference extends VRCoordinateSystem {
+  // To suppress missing implicit constructor warnings.
+  factory VRFrameOfReference._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final VRStageBounds bounds;
+
+  final num emulatedHeight;
+}
+// Copyright (c) 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.
+
+@Native("VRPose")
+class VRPose extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory VRPose._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final Float32List angularAcceleration;
+
+  final Float32List angularVelocity;
+
+  final Float32List linearAcceleration;
+
+  final Float32List linearVelocity;
+
+  final Float32List orientation;
+
+  final Float32List position;
+}
+// Copyright (c) 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.
+
+@Native("VRSession")
+class VRSession extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory VRSession._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> blurEvent =
+      const EventStreamProvider<Event>('blur');
+
+  static const EventStreamProvider<Event> focusEvent =
+      const EventStreamProvider<Event>('focus');
+
+  num depthFar;
+
+  num depthNear;
+
+  final VRDevice device;
+
+  final bool exclusive;
+
+  Future end() => promiseToFuture(JS("", "#.end()", this));
+
+  Future requestFrameOfReference(String type, [Map options]) {
+    var options_dict = null;
+    if (options != null) {
+      options_dict = convertDartToNative_Dictionary(options);
+    }
+    return promiseToFuture(
+        JS("", "#.requestFrameOfReference(#, #)", this, type, options_dict));
+  }
+
+  Stream<Event> get onBlur => blurEvent.forTarget(this);
+
+  Stream<Event> get onFocus => focusEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("VRSessionEvent")
+class VRSessionEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory VRSessionEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory VRSessionEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return VRSessionEvent._create_1(type, eventInitDict_1);
+  }
+  static VRSessionEvent _create_1(type, eventInitDict) =>
+      JS('VRSessionEvent', 'new VRSessionEvent(#,#)', type, eventInitDict);
+
+  final VRSession session;
+}
+// Copyright (c) 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.
+
+@Native("VRStageBounds")
+class VRStageBounds extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory VRStageBounds._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final List<VRStageBoundsPoint> geometry;
+}
+// Copyright (c) 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.
+
+@Native("VRStageBoundsPoint")
+class VRStageBoundsPoint extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory VRStageBoundsPoint._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num x;
+
+  final num z;
+}
+// Copyright (c) 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.
+
+@Native("VRStageParameters")
+class VRStageParameters extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory VRStageParameters._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final Float32List sittingToStandingTransform;
+
+  final num sizeX;
+
+  final num sizeZ;
+}
+// Copyright (c) 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.
+
+@Native("ValidityState")
+class ValidityState extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ValidityState._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool badInput;
+
+  final bool customError;
+
+  final bool patternMismatch;
+
+  final bool rangeOverflow;
+
+  final bool rangeUnderflow;
+
+  final bool stepMismatch;
+
+  final bool tooLong;
+
+  final bool tooShort;
+
+  final bool typeMismatch;
+
+  final bool valid;
+
+  final bool valueMissing;
+}
+// Copyright (c) 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.
+
+@Native("HTMLVideoElement")
+class VideoElement extends MediaElement implements CanvasImageSource {
+  // To suppress missing implicit constructor warnings.
+  factory VideoElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory VideoElement() => JS(
+      'returns:VideoElement;creates:VideoElement;new:true',
+      '#.createElement(#)',
+      document,
+      "video");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  VideoElement.created() : super.created();
+
+  int height;
+
+  String poster;
+
+  final int videoHeight;
+
+  final int videoWidth;
+
+  @JSName('webkitDecodedFrameCount')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  final int decodedFrameCount;
+
+  @JSName('webkitDroppedFrameCount')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  final int droppedFrameCount;
+
+  int width;
+
+  VideoPlaybackQuality getVideoPlaybackQuality() native;
+
+  @JSName('webkitEnterFullscreen')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void enterFullscreen() native;
+
+  @JSName('webkitExitFullscreen')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void exitFullscreen() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("VideoPlaybackQuality")
+class VideoPlaybackQuality extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory VideoPlaybackQuality._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int corruptedVideoFrames;
+
+  final num creationTime;
+
+  final int droppedVideoFrames;
+
+  final int totalVideoFrames;
+}
+// Copyright (c) 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.
+
+@Native("VideoTrack")
+class VideoTrack extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory VideoTrack._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String id;
+
+  final String kind;
+
+  final String label;
+
+  final String language;
+
+  bool selected;
+
+  final SourceBuffer sourceBuffer;
+}
+// Copyright (c) 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.
+
+@Native("VideoTrackList")
+class VideoTrackList extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory VideoTrackList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> changeEvent =
+      const EventStreamProvider<Event>('change');
+
+  final int length;
+
+  final int selectedIndex;
+
+  VideoTrack __getter__(int index) native;
+
+  VideoTrack getTrackById(String id) native;
+
+  Stream<Event> get onChange => changeEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("VisualViewport")
+class VisualViewport extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory VisualViewport._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> resizeEvent =
+      const EventStreamProvider<Event>('resize');
+
+  static const EventStreamProvider<Event> scrollEvent =
+      const EventStreamProvider<Event>('scroll');
+
+  final num height;
+
+  final num offsetLeft;
+
+  final num offsetTop;
+
+  final num pageLeft;
+
+  final num pageTop;
+
+  final num scale;
+
+  final num width;
+
+  Stream<Event> get onResize => resizeEvent.forTarget(this);
+
+  Stream<Event> get onScroll => scrollEvent.forTarget(this);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void VoidCallback();
+// Copyright (c) 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.
+
+@Native("VTTCue")
+class VttCue extends TextTrackCue {
+  // To suppress missing implicit constructor warnings.
+  factory VttCue._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory VttCue(num startTime, num endTime, String text) {
+    return VttCue._create_1(startTime, endTime, text);
+  }
+  static VttCue _create_1(startTime, endTime, text) =>
+      JS('VttCue', 'new VTTCue(#,#,#)', startTime, endTime, text);
+
+  String align;
+
+  @Creates('Null')
+  @Returns('num|String')
+  Object line;
+
+  @Creates('Null')
+  @Returns('num|String')
+  Object position;
+
+  VttRegion region;
+
+  num size;
+
+  bool snapToLines;
+
+  String text;
+
+  String vertical;
+
+  @JSName('getCueAsHTML')
+  DocumentFragment getCueAsHtml() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("VTTRegion")
+class VttRegion extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory VttRegion._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory VttRegion() {
+    return VttRegion._create_1();
+  }
+  static VttRegion _create_1() => JS('VttRegion', 'new VTTRegion()');
+
+  String id;
+
+  int lines;
+
+  num regionAnchorX;
+
+  num regionAnchorY;
+
+  String scroll;
+
+  num viewportAnchorX;
+
+  num viewportAnchorY;
+
+  num width;
+}
+// Copyright (c) 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.
+
+/**
+ * Use the WebSocket interface to connect to a WebSocket,
+ * and to send and receive data on that WebSocket.
+ *
+ * To use a WebSocket in your web app, first create a WebSocket object,
+ * passing the WebSocket URL as an argument to the constructor.
+ *
+ *     var webSocket = new WebSocket('ws://127.0.0.1:1337/ws');
+ *
+ * To send data on the WebSocket, use the [send] method.
+ *
+ *     if (webSocket != null && webSocket.readyState == WebSocket.OPEN) {
+ *       webSocket.send(data);
+ *     } else {
+ *       print('WebSocket not connected, message $data not sent');
+ *     }
+ *
+ * To receive data on the WebSocket, register a listener for message events.
+ *
+ *     webSocket.onMessage.listen((MessageEvent e) {
+ *       receivedData(e.data);
+ *     });
+ *
+ * The message event handler receives a [MessageEvent] object
+ * as its sole argument.
+ * You can also define open, close, and error handlers,
+ * as specified by [WebSocketEvents].
+ *
+ * For more information, see the
+ * [WebSockets](http://www.dartlang.org/docs/library-tour/#html-websockets)
+ * section of the library tour and
+ * [Introducing WebSockets](http://www.html5rocks.com/en/tutorials/websockets/basics/),
+ * an HTML5Rocks.com tutorial.
+ */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("WebSocket")
+class WebSocket extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory WebSocket._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `close` events to event
+   * handlers that are not necessarily instances of [WebSocket].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<CloseEvent> closeEvent =
+      const EventStreamProvider<CloseEvent>('close');
+
+  /**
+   * Static factory designed to expose `error` events to event
+   * handlers that are not necessarily instances of [WebSocket].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  /**
+   * Static factory designed to expose `message` events to event
+   * handlers that are not necessarily instances of [WebSocket].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MessageEvent> messageEvent =
+      const EventStreamProvider<MessageEvent>('message');
+
+  /**
+   * Static factory designed to expose `open` events to event
+   * handlers that are not necessarily instances of [WebSocket].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> openEvent =
+      const EventStreamProvider<Event>('open');
+
+  factory WebSocket(String url, [Object protocols]) {
+    if (protocols != null) {
+      return WebSocket._create_1(url, protocols);
+    }
+    return WebSocket._create_2(url);
+  }
+  static WebSocket _create_1(url, protocols) =>
+      JS('WebSocket', 'new WebSocket(#,#)', url, protocols);
+  static WebSocket _create_2(url) => JS('WebSocket', 'new WebSocket(#)', url);
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      JS('bool', 'typeof window.WebSocket != "undefined"');
+
+  static const int CLOSED = 3;
+
+  static const int CLOSING = 2;
+
+  static const int CONNECTING = 0;
+
+  static const int OPEN = 1;
+
+  String binaryType;
+
+  final int bufferedAmount;
+
+  final String extensions;
+
+  final String protocol;
+
+  final int readyState;
+
+  final String url;
+
+  void close([int code, String reason]) native;
+
+  /**
+   * Transmit data to the server over this connection.
+   *
+   * This method accepts data of type [Blob], [ByteBuffer], [String], or
+   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
+   * or [sendTypedData], in contrast, only accept data of the specified type.
+   */
+  void send(data) native;
+
+  @JSName('send')
+  /**
+   * Transmit data to the server over this connection.
+   *
+   * This method accepts data of type [Blob], [ByteBuffer], [String], or
+   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
+   * or [sendTypedData], in contrast, only accept data of the specified type.
+   */
+  void sendBlob(Blob data) native;
+
+  @JSName('send')
+  /**
+   * Transmit data to the server over this connection.
+   *
+   * This method accepts data of type [Blob], [ByteBuffer], [String], or
+   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
+   * or [sendTypedData], in contrast, only accept data of the specified type.
+   */
+  void sendByteBuffer(ByteBuffer data) native;
+
+  @JSName('send')
+  /**
+   * Transmit data to the server over this connection.
+   *
+   * This method accepts data of type [Blob], [ByteBuffer], [String], or
+   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
+   * or [sendTypedData], in contrast, only accept data of the specified type.
+   */
+  void sendString(String data) native;
+
+  @JSName('send')
+  /**
+   * Transmit data to the server over this connection.
+   *
+   * This method accepts data of type [Blob], [ByteBuffer], [String], or
+   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
+   * or [sendTypedData], in contrast, only accept data of the specified type.
+   */
+  void sendTypedData(TypedData data) native;
+
+  /// Stream of `close` events handled by this [WebSocket].
+  Stream<CloseEvent> get onClose => closeEvent.forTarget(this);
+
+  /// Stream of `error` events handled by this [WebSocket].
+  Stream<Event> get onError => errorEvent.forTarget(this);
+
+  /// Stream of `message` events handled by this [WebSocket].
+  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
+
+  /// Stream of `open` events handled by this [WebSocket].
+  Stream<Event> get onOpen => openEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("WheelEvent")
+class WheelEvent extends MouseEvent {
+  factory WheelEvent(String type,
+      {Window view,
+      num deltaX: 0,
+      num deltaY: 0,
+      num deltaZ: 0,
+      int deltaMode: 0,
+      int detail: 0,
+      int screenX: 0,
+      int screenY: 0,
+      int clientX: 0,
+      int clientY: 0,
+      int button: 0,
+      bool canBubble: true,
+      bool cancelable: true,
+      bool ctrlKey: false,
+      bool altKey: false,
+      bool shiftKey: false,
+      bool metaKey: false,
+      EventTarget relatedTarget}) {
+    var options = {
+      'view': view,
+      'deltaMode': deltaMode,
+      'deltaX': deltaX,
+      'deltaY': deltaY,
+      'deltaZ': deltaZ,
+      'detail': detail,
+      'screenX': screenX,
+      'screenY': screenY,
+      'clientX': clientX,
+      'clientY': clientY,
+      'button': button,
+      'bubbles': canBubble,
+      'cancelable': cancelable,
+      'ctrlKey': ctrlKey,
+      'altKey': altKey,
+      'shiftKey': shiftKey,
+      'metaKey': metaKey,
+      'relatedTarget': relatedTarget,
+    };
+
+    if (view == null) {
+      view = window;
+    }
+
+    return JS('WheelEvent', 'new WheelEvent(#, #)', type,
+        convertDartToNative_Dictionary(options));
+  }
+
+  factory WheelEvent._(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return WheelEvent._create_1(type, eventInitDict_1);
+    }
+    return WheelEvent._create_2(type);
+  }
+  static WheelEvent _create_1(type, eventInitDict) =>
+      JS('WheelEvent', 'new WheelEvent(#,#)', type, eventInitDict);
+  static WheelEvent _create_2(type) =>
+      JS('WheelEvent', 'new WheelEvent(#)', type);
+
+  static const int DOM_DELTA_LINE = 0x01;
+
+  static const int DOM_DELTA_PAGE = 0x02;
+
+  static const int DOM_DELTA_PIXEL = 0x00;
+
+  @JSName('deltaX')
+  final num _deltaX;
+
+  @JSName('deltaY')
+  final num _deltaY;
+
+  final num deltaZ;
+
+  /**
+   * The amount that is expected to scroll vertically, in units determined by
+   * [deltaMode].
+   *
+   * See also:
+   *
+   * * [WheelEvent.deltaY](http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-WheelEvent-deltaY) from the W3C.
+   */
+  num get deltaY {
+    if (JS('bool', '#.deltaY !== undefined', this)) {
+      // W3C WheelEvent
+      return this._deltaY;
+    }
+    throw new UnsupportedError('deltaY is not supported');
+  }
+
+  /**
+   * The amount that is expected to scroll horizontally, in units determined by
+   * [deltaMode].
+   *
+   * See also:
+   *
+   * * [WheelEvent.deltaX](http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-WheelEvent-deltaX) from the W3C.
+   */
+  num get deltaX {
+    if (JS('bool', '#.deltaX !== undefined', this)) {
+      // W3C WheelEvent
+      return this._deltaX;
+    }
+    throw new UnsupportedError('deltaX is not supported');
+  }
+
+  int get deltaMode {
+    if (JS('bool', '!!(#.deltaMode)', this)) {
+      return JS('int', '#.deltaMode', this);
+    }
+    // If not available then we're poly-filling and doing pixel scroll.
+    return 0;
+  }
+
+  num get _wheelDelta => JS('num', '#.wheelDelta', this);
+  num get _wheelDeltaX => JS('num', '#.wheelDeltaX', this);
+  num get _detail => JS('num', '#.detail', this);
+
+  bool get _hasInitMouseScrollEvent =>
+      JS('bool', '!!(#.initMouseScrollEvent)', this);
+
+  @JSName('initMouseScrollEvent')
+  void _initMouseScrollEvent(
+      String type,
+      bool canBubble,
+      bool cancelable,
+      Window view,
+      int detail,
+      int screenX,
+      int screenY,
+      int clientX,
+      int clientY,
+      bool ctrlKey,
+      bool altKey,
+      bool shiftKey,
+      bool metaKey,
+      int button,
+      EventTarget relatedTarget,
+      int axis) native;
+
+  bool get _hasInitWheelEvent => JS('bool', '!!(#.initWheelEvent)', this);
+  @JSName('initWheelEvent')
+  void _initWheelEvent(
+      String eventType,
+      bool canBubble,
+      bool cancelable,
+      Window view,
+      int detail,
+      int screenX,
+      int screenY,
+      int clientX,
+      int clientY,
+      int button,
+      EventTarget relatedTarget,
+      String modifiersList,
+      int deltaX,
+      int deltaY,
+      int deltaZ,
+      int deltaMode) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Top-level container for the current browser tab or window.
+ *
+ * In a web browser, each window has a [Window] object, but within the context
+ * of a script, this object represents only the current window.
+ * Each other window, tab, and iframe has its own [Window] object.
+ *
+ * Each window contains a [Document] object, which contains all of the window's
+ * content.
+ *
+ * Use the top-level `window` object to access the current window.
+ * For example:
+ *
+ *     // Draw a scene when the window repaints.
+ *     drawScene(num delta) {...}
+ *     window.animationFrame.then(drawScene);.
+ *
+ *     // Write to the console.
+ *     window.console.log('Jinkies!');
+ *     window.console.error('Jeepers!');
+ *
+ * **Note:** This class represents only the current window, while [WindowBase]
+ * is a representation of any window, including other tabs, windows, and frames.
+ *
+ * ## See also
+ *
+ * * [WindowBase]
+ *
+ * ## Other resources
+ *
+ * * [DOM Window](https://developer.mozilla.org/en-US/docs/DOM/window) from MDN.
+ * * [Window](http://www.w3.org/TR/Window/) from the W3C.
+ */
+@Native("Window,DOMWindow")
+class Window extends EventTarget
+    implements
+        WindowEventHandlers,
+        WindowBase,
+        GlobalEventHandlers,
+        _WindowTimers,
+        WindowBase64 {
+  /**
+   * Returns a Future that completes just before the window is about to
+   * repaint so the user can draw an animation frame.
+   *
+   * If you need to later cancel this animation, use [requestAnimationFrame]
+   * instead.
+   *
+   * The [Future] completes to a timestamp that represents a floating
+   * point value of the number of milliseconds that have elapsed since the page
+   * started to load (which is also the timestamp at this call to
+   * animationFrame).
+   *
+   * Note: The code that runs when the future completes should call
+   * [animationFrame] again for the animation to continue.
+   */
+  Future<num> get animationFrame {
+    var completer = new Completer<num>.sync();
+    requestAnimationFrame((time) {
+      completer.complete(time);
+    });
+    return completer.future;
+  }
+
+  /**
+   * The newest document in this window.
+   *
+   * ## Other resources
+   *
+   * * [Loading web
+   *   pages](https://html.spec.whatwg.org/multipage/browsers.html)
+   *   from WHATWG.
+   */
+  Document get document => JS('Document', '#.document', this);
+
+  WindowBase _open2(url, name) =>
+      JS('Window|Null', '#.open(#,#)', this, url, name);
+
+  WindowBase _open3(url, name, options) =>
+      JS('Window|Null', '#.open(#,#,#)', this, url, name, options);
+
+  /**
+   * Opens a new window.
+   *
+   * ## Other resources
+   *
+   * * [Window.open](https://developer.mozilla.org/en-US/docs/Web/API/Window.open)
+   *   from MDN.
+   */
+  WindowBase open(String url, String name, [String options]) {
+    if (options == null) {
+      return _DOMWindowCrossFrame._createSafe(_open2(url, name));
+    } else {
+      return _DOMWindowCrossFrame._createSafe(_open3(url, name, options));
+    }
+  }
+
+  // API level getter and setter for Location.
+  // TODO: The cross domain safe wrapper can be inserted here.
+  /**
+   * The current location of this window.
+   *
+   *     Location currentLocation = window.location;
+   *     print(currentLocation.href); // 'http://www.example.com:80/'
+   */
+  Location get location => _location;
+
+  // TODO: consider forcing users to do: window.location.assign('string').
+  /**
+   * Sets the window's location, which causes the browser to navigate to the new
+   * location.
+   */
+  set location(value) {
+    _location = value;
+  }
+
+  // Native getter and setter to access raw Location object.
+  dynamic get _location => JS('Location|Null', '#.location', this);
+  set _location(value) {
+    JS('void', '#.location = #', this, value);
+  }
+
+  /**
+   * Called to draw an animation frame and then request the window to repaint
+   * after [callback] has finished (creating the animation).
+   *
+   * Use this method only if you need to later call [cancelAnimationFrame]. If
+   * not, the preferred Dart idiom is to set animation frames by calling
+   * [animationFrame], which returns a Future.
+   *
+   * Returns a non-zero valued integer to represent the request id for this
+   * request. This value only needs to be saved if you intend to call
+   * [cancelAnimationFrame] so you can specify the particular animation to
+   * cancel.
+   *
+   * Note: The supplied [callback] needs to call [requestAnimationFrame] again
+   * for the animation to continue.
+   */
+  int requestAnimationFrame(FrameRequestCallback callback) {
+    _ensureRequestAnimationFrame();
+    return _requestAnimationFrame(_wrapZone(callback));
+  }
+
+  /**
+   * Cancels an animation frame request.
+   *
+   * ## Other resources
+   *
+   * * [Window.cancelAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/Window.cancelAnimationFrame)
+   *   from MDN.
+   */
+  void cancelAnimationFrame(int id) {
+    _ensureRequestAnimationFrame();
+    _cancelAnimationFrame(id);
+  }
+
+  @JSName('requestAnimationFrame')
+  int _requestAnimationFrame(FrameRequestCallback callback) native;
+
+  @JSName('cancelAnimationFrame')
+  void _cancelAnimationFrame(int id) native;
+
+  _ensureRequestAnimationFrame() {
+    if (JS<bool>(
+        'bool',
+        '!!(#.requestAnimationFrame && #.cancelAnimationFrame)',
+        this,
+        this)) return;
+
+    JS(
+        'void',
+        r"""
+  (function($this) {
+   var vendors = ['ms', 'moz', 'webkit', 'o'];
+   for (var i = 0; i < vendors.length && !$this.requestAnimationFrame; ++i) {
+     $this.requestAnimationFrame = $this[vendors[i] + 'RequestAnimationFrame'];
+     $this.cancelAnimationFrame =
+         $this[vendors[i]+'CancelAnimationFrame'] ||
+         $this[vendors[i]+'CancelRequestAnimationFrame'];
+   }
+   if ($this.requestAnimationFrame && $this.cancelAnimationFrame) return;
+   $this.requestAnimationFrame = function(callback) {
+      return window.setTimeout(function() {
+        callback(Date.now());
+      }, 16 /* 16ms ~= 60fps */);
+   };
+   $this.cancelAnimationFrame = function(id) { clearTimeout(id); }
+  })(#)""",
+        this);
+  }
+
+  /**
+   * Gets an instance of the Indexed DB factory to being using Indexed DB.
+   *
+   * Use [indexed_db.IdbFactory.supported] to check if Indexed DB is supported on the
+   * current platform.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME, '23.0')
+  @SupportedBrowser(SupportedBrowser.FIREFOX, '15.0')
+  @SupportedBrowser(SupportedBrowser.IE, '10.0')
+  IdbFactory get indexedDB => JS(
+      'IdbFactory|Null', // If not supported, returns null.
+      '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB',
+      this,
+      this,
+      this);
+
+  /// The debugging console for this window.
+  Console get console => Console._safeConsole;
+
+  /**
+   * Access a sandboxed file system of `size` bytes.
+   *
+   * If `persistent` is true, the application will request permission from the
+   * user to create lasting storage. This storage cannot be freed without the
+   * user's permission. Returns a [Future] whose value stores a reference to
+   * the sandboxed file system for use. Because the file system is sandboxed,
+   * applications cannot access file systems created in other web pages.
+   */
+  Future<FileSystem> requestFileSystem(int size, {bool persistent: false}) {
+    return _requestFileSystem(persistent ? 1 : 0, size);
+  }
+
+  /**
+   * convertPointFromNodeToPage and convertPointFromPageToNode are removed.
+   * see http://dev.w3.org/csswg/cssom-view/#geometry
+   */
+  static bool get supportsPointConversions => DomPoint.supported;
+  // To suppress missing implicit constructor warnings.
+  factory Window._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `contentloaded` events to event
+   * handlers that are not necessarily instances of [Window].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> contentLoadedEvent =
+      const EventStreamProvider<Event>('DOMContentLoaded');
+
+  /**
+   * Static factory designed to expose `devicemotion` events to event
+   * handlers that are not necessarily instances of [Window].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<DeviceMotionEvent> deviceMotionEvent =
+      const EventStreamProvider<DeviceMotionEvent>('devicemotion');
+
+  /**
+   * Static factory designed to expose `deviceorientation` events to event
+   * handlers that are not necessarily instances of [Window].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<DeviceOrientationEvent>
+      deviceOrientationEvent =
+      const EventStreamProvider<DeviceOrientationEvent>('deviceorientation');
+
+  /**
+   * Static factory designed to expose `hashchange` events to event
+   * handlers that are not necessarily instances of [Window].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> hashChangeEvent =
+      const EventStreamProvider<Event>('hashchange');
+
+  static const EventStreamProvider<Event> loadStartEvent =
+      const EventStreamProvider<Event>('loadstart');
+
+  /**
+   * Static factory designed to expose `message` events to event
+   * handlers that are not necessarily instances of [Window].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MessageEvent> messageEvent =
+      const EventStreamProvider<MessageEvent>('message');
+
+  /**
+   * Static factory designed to expose `offline` events to event
+   * handlers that are not necessarily instances of [Window].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> offlineEvent =
+      const EventStreamProvider<Event>('offline');
+
+  /**
+   * Static factory designed to expose `online` events to event
+   * handlers that are not necessarily instances of [Window].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> onlineEvent =
+      const EventStreamProvider<Event>('online');
+
+  /**
+   * Static factory designed to expose `pagehide` events to event
+   * handlers that are not necessarily instances of [Window].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> pageHideEvent =
+      const EventStreamProvider<Event>('pagehide');
+
+  /**
+   * Static factory designed to expose `pageshow` events to event
+   * handlers that are not necessarily instances of [Window].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> pageShowEvent =
+      const EventStreamProvider<Event>('pageshow');
+
+  /**
+   * Static factory designed to expose `popstate` events to event
+   * handlers that are not necessarily instances of [Window].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<PopStateEvent> popStateEvent =
+      const EventStreamProvider<PopStateEvent>('popstate');
+
+  static const EventStreamProvider<Event> progressEvent =
+      const EventStreamProvider<Event>('progress');
+
+  /**
+   * Static factory designed to expose `storage` events to event
+   * handlers that are not necessarily instances of [Window].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<StorageEvent> storageEvent =
+      const EventStreamProvider<StorageEvent>('storage');
+
+  /**
+   * Static factory designed to expose `unload` events to event
+   * handlers that are not necessarily instances of [Window].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> unloadEvent =
+      const EventStreamProvider<Event>('unload');
+
+  /**
+   * Static factory designed to expose `animationend` events to event
+   * handlers that are not necessarily instances of [Window].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  static const EventStreamProvider<AnimationEvent> animationEndEvent =
+      const EventStreamProvider<AnimationEvent>('webkitAnimationEnd');
+
+  /**
+   * Static factory designed to expose `animationiteration` events to event
+   * handlers that are not necessarily instances of [Window].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  static const EventStreamProvider<AnimationEvent> animationIterationEvent =
+      const EventStreamProvider<AnimationEvent>('webkitAnimationIteration');
+
+  /**
+   * Static factory designed to expose `animationstart` events to event
+   * handlers that are not necessarily instances of [Window].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  static const EventStreamProvider<AnimationEvent> animationStartEvent =
+      const EventStreamProvider<AnimationEvent>('webkitAnimationStart');
+
+  /**
+   * Indicates that file system data cannot be cleared unless given user
+   * permission.
+   *
+   * ## Other resources
+   *
+   * * [Exploring the FileSystem
+   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/)
+   *   from HTML5Rocks.
+   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)
+   *   from W3C.
+   */
+  static const int PERSISTENT = 1;
+
+  /**
+   * Indicates that file system data can be cleared at any time.
+   *
+   * ## Other resources
+   *
+   * * [Exploring the FileSystem
+   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
+   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)
+   *   from W3C.
+   */
+  static const int TEMPORARY = 0;
+
+  final _Worklet animationWorklet;
+
+  /**
+   * The application cache for this window.
+   *
+   * ## Other resources
+   *
+   * * [A beginner's guide to using the application
+   *   cache](http://www.html5rocks.com/en/tutorials/appcache/beginner)
+   *   from HTML5Rocks.
+   * * [Application cache
+   *   API](https://html.spec.whatwg.org/multipage/browsers.html#application-cache-api)
+   *   from WHATWG.
+   */
+  final ApplicationCache applicationCache;
+
+  final _Worklet audioWorklet;
+
+  final CacheStorage caches;
+
+  final bool closed;
+
+  final CookieStore cookieStore;
+
+  /**
+   * Entrypoint for the browser's cryptographic functions.
+   *
+   * ## Other resources
+   *
+   * * [Web cryptography API](http://www.w3.org/TR/WebCryptoAPI/) from W3C.
+   */
+  final Crypto crypto;
+
+  final CustomElementRegistry customElements;
+
+  /// *Deprecated*.
+  String defaultStatus;
+
+  /// *Deprecated*.
+  String defaultstatus;
+
+  /**
+   * The ratio between physical pixels and logical CSS pixels.
+   *
+   * ## Other resources
+   *
+   * * [devicePixelRatio](http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html)
+   *   from quirksmode.
+   * * [More about devicePixelRatio](http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html)
+   *   from quirksmode.
+   */
+  final num devicePixelRatio;
+
+  final External external;
+
+  /**
+   * The current session history for this window's newest document.
+   *
+   * ## Other resources
+   *
+   * * [Loading web pages](https://html.spec.whatwg.org/multipage/browsers.html)
+   *   from WHATWG.
+   */
+  final History history;
+
+  /**
+   * The height of the viewport including scrollbars.
+   *
+   * ## Other resources
+   *
+   * * [Window.innerHeight](https://developer.mozilla.org/en-US/docs/Web/API/Window/innerHeight)
+   *   from MDN.
+   */
+  final int innerHeight;
+
+  /**
+   * The width of the viewport including scrollbars.
+   *
+   * ## Other resources
+   *
+   * * [Window.innerWidth](https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth)
+   *   from MDN.
+   */
+  final int innerWidth;
+
+  final bool isSecureContext;
+
+  /**
+   * Storage for this window that persists across sessions.
+   *
+   * ## Other resources
+   *
+   * * [DOM storage guide](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage)
+   *   from MDN.
+   * * [The past, present & future of local storage for web
+   *   applications](http://diveintohtml5.info/storage.html) from Dive Into HTML5.
+   * * [Local storage specification](http://www.w3.org/TR/webstorage/#the-localstorage-attribute)
+   *   from W3C.
+   */
+  final Storage localStorage;
+
+  /**
+   * This window's location bar, which displays the URL.
+   *
+   * ## Other resources
+   *
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
+   */
+  final BarProp locationbar;
+
+  /**
+   * This window's menu bar, which displays menu commands.
+   *
+   * ## Other resources
+   *
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
+   */
+  final BarProp menubar;
+
+  /**
+   * The name of this window.
+   *
+   * ## Other resources
+   *
+   * * [Window.name](https://developer.mozilla.org/en-US/docs/Web/API/Window/name)
+   *   from MDN.
+   */
+  String name;
+
+  /**
+   * The user agent accessing this window.
+   *
+   * ## Other resources
+   *
+   * * [The navigator
+   *   object](https://html.spec.whatwg.org/multipage/webappapis.html#the-navigator-object)
+   *   from WHATWG.
+   */
+  final Navigator navigator;
+
+  /**
+   * Whether objects are drawn offscreen before being displayed.
+   *
+   * ## Other resources
+   *
+   * * [offscreenBuffering](https://webplatform.github.io/docs/dom/HTMLElement/offscreenBuffering/)
+   *   from WebPlatform.org.
+   */
+  final bool offscreenBuffering;
+
+  WindowBase get opener => _convertNativeToDart_Window(this._get_opener);
+  @JSName('opener')
+  @Creates('Window|=Object')
+  @Returns('Window|=Object')
+  final dynamic _get_opener;
+
+  set opener(Window value) {
+    JS("void", "#.opener = #", this, value);
+  }
+
+  final int orientation;
+
+  final String origin;
+
+  /**
+   * The height of this window including all user interface elements.
+   *
+   * ## Other resources
+   *
+   * * [Window.outerHeight](https://developer.mozilla.org/en-US/docs/Web/API/Window/outerHeight)
+   *   from MDN.
+   */
+  final int outerHeight;
+
+  /**
+   * The width of the window including all user interface elements.
+   *
+   * ## Other resources
+   *
+   * * [Window.outerWidth](https://developer.mozilla.org/en-US/docs/Web/API/Window/outerWidth)
+   *   from MDN.
+   */
+  final int outerWidth;
+
+  @JSName('pageXOffset')
+  /**
+   * The distance this window has been scrolled horizontally.
+   *
+   * This attribute is an alias for [scrollX].
+   *
+   * ## Other resources
+   *
+   * * [The Screen interface
+   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [scrollX and
+   *   pageXOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)
+   *   from MDN.
+   */
+  final num _pageXOffset;
+
+  @JSName('pageYOffset')
+  /**
+   * The distance this window has been scrolled vertically.
+   *
+   * This attribute is an alias for [scrollY].
+   *
+   * ## Other resources
+   *
+   * * [The Screen interface
+   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [scrollY and
+   *   pageYOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)
+   *   from MDN.
+   */
+  final num _pageYOffset;
+
+  WindowBase get parent => _convertNativeToDart_Window(this._get_parent);
+  @JSName('parent')
+  @Creates('Window|=Object')
+  @Returns('Window|=Object')
+  final dynamic _get_parent;
+
+  /**
+   * Timing and navigation data for this window.
+   *
+   * ## Other resources
+   *
+   * * [Measuring page load speed with navigation
+   *   timeing](http://www.html5rocks.com/en/tutorials/webperformance/basics/)
+   *   from HTML5Rocks.
+   * * [Navigation timing
+   *   specification](http://www.w3.org/TR/navigation-timing/) from W3C.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE)
+  final Performance performance;
+
+  /**
+   * Information about the screen displaying this window.
+   *
+   * ## Other resources
+   *
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
+   */
+  final Screen screen;
+
+  /**
+   * The distance from the left side of the screen to the left side of this
+   * window.
+   *
+   * ## Other resources
+   *
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
+   */
+  final int screenLeft;
+
+  /**
+   * The distance from the top of the screen to the top of this window.
+   *
+   * ## Other resources
+   *
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
+   */
+  final int screenTop;
+
+  /**
+   * The distance from the left side of the screen to the mouse pointer.
+   *
+   * ## Other resources
+   *
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
+   */
+  final int screenX;
+
+  /**
+   * The distance from the top of the screen to the mouse pointer.
+   *
+   * ## Other resources
+   *
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
+   */
+  final int screenY;
+
+  /**
+   * This window's scroll bars.
+   *
+   * ## Other resources
+   *
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
+   */
+  final BarProp scrollbars;
+
+  /**
+   * The current window.
+   *
+   * ## Other resources
+   *
+   * * [Window.self](https://developer.mozilla.org/en-US/docs/Web/API/Window.self)
+   *   from MDN.
+   */
+  WindowBase get self => _convertNativeToDart_Window(this._get_self);
+  @JSName('self')
+  /**
+   * The current window.
+   *
+   * ## Other resources
+   *
+   * * [Window.self](https://developer.mozilla.org/en-US/docs/Web/API/Window.self)
+   *   from MDN.
+   */
+  @Creates('Window|=Object')
+  @Returns('Window|=Object')
+  final dynamic _get_self;
+
+  /**
+   * Storage for this window that is cleared when this session ends.
+   *
+   * ## Other resources
+   *
+   * * [DOM storage
+   *   guide](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage)
+   *   from MDN.
+   * * [The past, present & future of local storage for web
+   *   applications](http://diveintohtml5.info/storage.html) from Dive Into HTML5.
+   * * [Local storage
+   *   specification](http://www.w3.org/TR/webstorage/#dom-sessionstorage) from W3C.
+   */
+  final Storage sessionStorage;
+
+  /**
+   * Access to speech synthesis in the browser.
+   *
+   * ## Other resources
+   *
+   * * [Web speech
+   *   specification](https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section)
+   *   from W3C.
+   */
+  final SpeechSynthesis speechSynthesis;
+
+  /// *Deprecated*.
+  String status;
+
+  /**
+   * This window's status bar.
+   *
+   * ## Other resources
+   *
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
+   */
+  final BarProp statusbar;
+
+  /**
+   * Access to CSS media queries.
+   *
+   * ## Other resources
+   *
+   * * [StyleMedia class
+   *   reference](https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/)
+   *   from Safari Developer Library.
+   */
+  final StyleMedia styleMedia;
+
+  /**
+   * This window's tool bar.
+   *
+   * ## Other resources
+   *
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
+   */
+  final BarProp toolbar;
+
+  WindowBase get top => _convertNativeToDart_Window(this._get_top);
+  @JSName('top')
+  @Creates('Window|=Object')
+  @Returns('Window|=Object')
+  final dynamic _get_top;
+
+  final VisualViewport visualViewport;
+
+  /**
+   * The current window.
+   *
+   * ## Other resources
+   *
+   * * [Window.window](https://developer.mozilla.org/en-US/docs/Web/API/Window.window)
+   *   from MDN.
+   */
+  WindowBase get window => _convertNativeToDart_Window(this._get_window);
+  @JSName('window')
+  /**
+   * The current window.
+   *
+   * ## Other resources
+   *
+   * * [Window.window](https://developer.mozilla.org/en-US/docs/Web/API/Window.window)
+   *   from MDN.
+   */
+  @Creates('Window|=Object')
+  @Returns('Window|=Object')
+  final dynamic _get_window;
+
+  @Creates('Window|=Object')
+  @Returns('Window|=Object')
+  WindowBase __getter__(index_OR_name) {
+    if ((index_OR_name is int)) {
+      return _convertNativeToDart_Window(__getter___1(index_OR_name));
+    }
+    if ((index_OR_name is String)) {
+      return _convertNativeToDart_Window(__getter___2(index_OR_name));
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('__getter__')
+  @Creates('Window|=Object')
+  @Returns('Window|=Object')
+  __getter___1(int index) native;
+  @JSName('__getter__')
+  @Creates('Window|=Object')
+  @Returns('Window|=Object')
+  __getter___2(String name) native;
+
+  /**
+   * Displays a modal alert to the user.
+   *
+   * ## Other resources
+   *
+   * * [User prompts](https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts)
+   *   from WHATWG.
+   */
+  void alert([String message]) native;
+
+  void cancelIdleCallback(int handle) native;
+
+  void close() native;
+
+  /**
+   * Displays a modal OK/Cancel prompt to the user.
+   *
+   * ## Other resources
+   *
+   * * [User prompts](https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts)
+   *   from WHATWG.
+   */
+  bool confirm([String message]) native;
+
+  Future fetch(/*RequestInfo*/ input, [Map init]) {
+    var init_dict = null;
+    if (init != null) {
+      init_dict = convertDartToNative_Dictionary(init);
+    }
+    return promiseToFuture(JS("", "#.fetch(#, #)", this, input, init_dict));
+  }
+
+  /**
+   * Finds text in this window.
+   *
+   * ## Other resources
+   *
+   * * [Window.find](https://developer.mozilla.org/en-US/docs/Web/API/Window.find)
+   *   from MDN.
+   */
+  bool find(String string, bool caseSensitive, bool backwards, bool wrap,
+      bool wholeWord, bool searchInFrames, bool showDialog) native;
+
+  @JSName('getComputedStyle')
+  CssStyleDeclaration _getComputedStyle(Element elt, [String pseudoElt]) native;
+
+  StylePropertyMapReadonly getComputedStyleMap(
+      Element element, String pseudoElement) native;
+
+  @JSName('getMatchedCSSRules')
+  /**
+   * Returns all CSS rules that apply to the element's pseudo-element.
+   */
+  @Returns('_CssRuleList|Null')
+  @Creates('_CssRuleList')
+  List<CssRule> getMatchedCssRules(Element element, String pseudoElement)
+      native;
+
+  /**
+   * Returns the currently selected text.
+   *
+   * ## Other resources
+   *
+   * * [Window.getSelection](https://developer.mozilla.org/en-US/docs/Web/API/Window.getSelection)
+   *   from MDN.
+   */
+  Selection getSelection() native;
+
+  /**
+   * Returns a list of media queries for the given query string.
+   *
+   * ## Other resources
+   *
+   * * [Testing media
+   *   queries](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries)
+   *   from MDN.
+   * * [The MediaQueryList
+   *   specification](http://www.w3.org/TR/cssom-view/#the-mediaquerylist-interface) from W3C.
+   */
+  MediaQueryList matchMedia(String query) native;
+
+  /**
+   * Moves this window.
+   *
+   * x and y can be negative.
+   *
+   * ## Other resources
+   *
+   * * [Window.moveBy](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveBy)
+   *   from MDN.
+   * * [Window.moveBy](http://dev.w3.org/csswg/cssom-view/#dom-window-moveby) from W3C.
+   */
+  void moveBy(int x, int y) native;
+
+  @JSName('moveTo')
+  void _moveTo(int x, int y) native;
+
+  @JSName('openDatabase')
+
+  /// *Deprecated.*
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Creates('SqlDatabase')
+  SqlDatabase _openDatabase(
+      String name, String version, String displayName, int estimatedSize,
+      [DatabaseCallback creationCallback]) native;
+
+  void postMessage(/*any*/ message, String targetOrigin,
+      [List<Object> transfer]) {
+    if (transfer != null) {
+      var message_1 = convertDartToNative_SerializedScriptValue(message);
+      _postMessage_1(message_1, targetOrigin, transfer);
+      return;
+    }
+    var message_1 = convertDartToNative_SerializedScriptValue(message);
+    _postMessage_2(message_1, targetOrigin);
+    return;
+  }
+
+  @JSName('postMessage')
+  void _postMessage_1(message, targetOrigin, List<Object> transfer) native;
+  @JSName('postMessage')
+  void _postMessage_2(message, targetOrigin) native;
+
+  /**
+   * Opens the print dialog for this window.
+   *
+   * ## Other resources
+   *
+   * * [Window.print](https://developer.mozilla.org/en-US/docs/Web/API/Window.print)
+   *   from MDN.
+   */
+  void print() native;
+
+  int requestIdleCallback(IdleRequestCallback callback, [Map options]) {
+    if (options != null) {
+      var callback_1 = convertDartClosureToJS(callback, 1);
+      var options_2 = convertDartToNative_Dictionary(options);
+      return _requestIdleCallback_1(callback_1, options_2);
+    }
+    var callback_1 = convertDartClosureToJS(callback, 1);
+    return _requestIdleCallback_2(callback_1);
+  }
+
+  @JSName('requestIdleCallback')
+  int _requestIdleCallback_1(callback, options) native;
+  @JSName('requestIdleCallback')
+  int _requestIdleCallback_2(callback) native;
+
+  /**
+   * Resizes this window by an offset.
+   *
+   * ## Other resources
+   *
+   * * [Window.resizeBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/resizeBy)
+   *   from MDN.
+   */
+  void resizeBy(int x, int y) native;
+
+  /**
+   * Resizes this window to a specific width and height.
+   *
+   * ## Other resources
+   *
+   * * [Window.resizeTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/resizeTo)
+   *   from MDN.
+   */
+  void resizeTo(int x, int y) native;
+
+  /**
+   * Scrolls the page horizontally and vertically to a specific point.
+   *
+   * This method is identical to [scrollTo].
+   *
+   * ## Other resources
+   *
+   * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
+   *   from MDN.
+   */
+  void scroll([options_OR_x, y, Map scrollOptions]) {
+    if (options_OR_x == null && y == null && scrollOptions == null) {
+      _scroll_1();
+      return;
+    }
+    if ((options_OR_x is Map) && y == null && scrollOptions == null) {
+      var options_1 = convertDartToNative_Dictionary(options_OR_x);
+      _scroll_2(options_1);
+      return;
+    }
+    if ((y is num) && (options_OR_x is num) && scrollOptions == null) {
+      _scroll_3(options_OR_x, y);
+      return;
+    }
+    if ((y is int) && (options_OR_x is int) && scrollOptions == null) {
+      _scroll_4(options_OR_x, y);
+      return;
+    }
+    if (scrollOptions != null && (y is int) && (options_OR_x is int)) {
+      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
+      _scroll_5(options_OR_x, y, scrollOptions_1);
+      return;
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('scroll')
+  /**
+   * Scrolls the page horizontally and vertically to a specific point.
+   *
+   * This method is identical to [scrollTo].
+   *
+   * ## Other resources
+   *
+   * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
+   *   from MDN.
+   */
+  void _scroll_1() native;
+  @JSName('scroll')
+  /**
+   * Scrolls the page horizontally and vertically to a specific point.
+   *
+   * This method is identical to [scrollTo].
+   *
+   * ## Other resources
+   *
+   * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
+   *   from MDN.
+   */
+  void _scroll_2(options) native;
+  @JSName('scroll')
+  /**
+   * Scrolls the page horizontally and vertically to a specific point.
+   *
+   * This method is identical to [scrollTo].
+   *
+   * ## Other resources
+   *
+   * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
+   *   from MDN.
+   */
+  void _scroll_3(num x, num y) native;
+  @JSName('scroll')
+  /**
+   * Scrolls the page horizontally and vertically to a specific point.
+   *
+   * This method is identical to [scrollTo].
+   *
+   * ## Other resources
+   *
+   * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
+   *   from MDN.
+   */
+  void _scroll_4(int x, int y) native;
+  @JSName('scroll')
+  /**
+   * Scrolls the page horizontally and vertically to a specific point.
+   *
+   * This method is identical to [scrollTo].
+   *
+   * ## Other resources
+   *
+   * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
+   *   from MDN.
+   */
+  void _scroll_5(int x, int y, scrollOptions) native;
+
+  /**
+   * Scrolls the page horizontally and vertically by an offset.
+   *
+   * ## Other resources
+   *
+   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
+   *   from MDN.
+   */
+  void scrollBy([options_OR_x, y, Map scrollOptions]) {
+    if (options_OR_x == null && y == null && scrollOptions == null) {
+      _scrollBy_1();
+      return;
+    }
+    if ((options_OR_x is Map) && y == null && scrollOptions == null) {
+      var options_1 = convertDartToNative_Dictionary(options_OR_x);
+      _scrollBy_2(options_1);
+      return;
+    }
+    if ((y is num) && (options_OR_x is num) && scrollOptions == null) {
+      _scrollBy_3(options_OR_x, y);
+      return;
+    }
+    if ((y is int) && (options_OR_x is int) && scrollOptions == null) {
+      _scrollBy_4(options_OR_x, y);
+      return;
+    }
+    if (scrollOptions != null && (y is int) && (options_OR_x is int)) {
+      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
+      _scrollBy_5(options_OR_x, y, scrollOptions_1);
+      return;
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('scrollBy')
+  /**
+   * Scrolls the page horizontally and vertically by an offset.
+   *
+   * ## Other resources
+   *
+   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
+   *   from MDN.
+   */
+  void _scrollBy_1() native;
+  @JSName('scrollBy')
+  /**
+   * Scrolls the page horizontally and vertically by an offset.
+   *
+   * ## Other resources
+   *
+   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
+   *   from MDN.
+   */
+  void _scrollBy_2(options) native;
+  @JSName('scrollBy')
+  /**
+   * Scrolls the page horizontally and vertically by an offset.
+   *
+   * ## Other resources
+   *
+   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
+   *   from MDN.
+   */
+  void _scrollBy_3(num x, num y) native;
+  @JSName('scrollBy')
+  /**
+   * Scrolls the page horizontally and vertically by an offset.
+   *
+   * ## Other resources
+   *
+   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
+   *   from MDN.
+   */
+  void _scrollBy_4(int x, int y) native;
+  @JSName('scrollBy')
+  /**
+   * Scrolls the page horizontally and vertically by an offset.
+   *
+   * ## Other resources
+   *
+   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
+   *   from MDN.
+   */
+  void _scrollBy_5(int x, int y, scrollOptions) native;
+
+  /**
+   * Scrolls the page horizontally and vertically to a specific point.
+   *
+   * This method is identical to [scroll].
+   *
+   * ## Other resources
+   *
+   * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
+   *   from MDN.
+   */
+  void scrollTo([options_OR_x, y, Map scrollOptions]) {
+    if (options_OR_x == null && y == null && scrollOptions == null) {
+      _scrollTo_1();
+      return;
+    }
+    if ((options_OR_x is Map) && y == null && scrollOptions == null) {
+      var options_1 = convertDartToNative_Dictionary(options_OR_x);
+      _scrollTo_2(options_1);
+      return;
+    }
+    if ((y is num) && (options_OR_x is num) && scrollOptions == null) {
+      _scrollTo_3(options_OR_x, y);
+      return;
+    }
+    if ((y is int) && (options_OR_x is int) && scrollOptions == null) {
+      _scrollTo_4(options_OR_x, y);
+      return;
+    }
+    if (scrollOptions != null && (y is int) && (options_OR_x is int)) {
+      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
+      _scrollTo_5(options_OR_x, y, scrollOptions_1);
+      return;
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('scrollTo')
+  /**
+   * Scrolls the page horizontally and vertically to a specific point.
+   *
+   * This method is identical to [scroll].
+   *
+   * ## Other resources
+   *
+   * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
+   *   from MDN.
+   */
+  void _scrollTo_1() native;
+  @JSName('scrollTo')
+  /**
+   * Scrolls the page horizontally and vertically to a specific point.
+   *
+   * This method is identical to [scroll].
+   *
+   * ## Other resources
+   *
+   * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
+   *   from MDN.
+   */
+  void _scrollTo_2(options) native;
+  @JSName('scrollTo')
+  /**
+   * Scrolls the page horizontally and vertically to a specific point.
+   *
+   * This method is identical to [scroll].
+   *
+   * ## Other resources
+   *
+   * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
+   *   from MDN.
+   */
+  void _scrollTo_3(num x, num y) native;
+  @JSName('scrollTo')
+  /**
+   * Scrolls the page horizontally and vertically to a specific point.
+   *
+   * This method is identical to [scroll].
+   *
+   * ## Other resources
+   *
+   * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
+   *   from MDN.
+   */
+  void _scrollTo_4(int x, int y) native;
+  @JSName('scrollTo')
+  /**
+   * Scrolls the page horizontally and vertically to a specific point.
+   *
+   * This method is identical to [scroll].
+   *
+   * ## Other resources
+   *
+   * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
+   *   from MDN.
+   */
+  void _scrollTo_5(int x, int y, scrollOptions) native;
+
+  /**
+   * Stops the window from loading.
+   *
+   * ## Other resources
+   *
+   * * [The Window
+   *   object](http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)
+   *   from W3C.
+   */
+  void stop() native;
+
+  @JSName('webkitRequestFileSystem')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  void __requestFileSystem(
+      int type, int size, _FileSystemCallback successCallback,
+      [_ErrorCallback errorCallback]) native;
+
+  @JSName('webkitRequestFileSystem')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  Future<FileSystem> _requestFileSystem(int type, int size) {
+    var completer = new Completer<FileSystem>();
+    __requestFileSystem(type, size, (value) {
+      applyExtension('DOMFileSystem', value);
+      applyExtension('DirectoryEntry', value.root);
+      completer.complete(value);
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+
+  @JSName('webkitResolveLocalFileSystemURL')
+  /**
+   * Asynchronously retrieves a local filesystem entry.
+   *
+   * ## Other resources
+   *
+   * * [Obtaining access to file system entry
+   *   points](http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
+   * from W3C.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  void _resolveLocalFileSystemUrl(String url, _EntryCallback successCallback,
+      [_ErrorCallback errorCallback]) native;
+
+  @JSName('webkitResolveLocalFileSystemURL')
+  /**
+   * Asynchronously retrieves a local filesystem entry.
+   *
+   * ## Other resources
+   *
+   * * [Obtaining access to file system entry
+   *   points](http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
+   * from W3C.
+   */
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  Future<Entry> resolveLocalFileSystemUrl(String url) {
+    var completer = new Completer<Entry>();
+    _resolveLocalFileSystemUrl(url, (value) {
+      completer.complete(value);
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+
+  // From WindowBase64
+
+  String atob(String atob) native;
+
+  String btoa(String btoa) native;
+
+  // From WindowTimers
+
+  @JSName('setInterval')
+  int _setInterval_String(String handler, [int timeout, Object arguments])
+      native;
+
+  @JSName('setTimeout')
+  int _setTimeout_String(String handler, [int timeout, Object arguments])
+      native;
+
+  @JSName('clearInterval')
+  void _clearInterval([int handle]) native;
+
+  @JSName('clearTimeout')
+  void _clearTimeout([int handle]) native;
+
+  @JSName('setInterval')
+  int _setInterval(Object handler, [int timeout]) native;
+
+  @JSName('setTimeout')
+  int _setTimeout(Object handler, [int timeout]) native;
+
+  /// Stream of `contentloaded` events handled by this [Window].
+  Stream<Event> get onContentLoaded => contentLoadedEvent.forTarget(this);
+
+  /// Stream of `abort` events handled by this [Window].
+  Stream<Event> get onAbort => Element.abortEvent.forTarget(this);
+
+  /// Stream of `blur` events handled by this [Window].
+  Stream<Event> get onBlur => Element.blurEvent.forTarget(this);
+
+  Stream<Event> get onCanPlay => Element.canPlayEvent.forTarget(this);
+
+  Stream<Event> get onCanPlayThrough =>
+      Element.canPlayThroughEvent.forTarget(this);
+
+  /// Stream of `change` events handled by this [Window].
+  Stream<Event> get onChange => Element.changeEvent.forTarget(this);
+
+  /// Stream of `click` events handled by this [Window].
+  Stream<MouseEvent> get onClick => Element.clickEvent.forTarget(this);
+
+  /// Stream of `contextmenu` events handled by this [Window].
+  Stream<MouseEvent> get onContextMenu =>
+      Element.contextMenuEvent.forTarget(this);
+
+  /// Stream of `doubleclick` events handled by this [Window].
+  @DomName('Window.ondblclick')
+  Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);
+
+  /// Stream of `devicemotion` events handled by this [Window].
+  Stream<DeviceMotionEvent> get onDeviceMotion =>
+      deviceMotionEvent.forTarget(this);
+
+  /// Stream of `deviceorientation` events handled by this [Window].
+  Stream<DeviceOrientationEvent> get onDeviceOrientation =>
+      deviceOrientationEvent.forTarget(this);
+
+  /// Stream of `drag` events handled by this [Window].
+  Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);
+
+  /// Stream of `dragend` events handled by this [Window].
+  Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);
+
+  /// Stream of `dragenter` events handled by this [Window].
+  Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);
+
+  /// Stream of `dragleave` events handled by this [Window].
+  Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);
+
+  /// Stream of `dragover` events handled by this [Window].
+  Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);
+
+  /// Stream of `dragstart` events handled by this [Window].
+  Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);
+
+  /// Stream of `drop` events handled by this [Window].
+  Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);
+
+  Stream<Event> get onDurationChange =>
+      Element.durationChangeEvent.forTarget(this);
+
+  Stream<Event> get onEmptied => Element.emptiedEvent.forTarget(this);
+
+  Stream<Event> get onEnded => Element.endedEvent.forTarget(this);
+
+  /// Stream of `error` events handled by this [Window].
+  Stream<Event> get onError => Element.errorEvent.forTarget(this);
+
+  /// Stream of `focus` events handled by this [Window].
+  Stream<Event> get onFocus => Element.focusEvent.forTarget(this);
+
+  /// Stream of `hashchange` events handled by this [Window].
+  Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);
+
+  /// Stream of `input` events handled by this [Window].
+  Stream<Event> get onInput => Element.inputEvent.forTarget(this);
+
+  /// Stream of `invalid` events handled by this [Window].
+  Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);
+
+  /// Stream of `keydown` events handled by this [Window].
+  Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);
+
+  /// Stream of `keypress` events handled by this [Window].
+  Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);
+
+  /// Stream of `keyup` events handled by this [Window].
+  Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);
+
+  /// Stream of `load` events handled by this [Window].
+  Stream<Event> get onLoad => Element.loadEvent.forTarget(this);
+
+  Stream<Event> get onLoadedData => Element.loadedDataEvent.forTarget(this);
+
+  Stream<Event> get onLoadedMetadata =>
+      Element.loadedMetadataEvent.forTarget(this);
+
+  Stream<Event> get onLoadStart => loadStartEvent.forTarget(this);
+
+  /// Stream of `message` events handled by this [Window].
+  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
+
+  /// Stream of `mousedown` events handled by this [Window].
+  Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);
+
+  /// Stream of `mouseenter` events handled by this [Window].
+  Stream<MouseEvent> get onMouseEnter =>
+      Element.mouseEnterEvent.forTarget(this);
+
+  /// Stream of `mouseleave` events handled by this [Window].
+  Stream<MouseEvent> get onMouseLeave =>
+      Element.mouseLeaveEvent.forTarget(this);
+
+  /// Stream of `mousemove` events handled by this [Window].
+  Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);
+
+  /// Stream of `mouseout` events handled by this [Window].
+  Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);
+
+  /// Stream of `mouseover` events handled by this [Window].
+  Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);
+
+  /// Stream of `mouseup` events handled by this [Window].
+  Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);
+
+  /// Stream of `mousewheel` events handled by this [Window].
+  Stream<WheelEvent> get onMouseWheel =>
+      Element.mouseWheelEvent.forTarget(this);
+
+  /// Stream of `offline` events handled by this [Window].
+  Stream<Event> get onOffline => offlineEvent.forTarget(this);
+
+  /// Stream of `online` events handled by this [Window].
+  Stream<Event> get onOnline => onlineEvent.forTarget(this);
+
+  /// Stream of `pagehide` events handled by this [Window].
+  Stream<Event> get onPageHide => pageHideEvent.forTarget(this);
+
+  /// Stream of `pageshow` events handled by this [Window].
+  Stream<Event> get onPageShow => pageShowEvent.forTarget(this);
+
+  Stream<Event> get onPause => Element.pauseEvent.forTarget(this);
+
+  Stream<Event> get onPlay => Element.playEvent.forTarget(this);
+
+  Stream<Event> get onPlaying => Element.playingEvent.forTarget(this);
+
+  /// Stream of `popstate` events handled by this [Window].
+  Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);
+
+  Stream<Event> get onProgress => progressEvent.forTarget(this);
+
+  Stream<Event> get onRateChange => Element.rateChangeEvent.forTarget(this);
+
+  /// Stream of `reset` events handled by this [Window].
+  Stream<Event> get onReset => Element.resetEvent.forTarget(this);
+
+  /// Stream of `resize` events handled by this [Window].
+  Stream<Event> get onResize => Element.resizeEvent.forTarget(this);
+
+  /// Stream of `scroll` events handled by this [Window].
+  Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);
+
+  /// Stream of `search` events handled by this [Window].
+  Stream<Event> get onSearch => Element.searchEvent.forTarget(this);
+
+  Stream<Event> get onSeeked => Element.seekedEvent.forTarget(this);
+
+  Stream<Event> get onSeeking => Element.seekingEvent.forTarget(this);
+
+  /// Stream of `select` events handled by this [Window].
+  Stream<Event> get onSelect => Element.selectEvent.forTarget(this);
+
+  Stream<Event> get onStalled => Element.stalledEvent.forTarget(this);
+
+  /// Stream of `storage` events handled by this [Window].
+  Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);
+
+  /// Stream of `submit` events handled by this [Window].
+  Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);
+
+  Stream<Event> get onSuspend => Element.suspendEvent.forTarget(this);
+
+  Stream<Event> get onTimeUpdate => Element.timeUpdateEvent.forTarget(this);
+
+  /// Stream of `touchcancel` events handled by this [Window].
+  Stream<TouchEvent> get onTouchCancel =>
+      Element.touchCancelEvent.forTarget(this);
+
+  /// Stream of `touchend` events handled by this [Window].
+  Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);
+
+  /// Stream of `touchmove` events handled by this [Window].
+  Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);
+
+  /// Stream of `touchstart` events handled by this [Window].
+  Stream<TouchEvent> get onTouchStart =>
+      Element.touchStartEvent.forTarget(this);
+
+  /// Stream of `transitionend` events handled by this [Window].
+  Stream<TransitionEvent> get onTransitionEnd =>
+      Element.transitionEndEvent.forTarget(this);
+
+  /// Stream of `unload` events handled by this [Window].
+  Stream<Event> get onUnload => unloadEvent.forTarget(this);
+
+  Stream<Event> get onVolumeChange => Element.volumeChangeEvent.forTarget(this);
+
+  Stream<Event> get onWaiting => Element.waitingEvent.forTarget(this);
+
+  /// Stream of `animationend` events handled by this [Window].
+  Stream<AnimationEvent> get onAnimationEnd =>
+      animationEndEvent.forTarget(this);
+
+  /// Stream of `animationiteration` events handled by this [Window].
+  Stream<AnimationEvent> get onAnimationIteration =>
+      animationIterationEvent.forTarget(this);
+
+  /// Stream of `animationstart` events handled by this [Window].
+  Stream<AnimationEvent> get onAnimationStart =>
+      animationStartEvent.forTarget(this);
+
+  /**
+   * Static factory designed to expose `beforeunload` events to event
+   * handlers that are not necessarily instances of [Window].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<BeforeUnloadEvent> beforeUnloadEvent =
+      const _BeforeUnloadEventStreamProvider('beforeunload');
+
+  /// Stream of `beforeunload` events handled by this [Window].
+  Stream<Event> get onBeforeUnload => beforeUnloadEvent.forTarget(this);
+
+  /// Stream of `wheel` events handled by this [Window].
+  Stream<WheelEvent> get onWheel => Element.wheelEvent.forTarget(this);
+
+  /**
+   * Moves this window to a specific position.
+   *
+   * x and y can be negative.
+   *
+   * ## Other resources
+   *
+   * * [Window.moveTo](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveTo)
+   *   from MDN.
+   * * [Window.moveTo](http://dev.w3.org/csswg/cssom-view/#dom-window-moveto)
+   *   from W3C.
+   */
+  void moveTo(Point p) {
+    _moveTo(p.x, p.y);
+  }
+
+  @JSName('openDatabase')
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Creates('SqlDatabase')
+  SqlDatabase openDatabase(
+      String name, String version, String displayName, int estimatedSize,
+      [DatabaseCallback creationCallback]) {
+    var db;
+    if (creationCallback == null)
+      db = _openDatabase(name, version, displayName, estimatedSize);
+    else
+      db = _openDatabase(
+          name, version, displayName, estimatedSize, creationCallback);
+
+    applyExtension('Database', db);
+
+    return db;
+  }
+
+  int get pageXOffset => JS<num>('num', '#.pageXOffset', this).round();
+
+  int get pageYOffset => JS<num>('num', '#.pageYOffset', this).round();
+
+  /**
+   * The distance this window has been scrolled horizontally.
+   *
+   * ## Other resources
+   *
+   * * [The Screen interface
+   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [scrollX](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)
+   *   from MDN.
+   */
+  int get scrollX => JS<bool>('bool', '("scrollX" in #)', this)
+      ? JS<num>('num', '#.scrollX', this).round()
+      : document.documentElement.scrollLeft;
+
+  /**
+   * The distance this window has been scrolled vertically.
+   *
+   * ## Other resources
+   *
+   * * [The Screen interface
+   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [scrollY](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)
+   *   from MDN.
+   */
+  int get scrollY => JS<bool>('bool', '("scrollY" in #)', this)
+      ? JS<num>('num', '#.scrollY', this).round()
+      : document.documentElement.scrollTop;
+}
+
+class _BeforeUnloadEvent extends _WrappedEvent implements BeforeUnloadEvent {
+  String _returnValue;
+
+  _BeforeUnloadEvent(Event base) : super(base);
+
+  String get returnValue => _returnValue;
+
+  set returnValue(String value) {
+    _returnValue = value;
+    // FF and IE use the value as the return value, Chrome will return this from
+    // the event callback function.
+    if (JS<bool>('bool', '("returnValue" in #)', wrapped)) {
+      JS('void', '#.returnValue = #', wrapped, value);
+    }
+  }
+}
+
+class _BeforeUnloadEventStreamProvider
+    implements EventStreamProvider<BeforeUnloadEvent> {
+  final String _eventType;
+
+  const _BeforeUnloadEventStreamProvider(this._eventType);
+
+  Stream<BeforeUnloadEvent> forTarget(EventTarget e, {bool useCapture: false}) {
+    // Specify the generic type for EventStream only in dart2js.
+    var stream = new _EventStream<BeforeUnloadEvent>(e, _eventType, useCapture);
+    var controller = new StreamController<BeforeUnloadEvent>(sync: true);
+
+    stream.listen((event) {
+      var wrapped = new _BeforeUnloadEvent(event);
+      controller.add(wrapped);
+    });
+
+    return controller.stream;
+  }
+
+  String getEventType(EventTarget target) {
+    return _eventType;
+  }
+
+  ElementStream<BeforeUnloadEvent> forElement(Element e,
+      {bool useCapture: false}) {
+    // Specify the generic type for _ElementEventStreamImpl only in dart2js.
+    return new _ElementEventStreamImpl<BeforeUnloadEvent>(
+        e, _eventType, useCapture);
+  }
+
+  ElementStream<BeforeUnloadEvent> _forElementList(ElementList<Element> e,
+      {bool useCapture: false}) {
+    // Specify the generic type for _ElementEventStreamImpl only in dart2js.
+    return new _ElementListEventStreamImpl<BeforeUnloadEvent>(
+        e, _eventType, useCapture);
+  }
+}
+// Copyright (c) 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.
+
+abstract class WindowBase64 extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory WindowBase64._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  String atob(String atob);
+
+  String btoa(String btoa);
+}
+// Copyright (c) 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.
+
+@Native("WindowClient")
+class WindowClient extends Client {
+  // To suppress missing implicit constructor warnings.
+  factory WindowClient._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool focused;
+
+  final String visibilityState;
+
+  Future<WindowClient> focus() =>
+      promiseToFuture<WindowClient>(JS("", "#.focus()", this));
+
+  Future<WindowClient> navigate(String url) =>
+      promiseToFuture<WindowClient>(JS("", "#.navigate(#)", this, url));
+}
+// Copyright (c) 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.
+
+abstract class WindowEventHandlers extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory WindowEventHandlers._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> hashChangeEvent =
+      const EventStreamProvider<Event>('hashchange');
+
+  static const EventStreamProvider<MessageEvent> messageEvent =
+      const EventStreamProvider<MessageEvent>('message');
+
+  static const EventStreamProvider<Event> offlineEvent =
+      const EventStreamProvider<Event>('offline');
+
+  static const EventStreamProvider<Event> onlineEvent =
+      const EventStreamProvider<Event>('online');
+
+  static const EventStreamProvider<PopStateEvent> popStateEvent =
+      const EventStreamProvider<PopStateEvent>('popstate');
+
+  static const EventStreamProvider<StorageEvent> storageEvent =
+      const EventStreamProvider<StorageEvent>('storage');
+
+  static const EventStreamProvider<Event> unloadEvent =
+      const EventStreamProvider<Event>('unload');
+
+  Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);
+
+  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
+
+  Stream<Event> get onOffline => offlineEvent.forTarget(this);
+
+  Stream<Event> get onOnline => onlineEvent.forTarget(this);
+
+  Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);
+
+  Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);
+
+  Stream<Event> get onUnload => unloadEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Native("Worker")
+class Worker extends EventTarget implements AbstractWorker {
+  // To suppress missing implicit constructor warnings.
+  factory Worker._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `error` events to event
+   * handlers that are not necessarily instances of [Worker].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  /**
+   * Static factory designed to expose `message` events to event
+   * handlers that are not necessarily instances of [Worker].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<MessageEvent> messageEvent =
+      const EventStreamProvider<MessageEvent>('message');
+
+  factory Worker(String scriptUrl) {
+    return Worker._create_1(scriptUrl);
+  }
+  static Worker _create_1(scriptUrl) =>
+      JS('Worker', 'new Worker(#)', scriptUrl);
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      JS('bool', '(typeof window.Worker != "undefined")');
+
+  void postMessage(/*any*/ message, [List<Object> transfer]) {
+    if (transfer != null) {
+      var message_1 = convertDartToNative_SerializedScriptValue(message);
+      _postMessage_1(message_1, transfer);
+      return;
+    }
+    var message_1 = convertDartToNative_SerializedScriptValue(message);
+    _postMessage_2(message_1);
+    return;
+  }
+
+  @JSName('postMessage')
+  void _postMessage_1(message, List<Object> transfer) native;
+  @JSName('postMessage')
+  void _postMessage_2(message) native;
+
+  void terminate() native;
+
+  /// Stream of `error` events handled by this [Worker].
+  Stream<Event> get onError => errorEvent.forTarget(this);
+
+  /// Stream of `message` events handled by this [Worker].
+  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("WorkerGlobalScope")
+class WorkerGlobalScope extends EventTarget
+    implements _WindowTimers, WindowBase64 {
+  // To suppress missing implicit constructor warnings.
+  factory WorkerGlobalScope._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `error` events to event
+   * handlers that are not necessarily instances of [WorkerGlobalScope].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  final String addressSpace;
+
+  final CacheStorage caches;
+
+  final Crypto crypto;
+
+  final IdbFactory indexedDB;
+
+  final bool isSecureContext;
+
+  final _WorkerLocation location;
+
+  final _WorkerNavigator navigator;
+
+  final String origin;
+
+  final WorkerPerformance performance;
+
+  final WorkerGlobalScope self;
+
+  Future fetch(/*RequestInfo*/ input, [Map init]) {
+    var init_dict = null;
+    if (init != null) {
+      init_dict = convertDartToNative_Dictionary(init);
+    }
+    return promiseToFuture(JS("", "#.fetch(#, #)", this, input, init_dict));
+  }
+
+  void importScripts(String urls) native;
+
+  // From WindowBase64
+
+  String atob(String atob) native;
+
+  String btoa(String btoa) native;
+
+  // From WindowTimers
+
+  @JSName('setInterval')
+  int _setInterval_String(String handler, [int timeout, Object arguments])
+      native;
+
+  @JSName('setTimeout')
+  int _setTimeout_String(String handler, [int timeout, Object arguments])
+      native;
+
+  @JSName('clearInterval')
+  void _clearInterval([int handle]) native;
+
+  @JSName('clearTimeout')
+  void _clearTimeout([int handle]) native;
+
+  @JSName('setInterval')
+  int _setInterval(Object handler, [int timeout]) native;
+
+  @JSName('setTimeout')
+  int _setTimeout(Object handler, [int timeout]) native;
+
+  /// Stream of `error` events handled by this [WorkerGlobalScope].
+  Stream<Event> get onError => errorEvent.forTarget(this);
+
+  static WorkerGlobalScope get instance => _workerSelf;
+}
+
+// Copyright (c) 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.
+
+@Native("WorkerPerformance")
+class WorkerPerformance extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory WorkerPerformance._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final MemoryInfo memory;
+
+  final num timeOrigin;
+
+  void clearMarks(String markName) native;
+
+  void clearMeasures(String measureName) native;
+
+  void clearResourceTimings() native;
+
+  List<PerformanceEntry> getEntries() native;
+
+  List<PerformanceEntry> getEntriesByName(String name, String entryType) native;
+
+  List<PerformanceEntry> getEntriesByType(String entryType) native;
+
+  void mark(String markName) native;
+
+  void measure(String measureName, String startMark, String endMark) native;
+
+  double now() native;
+
+  void setResourceTimingBufferSize(int maxSize) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("WorkletAnimation")
+class WorkletAnimation extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory WorkletAnimation._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory WorkletAnimation(
+      String animatorName,
+      List<KeyframeEffectReadOnly> effects,
+      List<Object> timelines,
+      /*SerializedScriptValue*/ options) {
+    var options_1 = convertDartToNative_SerializedScriptValue(options);
+    return WorkletAnimation._create_1(
+        animatorName, effects, timelines, options_1);
+  }
+  static WorkletAnimation _create_1(
+          animatorName, effects, timelines, options) =>
+      JS('WorkletAnimation', 'new WorkletAnimation(#,#,#,#)', animatorName,
+          effects, timelines, options);
+
+  final String playState;
+
+  void cancel() native;
+
+  void play() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("WorkletGlobalScope")
+class WorkletGlobalScope extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory WorkletGlobalScope._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathEvaluator
+@deprecated // experimental
+@Native("XPathEvaluator")
+class XPathEvaluator extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory XPathEvaluator._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory XPathEvaluator() {
+    return XPathEvaluator._create_1();
+  }
+  static XPathEvaluator _create_1() =>
+      JS('XPathEvaluator', 'new XPathEvaluator()');
+
+  XPathExpression createExpression(String expression, XPathNSResolver resolver)
+      native;
+
+  XPathNSResolver createNSResolver(Node nodeResolver) native;
+
+  XPathResult evaluate(
+      String expression, Node contextNode, XPathNSResolver resolver,
+      [int type, Object inResult]) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathExpression
+@deprecated // experimental
+@Native("XPathExpression")
+class XPathExpression extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory XPathExpression._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  XPathResult evaluate(Node contextNode, [int type, Object inResult]) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathNSResolver
+@deprecated // experimental
+@Native("XPathNSResolver")
+class XPathNSResolver extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory XPathNSResolver._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('lookupNamespaceURI')
+  String lookupNamespaceUri(String prefix) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathResult
+@deprecated // experimental
+@Native("XPathResult")
+class XPathResult extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory XPathResult._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int ANY_TYPE = 0;
+
+  static const int ANY_UNORDERED_NODE_TYPE = 8;
+
+  static const int BOOLEAN_TYPE = 3;
+
+  static const int FIRST_ORDERED_NODE_TYPE = 9;
+
+  static const int NUMBER_TYPE = 1;
+
+  static const int ORDERED_NODE_ITERATOR_TYPE = 5;
+
+  static const int ORDERED_NODE_SNAPSHOT_TYPE = 7;
+
+  static const int STRING_TYPE = 2;
+
+  static const int UNORDERED_NODE_ITERATOR_TYPE = 4;
+
+  static const int UNORDERED_NODE_SNAPSHOT_TYPE = 6;
+
+  final bool booleanValue;
+
+  final bool invalidIteratorState;
+
+  final num numberValue;
+
+  final int resultType;
+
+  final Node singleNodeValue;
+
+  final int snapshotLength;
+
+  final String stringValue;
+
+  Node iterateNext() native;
+
+  Node snapshotItem(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("XMLDocument")
+class XmlDocument extends Document {
+  // To suppress missing implicit constructor warnings.
+  factory XmlDocument._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+// http://domparsing.spec.whatwg.org/#the-xmlserializer-interface
+@deprecated // stable
+@Native("XMLSerializer")
+class XmlSerializer extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory XmlSerializer._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory XmlSerializer() {
+    return XmlSerializer._create_1();
+  }
+  static XmlSerializer _create_1() =>
+      JS('XmlSerializer', 'new XMLSerializer()');
+
+  String serializeToString(Node root) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@deprecated // nonstandard
+@Native("XSLTProcessor")
+class XsltProcessor extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory XsltProcessor._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory XsltProcessor() {
+    return XsltProcessor._create_1();
+  }
+  static XsltProcessor _create_1() =>
+      JS('XsltProcessor', 'new XSLTProcessor()');
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(window.XSLTProcessor)');
+
+  void clearParameters() native;
+
+  String getParameter(String namespaceURI, String localName) native;
+
+  void importStylesheet(Node style) native;
+
+  void removeParameter(String namespaceURI, String localName) native;
+
+  void reset() native;
+
+  void setParameter(String namespaceURI, String localName, String value) native;
+
+  Document transformToDocument(Node source) native;
+
+  DocumentFragment transformToFragment(Node source, Document output) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("Attr")
+class _Attr extends Node {
+  // To suppress missing implicit constructor warnings.
+  factory _Attr._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('localName')
+  final String _localName;
+
+  final String name;
+
+  @JSName('namespaceURI')
+  final String _namespaceUri;
+
+  String value;
+}
+// Copyright (c) 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.
+
+@Native("Bluetooth")
+abstract class _Bluetooth extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _Bluetooth._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("BluetoothCharacteristicProperties")
+abstract class _BluetoothCharacteristicProperties extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _BluetoothCharacteristicProperties._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("BluetoothDevice")
+abstract class _BluetoothDevice extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory _BluetoothDevice._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("BluetoothRemoteGATTCharacteristic")
+abstract class _BluetoothRemoteGATTCharacteristic extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory _BluetoothRemoteGATTCharacteristic._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("BluetoothRemoteGATTServer")
+abstract class _BluetoothRemoteGATTServer extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _BluetoothRemoteGATTServer._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("BluetoothRemoteGATTService")
+abstract class _BluetoothRemoteGATTService extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _BluetoothRemoteGATTService._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("BluetoothUUID")
+abstract class _BluetoothUUID extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _BluetoothUUID._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("BudgetService")
+class _BudgetService extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _BudgetService._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Future<BudgetState> getBudget() =>
+      promiseToFuture<BudgetState>(JS("", "#.getBudget()", this));
+
+  Future<double> getCost(String operation) =>
+      promiseToFuture<double>(JS("", "#.getCost(#)", this, operation));
+
+  Future<bool> reserve(String operation) =>
+      promiseToFuture<bool>(JS("", "#.reserve(#)", this, operation));
+}
+// Copyright (c) 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.
+
+@Native("Cache")
+abstract class _Cache extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _Cache._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+abstract class _CanvasPath extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _CanvasPath._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("Clipboard")
+class _Clipboard extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory _Clipboard._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Future<DataTransfer> read() =>
+      promiseToFuture<DataTransfer>(JS("", "#.read()", this));
+
+  Future<String> readText() =>
+      promiseToFuture<String>(JS("", "#.readText()", this));
+
+  Future write(DataTransfer data) =>
+      promiseToFuture(JS("", "#.write(#)", this, data));
+
+  Future writeText(String data) =>
+      promiseToFuture(JS("", "#.writeText(#)", this, data));
+}
+// Copyright (c) 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.
+
+@Native("CSSRuleList")
+class _CssRuleList extends Interceptor
+    with ListMixin<CssRule>, ImmutableListMixin<CssRule>
+    implements JavaScriptIndexingBehavior<CssRule>, List<CssRule> {
+  // To suppress missing implicit constructor warnings.
+  factory _CssRuleList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  CssRule operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return JS("CssRule", "#[#]", this, index);
+  }
+
+  void operator []=(int index, CssRule value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<CssRule> mixins.
+  // CssRule is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  CssRule get first {
+    if (this.length > 0) {
+      return JS('CssRule', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  CssRule get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('CssRule', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  CssRule get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('CssRule', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  CssRule elementAt(int index) => this[index];
+  // -- end List<CssRule> mixins.
+
+  CssRule item(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@Native("DOMFileSystemSync")
+abstract class _DOMFileSystemSync extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _DOMFileSystemSync._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("DirectoryEntrySync")
+abstract class _DirectoryEntrySync extends _EntrySync {
+  // To suppress missing implicit constructor warnings.
+  factory _DirectoryEntrySync._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("DirectoryReaderSync")
+abstract class _DirectoryReaderSync extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _DirectoryReaderSync._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+// http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-412266927
+@deprecated // stable
+@Native("DocumentType")
+abstract class _DocumentType extends Node implements ChildNode {
+  // To suppress missing implicit constructor warnings.
+  factory _DocumentType._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  // From ChildNode
+
+}
+
+// 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.
+
+@Native("ClientRect,DOMRect")
+class _DomRect extends DomRectReadOnly implements Rectangle {
+  // NOTE! All code below should be common with RectangleBase.
+  String toString() {
+    return 'Rectangle ($left, $top) $width x $height';
+  }
+
+  bool operator ==(other) {
+    if (other is! Rectangle) return false;
+    return left == other.left &&
+        top == other.top &&
+        width == other.width &&
+        height == other.height;
+  }
+
+  int get hashCode => _JenkinsSmiHash.hash4(
+      left.hashCode, top.hashCode, width.hashCode, height.hashCode);
+
+  /**
+   * Computes the intersection of `this` and [other].
+   *
+   * The intersection of two axis-aligned rectangles, if any, is always another
+   * axis-aligned rectangle.
+   *
+   * Returns the intersection of this and `other`, or null if they don't
+   * intersect.
+   */
+  Rectangle intersection(Rectangle other) {
+    var x0 = max(left, other.left);
+    var x1 = min(left + width, other.left + other.width);
+
+    if (x0 <= x1) {
+      var y0 = max(top, other.top);
+      var y1 = min(top + height, other.top + other.height);
+
+      if (y0 <= y1) {
+        return new Rectangle(x0, y0, x1 - x0, y1 - y0);
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Returns true if `this` intersects [other].
+   */
+  bool intersects(Rectangle<num> other) {
+    return (left <= other.left + other.width &&
+        other.left <= left + width &&
+        top <= other.top + other.height &&
+        other.top <= top + height);
+  }
+
+  /**
+   * Returns a new rectangle which completely contains `this` and [other].
+   */
+  Rectangle boundingBox(Rectangle other) {
+    var right = max(this.left + this.width, other.left + other.width);
+    var bottom = max(this.top + this.height, other.top + other.height);
+
+    var left = min(this.left, other.left);
+    var top = min(this.top, other.top);
+
+    return new Rectangle(left, top, right - left, bottom - top);
+  }
+
+  /**
+   * Tests whether `this` entirely contains [another].
+   */
+  bool containsRectangle(Rectangle<num> another) {
+    return left <= another.left &&
+        left + width >= another.left + another.width &&
+        top <= another.top &&
+        top + height >= another.top + another.height;
+  }
+
+  /**
+   * Tests whether [another] is inside or along the edges of `this`.
+   */
+  bool containsPoint(Point<num> another) {
+    return another.x >= left &&
+        another.x <= left + width &&
+        another.y >= top &&
+        another.y <= top + height;
+  }
+
+  Point get topLeft => new Point(this.left, this.top);
+  Point get topRight => new Point(this.left + this.width, this.top);
+  Point get bottomRight =>
+      new Point(this.left + this.width, this.top + this.height);
+  Point get bottomLeft => new Point(this.left, this.top + this.height);
+
+  // To suppress missing implicit constructor warnings.
+  factory _DomRect._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory _DomRect([num x, num y, num width, num height]) {
+    if (height != null) {
+      return _DomRect._create_1(x, y, width, height);
+    }
+    if (width != null) {
+      return _DomRect._create_2(x, y, width);
+    }
+    if (y != null) {
+      return _DomRect._create_3(x, y);
+    }
+    if (x != null) {
+      return _DomRect._create_4(x);
+    }
+    return _DomRect._create_5();
+  }
+  static _DomRect _create_1(x, y, width, height) =>
+      JS('_DomRect', 'new DOMRect(#,#,#,#)', x, y, width, height);
+  static _DomRect _create_2(x, y, width) =>
+      JS('_DomRect', 'new DOMRect(#,#,#)', x, y, width);
+  static _DomRect _create_3(x, y) => JS('_DomRect', 'new DOMRect(#,#)', x, y);
+  static _DomRect _create_4(x) => JS('_DomRect', 'new DOMRect(#)', x);
+  static _DomRect _create_5() => JS('_DomRect', 'new DOMRect()');
+
+  // Shadowing definition.
+  num get height => JS("num", "#.height", this);
+
+  set height(num value) {
+    JS("void", "#.height = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get width => JS("num", "#.width", this);
+
+  set width(num value) {
+    JS("void", "#.width = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get x => JS("num", "#.x", this);
+
+  set x(num value) {
+    JS("void", "#.x = #", this, value);
+  }
+
+  // Shadowing definition.
+  num get y => JS("num", "#.y", this);
+
+  set y(num value) {
+    JS("void", "#.y = #", this, value);
+  }
+}
+
+/**
+ * This is the [Jenkins hash function][1] but using masking to keep
+ * values in SMI range.
+ *
+ * [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
+ *
+ * Use:
+ * Hash each value with the hash of the previous value, then get the final
+ * hash by calling finish.
+ *
+ *     var hash = 0;
+ *     for (var value in values) {
+ *       hash = JenkinsSmiHash.combine(hash, value.hashCode);
+ *     }
+ *     hash = JenkinsSmiHash.finish(hash);
+ */
+class _JenkinsSmiHash {
+  // TODO(11617): This class should be optimized and standardized elsewhere.
+
+  static int combine(int hash, int value) {
+    hash = 0x1fffffff & (hash + value);
+    hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
+    return hash ^ (hash >> 6);
+  }
+
+  static int finish(int hash) {
+    hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
+    hash = hash ^ (hash >> 11);
+    return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
+  }
+
+  static int hash2(a, b) => finish(combine(combine(0, a), b));
+
+  static int hash4(a, b, c, d) =>
+      finish(combine(combine(combine(combine(0, a), b), c), d));
+}
+// Copyright (c) 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.
+
+@Native("EntrySync")
+abstract class _EntrySync extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _EntrySync._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("FileEntrySync")
+abstract class _FileEntrySync extends _EntrySync {
+  // To suppress missing implicit constructor warnings.
+  factory _FileEntrySync._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("FileReaderSync")
+abstract class _FileReaderSync extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _FileReaderSync._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory _FileReaderSync() {
+    return _FileReaderSync._create_1();
+  }
+  static _FileReaderSync _create_1() =>
+      JS('_FileReaderSync', 'new FileReaderSync()');
+}
+// Copyright (c) 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.
+
+@Native("FileWriterSync")
+abstract class _FileWriterSync extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _FileWriterSync._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("GamepadList")
+class _GamepadList extends Interceptor
+    with ListMixin<Gamepad>, ImmutableListMixin<Gamepad>
+    implements List<Gamepad>, JavaScriptIndexingBehavior<Gamepad> {
+  // To suppress missing implicit constructor warnings.
+  factory _GamepadList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  Gamepad operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return JS("Gamepad|Null", "#[#]", this, index);
+  }
+
+  void operator []=(int index, Gamepad value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<Gamepad> mixins.
+  // Gamepad is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  Gamepad get first {
+    if (this.length > 0) {
+      return JS('Gamepad|Null', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  Gamepad get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('Gamepad|Null', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  Gamepad get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('Gamepad|Null', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  Gamepad elementAt(int index) => this[index];
+  // -- end List<Gamepad> mixins.
+
+  Gamepad item(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dom-document-all
+@deprecated // deprecated
+@Native("HTMLAllCollection")
+abstract class _HTMLAllCollection extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _HTMLAllCollection._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('item')
+  Element _item(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dir
+@deprecated // deprecated
+@Native("HTMLDirectoryElement")
+abstract class _HTMLDirectoryElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory _HTMLDirectoryElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLDirectoryElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#htmlfontelement
+@deprecated // deprecated
+@Native("HTMLFontElement")
+abstract class _HTMLFontElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory _HTMLFontElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLFontElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#htmlframeelement
+@deprecated // deprecated
+@Native("HTMLFrameElement")
+abstract class _HTMLFrameElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory _HTMLFrameElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLFrameElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#frameset
+@deprecated // deprecated
+@Native("HTMLFrameSetElement")
+abstract class _HTMLFrameSetElement extends HtmlElement
+    implements WindowEventHandlers {
+  // To suppress missing implicit constructor warnings.
+  factory _HTMLFrameSetElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLFrameSetElement.created() : super.created();
+}
+
+// Copyright (c) 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.
+
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#the-marquee-element
+@deprecated // deprecated
+@Native("HTMLMarqueeElement")
+abstract class _HTMLMarqueeElement extends HtmlElement {
+  // To suppress missing implicit constructor warnings.
+  factory _HTMLMarqueeElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLMarqueeElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Native("Mojo")
+abstract class _Mojo extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _Mojo._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("MojoHandle")
+abstract class _MojoHandle extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _MojoHandle._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("MojoInterfaceInterceptor")
+abstract class _MojoInterfaceInterceptor extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory _MojoInterfaceInterceptor._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory _MojoInterfaceInterceptor(String interfaceName, [String scope]) {
+    if (scope != null) {
+      return _MojoInterfaceInterceptor._create_1(interfaceName, scope);
+    }
+    return _MojoInterfaceInterceptor._create_2(interfaceName);
+  }
+  static _MojoInterfaceInterceptor _create_1(interfaceName, scope) => JS(
+      '_MojoInterfaceInterceptor',
+      'new MojoInterfaceInterceptor(#,#)',
+      interfaceName,
+      scope);
+  static _MojoInterfaceInterceptor _create_2(interfaceName) => JS(
+      '_MojoInterfaceInterceptor',
+      'new MojoInterfaceInterceptor(#)',
+      interfaceName);
+}
+// Copyright (c) 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.
+
+@Native("MojoInterfaceRequestEvent")
+abstract class _MojoInterfaceRequestEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory _MojoInterfaceRequestEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory _MojoInterfaceRequestEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return _MojoInterfaceRequestEvent._create_1(type, eventInitDict_1);
+    }
+    return _MojoInterfaceRequestEvent._create_2(type);
+  }
+  static _MojoInterfaceRequestEvent _create_1(type, eventInitDict) => JS(
+      '_MojoInterfaceRequestEvent',
+      'new MojoInterfaceRequestEvent(#,#)',
+      type,
+      eventInitDict);
+  static _MojoInterfaceRequestEvent _create_2(type) => JS(
+      '_MojoInterfaceRequestEvent', 'new MojoInterfaceRequestEvent(#)', type);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("MojoWatcher")
+abstract class _MojoWatcher extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _MojoWatcher._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("NFC")
+abstract class _NFC extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _NFC._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+// http://dom.spec.whatwg.org/#namednodemap
+@deprecated // deprecated
+@Native("NamedNodeMap,MozNamedAttrMap")
+class _NamedNodeMap extends Interceptor
+    with ListMixin<Node>, ImmutableListMixin<Node>
+    implements JavaScriptIndexingBehavior<Node>, List<Node> {
+  // To suppress missing implicit constructor warnings.
+  factory _NamedNodeMap._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  Node operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return JS("Node", "#[#]", this, index);
+  }
+
+  void operator []=(int index, Node value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<Node> mixins.
+  // Node is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  Node get first {
+    if (this.length > 0) {
+      return JS('Node', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  Node get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('Node', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  Node get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('Node', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  Node elementAt(int index) => this[index];
+  // -- end List<Node> mixins.
+
+  _Attr getNamedItem(String name) native;
+
+  _Attr getNamedItemNS(String namespaceURI, String localName) native;
+
+  _Attr item(int index) native;
+
+  _Attr removeNamedItem(String name) native;
+
+  _Attr removeNamedItemNS(String namespaceURI, String localName) native;
+
+  _Attr setNamedItem(_Attr attr) native;
+
+  _Attr setNamedItemNS(_Attr attr) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@deprecated // nonstandard
+@Native("PagePopupController")
+abstract class _PagePopupController extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _PagePopupController._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// 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.
+
+// Omit RadioNodeList for dart2js.  The Dart Form and FieldSet APIs don't
+// currently expose an API the returns RadioNodeList.  The only use of a
+// RadioNodeList is to get the selected value and it will be cleaner to
+// introduce a different API for that purpose.
+// Copyright (c) 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.
+
+@Native("Report")
+class _Report extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _Report._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final ReportBody body;
+
+  final String type;
+
+  final String url;
+}
+// Copyright (c) 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.
+
+@Native("Request")
+class _Request extends Body {
+  // To suppress missing implicit constructor warnings.
+  factory _Request._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory _Request(Object input, [Map requestInitDict]) {
+    if (requestInitDict != null) {
+      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict);
+      return _Request._create_1(input, requestInitDict_1);
+    }
+    return _Request._create_2(input);
+  }
+  static _Request _create_1(input, requestInitDict) =>
+      JS('_Request', 'new Request(#,#)', input, requestInitDict);
+  static _Request _create_2(input) => JS('_Request', 'new Request(#)', input);
+
+  final String cache;
+
+  final String credentials;
+
+  final Headers headers;
+
+  final String integrity;
+
+  final String mode;
+
+  final String redirect;
+
+  final String referrer;
+
+  final String referrerPolicy;
+
+  final String url;
+
+  _Request clone() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// https://chromiumcodereview.appspot.com/14773025/
+@deprecated // experimental
+@Native("ResourceProgressEvent")
+abstract class _ResourceProgressEvent extends ProgressEvent {
+  // To suppress missing implicit constructor warnings.
+  factory _ResourceProgressEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("Response")
+abstract class _Response extends Body {
+  // To suppress missing implicit constructor warnings.
+  factory _Response._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory _Response([Object body, Map init]) {
+    if (init != null) {
+      var init_1 = convertDartToNative_Dictionary(init);
+      return _Response._create_1(body, init_1);
+    }
+    if (body != null) {
+      return _Response._create_2(body);
+    }
+    return _Response._create_3();
+  }
+  static _Response _create_1(body, init) =>
+      JS('_Response', 'new Response(#,#)', body, init);
+  static _Response _create_2(body) => JS('_Response', 'new Response(#)', body);
+  static _Response _create_3() => JS('_Response', 'new Response()');
+}
+// Copyright (c) 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.
+
+@Native("SpeechRecognitionResultList")
+class _SpeechRecognitionResultList extends Interceptor
+    with
+        ListMixin<SpeechRecognitionResult>,
+        ImmutableListMixin<SpeechRecognitionResult>
+    implements
+        JavaScriptIndexingBehavior<SpeechRecognitionResult>,
+        List<SpeechRecognitionResult> {
+  // To suppress missing implicit constructor warnings.
+  factory _SpeechRecognitionResultList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  SpeechRecognitionResult operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return JS("SpeechRecognitionResult", "#[#]", this, index);
+  }
+
+  void operator []=(int index, SpeechRecognitionResult value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<SpeechRecognitionResult> mixins.
+  // SpeechRecognitionResult is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  SpeechRecognitionResult get first {
+    if (this.length > 0) {
+      return JS('SpeechRecognitionResult', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  SpeechRecognitionResult get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('SpeechRecognitionResult', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  SpeechRecognitionResult get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('SpeechRecognitionResult', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  SpeechRecognitionResult elementAt(int index) => this[index];
+  // -- end List<SpeechRecognitionResult> mixins.
+
+  SpeechRecognitionResult item(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("StyleSheetList")
+class _StyleSheetList extends Interceptor
+    with ListMixin<StyleSheet>, ImmutableListMixin<StyleSheet>
+    implements List<StyleSheet>, JavaScriptIndexingBehavior<StyleSheet> {
+  // To suppress missing implicit constructor warnings.
+  factory _StyleSheetList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  StyleSheet operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return JS("StyleSheet", "#[#]", this, index);
+  }
+
+  void operator []=(int index, StyleSheet value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<StyleSheet> mixins.
+  // StyleSheet is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  StyleSheet get first {
+    if (this.length > 0) {
+      return JS('StyleSheet', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  StyleSheet get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('StyleSheet', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  StyleSheet get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('StyleSheet', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  StyleSheet elementAt(int index) => this[index];
+  // -- end List<StyleSheet> mixins.
+
+  CssStyleSheet __getter__(String name) native;
+
+  StyleSheet item(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("SubtleCrypto")
+abstract class _SubtleCrypto extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _SubtleCrypto._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("USB")
+abstract class _USB extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory _USB._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("USBAlternateInterface")
+abstract class _USBAlternateInterface extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _USBAlternateInterface._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory _USBAlternateInterface(
+      _USBInterface deviceInterface, int alternateSetting) {
+    return _USBAlternateInterface._create_1(deviceInterface, alternateSetting);
+  }
+  static _USBAlternateInterface _create_1(deviceInterface, alternateSetting) =>
+      JS('_USBAlternateInterface', 'new USBAlternateInterface(#,#)',
+          deviceInterface, alternateSetting);
+}
+// Copyright (c) 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.
+
+@Native("USBConfiguration")
+abstract class _USBConfiguration extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _USBConfiguration._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory _USBConfiguration(_USBDevice device, int configurationValue) {
+    return _USBConfiguration._create_1(device, configurationValue);
+  }
+  static _USBConfiguration _create_1(device, configurationValue) => JS(
+      '_USBConfiguration',
+      'new USBConfiguration(#,#)',
+      device,
+      configurationValue);
+}
+// Copyright (c) 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.
+
+@Native("USBConnectionEvent")
+abstract class _USBConnectionEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory _USBConnectionEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory _USBConnectionEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return _USBConnectionEvent._create_1(type, eventInitDict_1);
+  }
+  static _USBConnectionEvent _create_1(type, eventInitDict) => JS(
+      '_USBConnectionEvent',
+      'new USBConnectionEvent(#,#)',
+      type,
+      eventInitDict);
+}
+// Copyright (c) 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.
+
+@Native("USBDevice")
+abstract class _USBDevice extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _USBDevice._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("USBEndpoint")
+abstract class _USBEndpoint extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _USBEndpoint._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory _USBEndpoint(
+      _USBAlternateInterface alternate, int endpointNumber, String direction) {
+    return _USBEndpoint._create_1(alternate, endpointNumber, direction);
+  }
+  static _USBEndpoint _create_1(alternate, endpointNumber, direction) => JS(
+      '_USBEndpoint',
+      'new USBEndpoint(#,#,#)',
+      alternate,
+      endpointNumber,
+      direction);
+}
+// Copyright (c) 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.
+
+@Native("USBInTransferResult")
+abstract class _USBInTransferResult extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _USBInTransferResult._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory _USBInTransferResult(String status, [ByteData data]) {
+    if (data != null) {
+      return _USBInTransferResult._create_1(status, data);
+    }
+    return _USBInTransferResult._create_2(status);
+  }
+  static _USBInTransferResult _create_1(status, data) =>
+      JS('_USBInTransferResult', 'new USBInTransferResult(#,#)', status, data);
+  static _USBInTransferResult _create_2(status) =>
+      JS('_USBInTransferResult', 'new USBInTransferResult(#)', status);
+}
+// Copyright (c) 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.
+
+@Native("USBInterface")
+abstract class _USBInterface extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _USBInterface._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory _USBInterface(_USBConfiguration configuration, int interfaceNumber) {
+    return _USBInterface._create_1(configuration, interfaceNumber);
+  }
+  static _USBInterface _create_1(configuration, interfaceNumber) => JS(
+      '_USBInterface', 'new USBInterface(#,#)', configuration, interfaceNumber);
+}
+// Copyright (c) 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.
+
+@Native("USBIsochronousInTransferPacket")
+abstract class _USBIsochronousInTransferPacket extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _USBIsochronousInTransferPacket._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory _USBIsochronousInTransferPacket(String status, [ByteData data]) {
+    if (data != null) {
+      return _USBIsochronousInTransferPacket._create_1(status, data);
+    }
+    return _USBIsochronousInTransferPacket._create_2(status);
+  }
+  static _USBIsochronousInTransferPacket _create_1(status, data) => JS(
+      '_USBIsochronousInTransferPacket',
+      'new USBIsochronousInTransferPacket(#,#)',
+      status,
+      data);
+  static _USBIsochronousInTransferPacket _create_2(status) => JS(
+      '_USBIsochronousInTransferPacket',
+      'new USBIsochronousInTransferPacket(#)',
+      status);
+}
+// Copyright (c) 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.
+
+@Native("USBIsochronousInTransferResult")
+abstract class _USBIsochronousInTransferResult extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _USBIsochronousInTransferResult._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory _USBIsochronousInTransferResult(
+      List<_USBIsochronousInTransferPacket> packets,
+      [ByteData data]) {
+    if (data != null) {
+      return _USBIsochronousInTransferResult._create_1(packets, data);
+    }
+    return _USBIsochronousInTransferResult._create_2(packets);
+  }
+  static _USBIsochronousInTransferResult _create_1(packets, data) => JS(
+      '_USBIsochronousInTransferResult',
+      'new USBIsochronousInTransferResult(#,#)',
+      packets,
+      data);
+  static _USBIsochronousInTransferResult _create_2(packets) => JS(
+      '_USBIsochronousInTransferResult',
+      'new USBIsochronousInTransferResult(#)',
+      packets);
+}
+// Copyright (c) 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.
+
+@Native("USBIsochronousOutTransferPacket")
+abstract class _USBIsochronousOutTransferPacket extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _USBIsochronousOutTransferPacket._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory _USBIsochronousOutTransferPacket(String status, [int bytesWritten]) {
+    if (bytesWritten != null) {
+      return _USBIsochronousOutTransferPacket._create_1(status, bytesWritten);
+    }
+    return _USBIsochronousOutTransferPacket._create_2(status);
+  }
+  static _USBIsochronousOutTransferPacket _create_1(status, bytesWritten) => JS(
+      '_USBIsochronousOutTransferPacket',
+      'new USBIsochronousOutTransferPacket(#,#)',
+      status,
+      bytesWritten);
+  static _USBIsochronousOutTransferPacket _create_2(status) => JS(
+      '_USBIsochronousOutTransferPacket',
+      'new USBIsochronousOutTransferPacket(#)',
+      status);
+}
+// Copyright (c) 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.
+
+@Native("USBIsochronousOutTransferResult")
+abstract class _USBIsochronousOutTransferResult extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _USBIsochronousOutTransferResult._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory _USBIsochronousOutTransferResult(
+      List<_USBIsochronousOutTransferPacket> packets) {
+    return _USBIsochronousOutTransferResult._create_1(packets);
+  }
+  static _USBIsochronousOutTransferResult _create_1(packets) => JS(
+      '_USBIsochronousOutTransferResult',
+      'new USBIsochronousOutTransferResult(#)',
+      packets);
+}
+// Copyright (c) 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.
+
+@Native("USBOutTransferResult")
+abstract class _USBOutTransferResult extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _USBOutTransferResult._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory _USBOutTransferResult(String status, [int bytesWritten]) {
+    if (bytesWritten != null) {
+      return _USBOutTransferResult._create_1(status, bytesWritten);
+    }
+    return _USBOutTransferResult._create_2(status);
+  }
+  static _USBOutTransferResult _create_1(status, bytesWritten) => JS(
+      '_USBOutTransferResult',
+      'new USBOutTransferResult(#,#)',
+      status,
+      bytesWritten);
+  static _USBOutTransferResult _create_2(status) =>
+      JS('_USBOutTransferResult', 'new USBOutTransferResult(#)', status);
+}
+// Copyright (c) 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.
+
+abstract class _WindowTimers extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _WindowTimers._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int _setInterval_String(String handler, [int timeout, Object arguments]);
+
+  int _setTimeout_String(String handler, [int timeout, Object arguments]);
+
+  void _clearInterval([int handle]);
+
+  void _clearTimeout([int handle]);
+
+  int _setInterval(Object handler, [int timeout]);
+
+  int _setTimeout(Object handler, [int timeout]);
+}
+// Copyright (c) 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.
+
+@Native("WorkerLocation")
+abstract class _WorkerLocation extends Interceptor implements UrlUtilsReadOnly {
+  // To suppress missing implicit constructor warnings.
+  factory _WorkerLocation._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  // From URLUtilsReadOnly
+
+}
+
+// Copyright (c) 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.
+
+@Native("WorkerNavigator")
+abstract class _WorkerNavigator extends NavigatorConcurrentHardware
+    implements NavigatorOnLine, NavigatorID {
+  // To suppress missing implicit constructor warnings.
+  factory _WorkerNavigator._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  // From NavigatorID
+
+  // From NavigatorOnLine
+
+}
+
+// Copyright (c) 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.
+
+@Native("Worklet")
+abstract class _Worklet extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _Worklet._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+abstract class _AttributeMap extends MapBase<String, String> {
+  final Element _element;
+
+  _AttributeMap(this._element);
+
+  void addAll(Map<String, String> other) {
+    other.forEach((k, v) {
+      this[k] = v;
+    });
+  }
+
+  Map<K, V> cast<K, V>() => Map.castFrom<String, String, K, V>(this);
+  bool containsValue(Object value) {
+    for (var v in this.values) {
+      if (value == v) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  String putIfAbsent(String key, String ifAbsent()) {
+    if (!containsKey(key)) {
+      this[key] = ifAbsent();
+    }
+    return this[key];
+  }
+
+  void clear() {
+    for (var key in keys) {
+      remove(key);
+    }
+  }
+
+  void forEach(void f(String key, String value)) {
+    for (var key in keys) {
+      var value = this[key];
+      f(key, value);
+    }
+  }
+
+  Iterable<String> get keys {
+    // TODO: generate a lazy collection instead.
+    var attributes = _element._attributes;
+    var keys = <String>[];
+    for (int i = 0, len = attributes.length; i < len; i++) {
+      _Attr attr = attributes[i];
+      if (_matches(attr)) {
+        keys.add(attr.name);
+      }
+    }
+    return keys;
+  }
+
+  Iterable<String> get values {
+    // TODO: generate a lazy collection instead.
+    var attributes = _element._attributes;
+    var values = <String>[];
+    for (int i = 0, len = attributes.length; i < len; i++) {
+      _Attr attr = attributes[i];
+      if (_matches(attr)) {
+        values.add(attr.value);
+      }
+    }
+    return values;
+  }
+
+  /**
+   * Returns true if there is no {key, value} pair in the map.
+   */
+  bool get isEmpty {
+    return length == 0;
+  }
+
+  /**
+   * Returns true if there is at least one {key, value} pair in the map.
+   */
+  bool get isNotEmpty => !isEmpty;
+
+  /**
+   * Checks to see if the node should be included in this map.
+   */
+  bool _matches(_Attr node);
+}
+
+/**
+ * Wrapper to expose [Element.attributes] as a typed map.
+ */
+class _ElementAttributeMap extends _AttributeMap {
+  _ElementAttributeMap(Element element) : super(element);
+
+  bool containsKey(Object key) {
+    return _element._hasAttribute(key);
+  }
+
+  String operator [](Object key) {
+    return _element.getAttribute(key);
+  }
+
+  void operator []=(String key, String value) {
+    _element.setAttribute(key, value);
+  }
+
+  @pragma('dart2js:tryInline')
+  String remove(Object key) => key is String ? _remove(_element, key) : null;
+
+  /**
+   * The number of {key, value} pairs in the map.
+   */
+  int get length {
+    return keys.length;
+  }
+
+  bool _matches(_Attr node) => node._namespaceUri == null;
+
+  // Inline this because almost all call sites of [remove] do not use [value],
+  // and the annotations on the `getAttribute` call allow it to be removed.
+  @pragma('dart2js:tryInline')
+  static String _remove(Element element, String key) {
+    String value = JS(
+        // throws:null(1) is not accurate since [key] could be malformed, but
+        // [key] is checked again by `removeAttributeNS`.
+        'returns:String|Null;depends:all;effects:none;throws:null(1)',
+        '#.getAttribute(#)',
+        element,
+        key);
+    JS('', '#.removeAttribute(#)', element, key);
+    return value;
+  }
+}
+
+/**
+ * Wrapper to expose namespaced attributes as a typed map.
+ */
+class _NamespacedAttributeMap extends _AttributeMap {
+  final String _namespace;
+
+  _NamespacedAttributeMap(Element element, this._namespace) : super(element);
+
+  bool containsKey(Object key) {
+    return _element._hasAttributeNS(_namespace, key);
+  }
+
+  String operator [](Object key) {
+    return _element.getAttributeNS(_namespace, key);
+  }
+
+  void operator []=(String key, String value) {
+    _element.setAttributeNS(_namespace, key, value);
+  }
+
+  @pragma('dart2js:tryInline')
+  String remove(Object key) =>
+      key is String ? _remove(_namespace, _element, key) : null;
+
+  /**
+   * The number of {key, value} pairs in the map.
+   */
+  int get length {
+    return keys.length;
+  }
+
+  bool _matches(_Attr node) => node._namespaceUri == _namespace;
+
+  // Inline this because almost all call sites of [remove] do not use the
+  // returned [value], and the annotations on the `getAttributeNS` call allow it
+  // to be removed.
+  @pragma('dart2js:tryInline')
+  static String _remove(String namespace, Element element, String key) {
+    String value = JS(
+        // throws:null(1) is not accurate since [key] could be malformed, but
+        // [key] is checked again by `removeAttributeNS`.
+        'returns:String|Null;depends:all;effects:none;throws:null(1)',
+        '#.getAttributeNS(#, #)',
+        element,
+        namespace,
+        key);
+    JS('', '#.removeAttributeNS(#, #)', element, namespace, key);
+    return value;
+  }
+}
+
+/**
+ * Provides a Map abstraction on top of data-* attributes, similar to the
+ * dataSet in the old DOM.
+ */
+class _DataAttributeMap extends MapBase<String, String> {
+  final Map<String, String> _attributes;
+
+  _DataAttributeMap(this._attributes);
+
+  // interface Map
+
+  void addAll(Map<String, String> other) {
+    other.forEach((k, v) {
+      this[k] = v;
+    });
+  }
+
+  Map<K, V> cast<K, V>() => Map.castFrom<String, String, K, V>(this);
+  // TODO: Use lazy iterator when it is available on Map.
+  bool containsValue(Object value) => values.any((v) => v == value);
+
+  bool containsKey(Object key) => _attributes.containsKey(_attr(key));
+
+  String operator [](Object key) => _attributes[_attr(key)];
+
+  void operator []=(String key, String value) {
+    _attributes[_attr(key)] = value;
+  }
+
+  String putIfAbsent(String key, String ifAbsent()) =>
+      _attributes.putIfAbsent(_attr(key), ifAbsent);
+
+  String remove(Object key) => _attributes.remove(_attr(key));
+
+  void clear() {
+    // Needs to operate on a snapshot since we are mutating the collection.
+    for (String key in keys) {
+      remove(key);
+    }
+  }
+
+  void forEach(void f(String key, String value)) {
+    _attributes.forEach((String key, String value) {
+      if (_matches(key)) {
+        f(_strip(key), value);
+      }
+    });
+  }
+
+  Iterable<String> get keys {
+    final keys = <String>[];
+    _attributes.forEach((String key, String value) {
+      if (_matches(key)) {
+        keys.add(_strip(key));
+      }
+    });
+    return keys;
+  }
+
+  Iterable<String> get values {
+    final values = <String>[];
+    _attributes.forEach((String key, String value) {
+      if (_matches(key)) {
+        values.add(value);
+      }
+    });
+    return values;
+  }
+
+  int get length => keys.length;
+
+  // TODO: Use lazy iterator when it is available on Map.
+  bool get isEmpty => length == 0;
+
+  bool get isNotEmpty => !isEmpty;
+
+  // Helpers.
+  String _attr(String key) => 'data-${_toHyphenedName(key)}';
+  bool _matches(String key) => key.startsWith('data-');
+  String _strip(String key) => _toCamelCase(key.substring(5));
+
+  /**
+   * Converts a string name with hyphens into an identifier, by removing hyphens
+   * and capitalizing the following letter. Optionally [startUppercase] to
+   * capitalize the first letter.
+   */
+  String _toCamelCase(String hyphenedName, {bool startUppercase: false}) {
+    var segments = hyphenedName.split('-');
+    int start = startUppercase ? 0 : 1;
+    for (int i = start; i < segments.length; i++) {
+      var segment = segments[i];
+      if (segment.length > 0) {
+        // Character between 'a'..'z' mapped to 'A'..'Z'
+        segments[i] = '${segment[0].toUpperCase()}${segment.substring(1)}';
+      }
+    }
+    return segments.join('');
+  }
+
+  /** Reverse of [toCamelCase]. */
+  String _toHyphenedName(String word) {
+    var sb = new StringBuffer();
+    for (int i = 0; i < word.length; i++) {
+      var lower = word[i].toLowerCase();
+      if (word[i] != lower && i > 0) sb.write('-');
+      sb.write(lower);
+    }
+    return sb.toString();
+  }
+}
+// Copyright (c) 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.
+
+/**
+ * An object that can be drawn to a 2D canvas rendering context.
+ *
+ * The image drawn to the canvas depends on the type of this object:
+ *
+ * * If this object is an [ImageElement], then this element's image is
+ * drawn to the canvas. If this element is an animated image, then this
+ * element's poster frame is drawn. If this element has no poster frame, then
+ * the first frame of animation is drawn.
+ *
+ * * If this object is a [VideoElement], then the frame at this element's current
+ * playback position is drawn to the canvas.
+ *
+ * * If this object is a [CanvasElement], then this element's bitmap is drawn to
+ * the canvas.
+ *
+ * **Note:** Currently all versions of Internet Explorer do not support
+ * drawing a video element to a canvas. You may also encounter problems drawing
+ * a video to a canvas in Firefox if the source of the video is a data URL.
+ *
+ * ## See also
+ *
+ * * [CanvasRenderingContext2D.drawImage]
+ * * [CanvasRenderingContext2D.drawImageToRect]
+ * * [CanvasRenderingContext2D.drawImageScaled]
+ * * [CanvasRenderingContext2D.drawImageScaledFromSource]
+ *
+ * ## Other resources
+ *
+ * * [Image sources for 2D rendering
+ *   contexts](https://html.spec.whatwg.org/multipage/scripting.html#image-sources-for-2d-rendering-contexts)
+ *   from WHATWG.
+ * * [Drawing images](https://html.spec.whatwg.org/multipage/scripting.html#dom-context-2d-drawimage)
+ *   from WHATWG.
+ */
+abstract class CanvasImageSource {}
+// Copyright (c) 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.
+
+/**
+ * Top-level container for a browser tab or window.
+ *
+ * In a web browser, a [WindowBase] object represents any browser window. This
+ * object contains the window's state and its relation to other
+ * windows, such as which window opened this window.
+ *
+ * **Note:** This class represents any window, while [Window] is
+ * used to access the properties and content of the current window or tab.
+ *
+ * ## See also
+ *
+ * * [Window]
+ *
+ * ## Other resources
+ *
+ * * [DOM Window](https://developer.mozilla.org/en-US/docs/DOM/window) from MDN.
+ * * [Window](http://www.w3.org/TR/Window/) from the W3C.
+ */
+abstract class WindowBase implements EventTarget {
+  // Fields.
+
+  /**
+   * The current location of this window.
+   *
+   *     Location currentLocation = window.location;
+   *     print(currentLocation.href); // 'http://www.example.com:80/'
+   */
+  LocationBase get location;
+
+  /**
+   * The current session history for this window.
+   *
+   * ## Other resources
+   *
+   * * [Session history and navigation
+   *   specification](https://html.spec.whatwg.org/multipage/browsers.html#history)
+   *   from WHATWG.
+   */
+  HistoryBase get history;
+
+  /**
+   * Indicates whether this window has been closed.
+   *
+   *     print(window.closed); // 'false'
+   *     window.close();
+   *     print(window.closed); // 'true'
+   */
+  bool get closed;
+
+  /**
+   * A reference to the window that opened this one.
+   *
+   *     Window thisWindow = window;
+   *     WindowBase otherWindow = thisWindow.open('http://www.example.com/', 'foo');
+   *     print(otherWindow.opener == thisWindow); // 'true'
+   */
+  WindowBase get opener;
+
+  /**
+   * A reference to the parent of this window.
+   *
+   * If this [WindowBase] has no parent, [parent] will return a reference to
+   * the [WindowBase] itself.
+   *
+   *     IFrameElement myIFrame = new IFrameElement();
+   *     window.document.body.elements.add(myIFrame);
+   *     print(myIframe.contentWindow.parent == window) // 'true'
+   *
+   *     print(window.parent == window) // 'true'
+   */
+  WindowBase get parent;
+
+  /**
+   * A reference to the topmost window in the window hierarchy.
+   *
+   * If this [WindowBase] is the topmost [WindowBase], [top] will return a
+   * reference to the [WindowBase] itself.
+   *
+   *     // Add an IFrame to the current window.
+   *     IFrameElement myIFrame = new IFrameElement();
+   *     window.document.body.elements.add(myIFrame);
+   *
+   *     // Add an IFrame inside of the other IFrame.
+   *     IFrameElement innerIFrame = new IFrameElement();
+   *     myIFrame.elements.add(innerIFrame);
+   *
+   *     print(myIframe.contentWindow.top == window) // 'true'
+   *     print(innerIFrame.contentWindow.top == window) // 'true'
+   *
+   *     print(window.top == window) // 'true'
+   */
+  WindowBase get top;
+
+  // Methods.
+  /**
+   * Closes the window.
+   *
+   * This method should only succeed if the [WindowBase] object is
+   * **script-closeable** and the window calling [close] is allowed to navigate
+   * the window.
+   *
+   * A window is script-closeable if it is either a window
+   * that was opened by another window, or if it is a window with only one
+   * document in its history.
+   *
+   * A window might not be allowed to navigate, and therefore close, another
+   * window due to browser security features.
+   *
+   *     var other = window.open('http://www.example.com', 'foo');
+   *     // Closes other window, as it is script-closeable.
+   *     other.close();
+   *     print(other.closed); // 'true'
+   *
+   *     var newLocation = window.location
+   *         ..href = 'http://www.mysite.com';
+   *     window.location = newLocation;
+   *     // Does not close this window, as the history has changed.
+   *     window.close();
+   *     print(window.closed); // 'false'
+   *
+   * See also:
+   *
+   * * [Window close discussion](http://www.w3.org/TR/html5/browsers.html#dom-window-close) from the W3C
+   */
+  void close();
+
+  /**
+   * Sends a cross-origin message.
+   *
+   * ## Other resources
+   *
+   * * [window.postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage)
+   *   from MDN.
+   * * [Cross-document messaging](https://html.spec.whatwg.org/multipage/comms.html#web-messaging)
+   *   from WHATWG.
+   */
+  void postMessage(var message, String targetOrigin,
+      [List<MessagePort> messagePorts]);
+}
+
+abstract class LocationBase {
+  void set href(String val);
+}
+
+abstract class HistoryBase {
+  void back();
+  void forward();
+  void go(int distance);
+}
+// Copyright (c) 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.
+
+/** A Set that stores the CSS class names for an element. */
+abstract class CssClassSet implements Set<String> {
+  /**
+   * Adds the class [value] to the element if it is not on it, removes it if it
+   * is.
+   *
+   * If [shouldAdd] is true, then we always add that [value] to the element. If
+   * [shouldAdd] is false then we always remove [value] from the element.
+   *
+   * If this corresponds to one element, returns `true` if [value] is present
+   * after the operation, and returns `false` if [value] is absent after the
+   * operation.
+   *
+   * If this corresponds to many elements, `null` is always returned.
+   *
+   * [value] must be a valid 'token' representing a single class, i.e. a
+   * non-empty string containing no whitespace.  To toggle multiple classes, use
+   * [toggleAll].
+   */
+  bool toggle(String value, [bool shouldAdd]);
+
+  /**
+   * Returns [:true:] if classes cannot be added or removed from this
+   * [:CssClassSet:].
+   */
+  bool get frozen;
+
+  /**
+   * Determine if this element contains the class [value].
+   *
+   * This is the Dart equivalent of jQuery's
+   * [hasClass](http://api.jquery.com/hasClass/).
+   *
+   * [value] must be a valid 'token' representing a single class, i.e. a
+   * non-empty string containing no whitespace.
+   */
+  bool contains(Object value);
+
+  /**
+   * Add the class [value] to element.
+   *
+   * [add] and [addAll] are the Dart equivalent of jQuery's
+   * [addClass](http://api.jquery.com/addClass/).
+   *
+   * If this CssClassSet corresponds to one element. Returns true if [value] was
+   * added to the set, otherwise false.
+   *
+   * If this corresponds to many elements, `null` is always returned.
+   *
+   * [value] must be a valid 'token' representing a single class, i.e. a
+   * non-empty string containing no whitespace.  To add multiple classes use
+   * [addAll].
+   */
+  bool add(String value);
+
+  /**
+   * Remove the class [value] from element, and return true on successful
+   * removal.
+   *
+   * [remove] and [removeAll] are the Dart equivalent of jQuery's
+   * [removeClass](http://api.jquery.com/removeClass/).
+   *
+   * [value] must be a valid 'token' representing a single class, i.e. a
+   * non-empty string containing no whitespace.  To remove multiple classes, use
+   * [removeAll].
+   */
+  bool remove(Object value);
+
+  /**
+   * Add all classes specified in [iterable] to element.
+   *
+   * [add] and [addAll] are the Dart equivalent of jQuery's
+   * [addClass](http://api.jquery.com/addClass/).
+   *
+   * Each element of [iterable] must be a valid 'token' representing a single
+   * class, i.e. a non-empty string containing no whitespace.
+   */
+  void addAll(Iterable<String> iterable);
+
+  /**
+   * Remove all classes specified in [iterable] from element.
+   *
+   * [remove] and [removeAll] are the Dart equivalent of jQuery's
+   * [removeClass](http://api.jquery.com/removeClass/).
+   *
+   * Each element of [iterable] must be a valid 'token' representing a single
+   * class, i.e. a non-empty string containing no whitespace.
+   */
+  void removeAll(Iterable<Object> iterable);
+
+  /**
+   * Toggles all classes specified in [iterable] on element.
+   *
+   * Iterate through [iterable]'s items, and add it if it is not on it, or
+   * remove it if it is. This is the Dart equivalent of jQuery's
+   * [toggleClass](http://api.jquery.com/toggleClass/).
+   * If [shouldAdd] is true, then we always add all the classes in [iterable]
+   * element. If [shouldAdd] is false then we always remove all the classes in
+   * [iterable] from the element.
+   *
+   * Each element of [iterable] must be a valid 'token' representing a single
+   * class, i.e. a non-empty string containing no whitespace.
+   */
+  void toggleAll(Iterable<String> iterable, [bool shouldAdd]);
+}
+// 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 rectangle representing all the content of the element in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _ContentCssRect extends CssRect {
+  _ContentCssRect(Element element) : super(element);
+
+  num get height =>
+      _element.offsetHeight + _addOrSubtractToBoxModel(_HEIGHT, _CONTENT);
+
+  num get width =>
+      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _CONTENT);
+
+  /**
+   * Set the height to `newHeight`.
+   *
+   * newHeight can be either a [num] representing the height in pixels or a
+   * [Dimension] object. Values of newHeight that are less than zero are
+   * converted to effectively setting the height to 0. This is equivalent to the
+   * `height` function in jQuery and the calculated `height` CSS value,
+   * converted to a num in pixels.
+   */
+  set height(dynamic newHeight) {
+    if (newHeight is Dimension) {
+      Dimension newHeightAsDimension = newHeight;
+      if (newHeightAsDimension.value < 0) newHeight = new Dimension.px(0);
+      _element.style.height = newHeight.toString();
+    } else if (newHeight is num) {
+      if (newHeight < 0) newHeight = 0;
+      _element.style.height = '${newHeight}px';
+    } else {
+      throw new ArgumentError("newHeight is not a Dimension or num");
+    }
+  }
+
+  /**
+   * Set the current computed width in pixels of this element.
+   *
+   * newWidth can be either a [num] representing the width in pixels or a
+   * [Dimension] object. This is equivalent to the `width` function in jQuery
+   * and the calculated
+   * `width` CSS value, converted to a dimensionless num in pixels.
+   */
+  set width(dynamic newWidth) {
+    if (newWidth is Dimension) {
+      Dimension newWidthAsDimension = newWidth;
+      if (newWidthAsDimension.value < 0) newWidth = new Dimension.px(0);
+      _element.style.width = newWidth.toString();
+    } else if (newWidth is num) {
+      if (newWidth < 0) newWidth = 0;
+      _element.style.width = '${newWidth}px';
+    } else {
+      throw new ArgumentError("newWidth is not a Dimension or num");
+    }
+  }
+
+  num get left =>
+      _element.getBoundingClientRect().left -
+      _addOrSubtractToBoxModel(['left'], _CONTENT);
+  num get top =>
+      _element.getBoundingClientRect().top -
+      _addOrSubtractToBoxModel(['top'], _CONTENT);
+}
+
+/**
+ * A list of element content rectangles in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _ContentCssListRect extends _ContentCssRect {
+  List<Element> _elementList;
+
+  _ContentCssListRect(List<Element> elementList) : super(elementList.first) {
+    _elementList = elementList;
+  }
+
+  /**
+   * Set the height to `newHeight`.
+   *
+   * Values of newHeight that are less than zero are converted to effectively
+   * setting the height to 0. This is equivalent to the `height`
+   * function in jQuery and the calculated `height` CSS value, converted to a
+   * num in pixels.
+   */
+  set height(newHeight) {
+    _elementList.forEach((e) => e.contentEdge.height = newHeight);
+  }
+
+  /**
+   * Set the current computed width in pixels of this element.
+   *
+   * This is equivalent to the `width` function in jQuery and the calculated
+   * `width` CSS value, converted to a dimensionless num in pixels.
+   */
+  set width(newWidth) {
+    _elementList.forEach((e) => e.contentEdge.width = newWidth);
+  }
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _PaddingCssRect extends CssRect {
+  _PaddingCssRect(element) : super(element);
+  num get height =>
+      _element.offsetHeight + _addOrSubtractToBoxModel(_HEIGHT, _PADDING);
+  num get width =>
+      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _PADDING);
+
+  num get left =>
+      _element.getBoundingClientRect().left -
+      _addOrSubtractToBoxModel(['left'], _PADDING);
+  num get top =>
+      _element.getBoundingClientRect().top -
+      _addOrSubtractToBoxModel(['top'], _PADDING);
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding + border in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _BorderCssRect extends CssRect {
+  _BorderCssRect(element) : super(element);
+  num get height => _element.offsetHeight;
+  num get width => _element.offsetWidth;
+
+  num get left => _element.getBoundingClientRect().left;
+  num get top => _element.getBoundingClientRect().top;
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding + border + margin in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _MarginCssRect extends CssRect {
+  _MarginCssRect(element) : super(element);
+  num get height =>
+      _element.offsetHeight + _addOrSubtractToBoxModel(_HEIGHT, _MARGIN);
+  num get width =>
+      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _MARGIN);
+
+  num get left =>
+      _element.getBoundingClientRect().left -
+      _addOrSubtractToBoxModel(['left'], _MARGIN);
+  num get top =>
+      _element.getBoundingClientRect().top -
+      _addOrSubtractToBoxModel(['top'], _MARGIN);
+}
+
+/**
+ * A class for representing CSS dimensions.
+ *
+ * In contrast to the more general purpose [Rectangle] class, this class's
+ * values are mutable, so one can change the height of an element
+ * programmatically.
+ *
+ * _Important_ _note_: use of these methods will perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of these properties _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+abstract class CssRect implements Rectangle<num> {
+  Element _element;
+
+  CssRect(this._element);
+
+  num get left;
+
+  num get top;
+
+  /**
+   * The height of this rectangle.
+   *
+   * This is equivalent to the `height` function in jQuery and the calculated
+   * `height` CSS value, converted to a dimensionless num in pixels. Unlike
+   * [getBoundingClientRect], `height` will return the same numerical width if
+   * the element is hidden or not.
+   */
+  num get height;
+
+  /**
+   * The width of this rectangle.
+   *
+   * This is equivalent to the `width` function in jQuery and the calculated
+   * `width` CSS value, converted to a dimensionless num in pixels. Unlike
+   * [getBoundingClientRect], `width` will return the same numerical width if
+   * the element is hidden or not.
+   */
+  num get width;
+
+  /**
+   * Set the height to `newHeight`.
+   *
+   * newHeight can be either a [num] representing the height in pixels or a
+   * [Dimension] object. Values of newHeight that are less than zero are
+   * converted to effectively setting the height to 0. This is equivalent to the
+   * `height` function in jQuery and the calculated `height` CSS value,
+   * converted to a num in pixels.
+   *
+   * Note that only the content height can actually be set via this method.
+   */
+  set height(dynamic newHeight) {
+    throw new UnsupportedError("Can only set height for content rect.");
+  }
+
+  /**
+   * Set the current computed width in pixels of this element.
+   *
+   * newWidth can be either a [num] representing the width in pixels or a
+   * [Dimension] object. This is equivalent to the `width` function in jQuery
+   * and the calculated
+   * `width` CSS value, converted to a dimensionless num in pixels.
+   *
+   * Note that only the content width can be set via this method.
+   */
+  set width(dynamic newWidth) {
+    throw new UnsupportedError("Can only set width for content rect.");
+  }
+
+  /**
+   * Return a value that is used to modify the initial height or width
+   * measurement of an element. Depending on the value (ideally an enum) passed
+   * to augmentingMeasurement, we may need to add or subtract margin, padding,
+   * or border values, depending on the measurement we're trying to obtain.
+   */
+  num _addOrSubtractToBoxModel(
+      List<String> dimensions, String augmentingMeasurement) {
+    // getComputedStyle always returns pixel values (hence, computed), so we're
+    // always dealing with pixels in this method.
+    var styles = _element.getComputedStyle();
+
+    var val = 0;
+
+    for (String measurement in dimensions) {
+      // The border-box and default box model both exclude margin in the regular
+      // height/width calculation, so add it if we want it for this measurement.
+      if (augmentingMeasurement == _MARGIN) {
+        val += new Dimension.css(
+                styles.getPropertyValue('$augmentingMeasurement-$measurement'))
+            .value;
+      }
+
+      // The border-box includes padding and border, so remove it if we want
+      // just the content itself.
+      if (augmentingMeasurement == _CONTENT) {
+        val -= new Dimension.css(
+                styles.getPropertyValue('${_PADDING}-$measurement'))
+            .value;
+      }
+
+      // At this point, we don't wan't to augment with border or margin,
+      // so remove border.
+      if (augmentingMeasurement != _MARGIN) {
+        val -= new Dimension.css(
+                styles.getPropertyValue('border-${measurement}-width'))
+            .value;
+      }
+    }
+    return val;
+  }
+
+  // TODO(jacobr): these methods are duplicated from _RectangleBase in dart:math
+  // Ideally we would provide a RectangleMixin class that provides this implementation.
+  // In an ideal world we would exp
+  /** The x-coordinate of the right edge. */
+  num get right => left + width;
+  /** The y-coordinate of the bottom edge. */
+  num get bottom => top + height;
+
+  String toString() {
+    return 'Rectangle ($left, $top) $width x $height';
+  }
+
+  bool operator ==(other) {
+    if (other is! Rectangle) return false;
+    return left == other.left &&
+        top == other.top &&
+        right == other.right &&
+        bottom == other.bottom;
+  }
+
+  int get hashCode => _JenkinsSmiHash.hash4(
+      left.hashCode, top.hashCode, right.hashCode, bottom.hashCode);
+
+  /**
+   * Computes the intersection of `this` and [other].
+   *
+   * The intersection of two axis-aligned rectangles, if any, is always another
+   * axis-aligned rectangle.
+   *
+   * Returns the intersection of this and `other`, or `null` if they don't
+   * intersect.
+   */
+  Rectangle<num> intersection(Rectangle<num> other) {
+    var x0 = max(left, other.left);
+    var x1 = min(left + width, other.left + other.width);
+
+    if (x0 <= x1) {
+      var y0 = max(top, other.top);
+      var y1 = min(top + height, other.top + other.height);
+
+      if (y0 <= y1) {
+        return new Rectangle<num>(x0, y0, x1 - x0, y1 - y0);
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Returns true if `this` intersects [other].
+   */
+  bool intersects(Rectangle<num> other) {
+    return (left <= other.left + other.width &&
+        other.left <= left + width &&
+        top <= other.top + other.height &&
+        other.top <= top + height);
+  }
+
+  /**
+   * Returns a new rectangle which completely contains `this` and [other].
+   */
+  Rectangle<num> boundingBox(Rectangle<num> other) {
+    var right = max(this.left + this.width, other.left + other.width);
+    var bottom = max(this.top + this.height, other.top + other.height);
+
+    var left = min(this.left, other.left);
+    var top = min(this.top, other.top);
+
+    return new Rectangle<num>(left, top, right - left, bottom - top);
+  }
+
+  /**
+   * Tests whether `this` entirely contains [another].
+   */
+  bool containsRectangle(Rectangle<num> another) {
+    return left <= another.left &&
+        left + width >= another.left + another.width &&
+        top <= another.top &&
+        top + height >= another.top + another.height;
+  }
+
+  /**
+   * Tests whether [another] is inside or along the edges of `this`.
+   */
+  bool containsPoint(Point<num> another) {
+    return another.x >= left &&
+        another.x <= left + width &&
+        another.y >= top &&
+        another.y <= top + height;
+  }
+
+  Point<num> get topLeft => new Point<num>(this.left, this.top);
+  Point<num> get topRight => new Point<num>(this.left + this.width, this.top);
+  Point<num> get bottomRight =>
+      new Point<num>(this.left + this.width, this.top + this.height);
+  Point<num> get bottomLeft =>
+      new Point<num>(this.left, this.top + this.height);
+}
+
+final _HEIGHT = ['top', 'bottom'];
+final _WIDTH = ['right', 'left'];
+final _CONTENT = 'content';
+final _PADDING = 'padding';
+final _MARGIN = 'margin';
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for 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 set (union) of the CSS classes that are present in a set of elements.
+ * Implemented separately from _ElementCssClassSet for performance.
+ */
+class _MultiElementCssClassSet extends CssClassSetImpl {
+  final Iterable<Element> _elementIterable;
+
+  // TODO(sra): Perhaps we should store the DomTokenList instead.
+  final List<CssClassSetImpl> _sets;
+
+  factory _MultiElementCssClassSet(Iterable<Element> elements) {
+    return new _MultiElementCssClassSet._(elements,
+        new List<CssClassSetImpl>.from(elements.map((Element e) => e.classes)));
+  }
+
+  _MultiElementCssClassSet._(this._elementIterable, this._sets);
+
+  Set<String> readClasses() {
+    var s = new LinkedHashSet<String>();
+    _sets.forEach((CssClassSetImpl e) => s.addAll(e.readClasses()));
+    return s;
+  }
+
+  void writeClasses(Set<String> s) {
+    var classes = s.join(' ');
+    for (Element e in _elementIterable) {
+      e.className = classes;
+    }
+  }
+
+  /**
+   * Helper method used to modify the set of css classes on this element.
+   *
+   *   f - callback with:
+   *   s - a Set of all the css class name currently on this element.
+   *
+   *   After f returns, the modified set is written to the
+   *       className property of this element.
+   */
+  modify(f(Set<String> s)) {
+    _sets.forEach((CssClassSetImpl e) => e.modify(f));
+  }
+
+  /**
+   * Adds the class [value] to the element if it is not on it, removes it if it
+   * is.
+   *
+   * TODO(sra): It seems wrong to collect a 'changed' flag like this when the
+   * underlying toggle returns an 'is set' flag.
+   */
+  bool toggle(String value, [bool shouldAdd]) => _sets.fold(
+      false,
+      (bool changed, CssClassSetImpl e) =>
+          e.toggle(value, shouldAdd) || changed);
+
+  /**
+   * Remove the class [value] from element, and return true on successful
+   * removal.
+   *
+   * This is the Dart equivalent of jQuery's
+   * [removeClass](http://api.jquery.com/removeClass/).
+   */
+  bool remove(Object value) => _sets.fold(
+      false, (bool changed, CssClassSetImpl e) => e.remove(value) || changed);
+}
+
+class _ElementCssClassSet extends CssClassSetImpl {
+  final Element _element;
+
+  _ElementCssClassSet(this._element);
+
+  Set<String> readClasses() {
+    var s = new LinkedHashSet<String>();
+    var classname = _element.className;
+
+    for (String name in classname.split(' ')) {
+      String trimmed = name.trim();
+      if (!trimmed.isEmpty) {
+        s.add(trimmed);
+      }
+    }
+    return s;
+  }
+
+  void writeClasses(Set<String> s) {
+    _element.className = s.join(' ');
+  }
+
+  int get length => _classListLength(_classListOf(_element));
+  bool get isEmpty => length == 0;
+  bool get isNotEmpty => length != 0;
+
+  void clear() {
+    _element.className = '';
+  }
+
+  bool contains(Object value) {
+    return _contains(_element, value);
+  }
+
+  bool add(String value) {
+    return _add(_element, value);
+  }
+
+  bool remove(Object value) {
+    return value is String && _remove(_element, value);
+  }
+
+  bool toggle(String value, [bool shouldAdd]) {
+    return _toggle(_element, value, shouldAdd);
+  }
+
+  void addAll(Iterable<String> iterable) {
+    _addAll(_element, iterable);
+  }
+
+  void removeAll(Iterable<Object> iterable) {
+    _removeAll(_element, iterable);
+  }
+
+  void retainAll(Iterable<Object> iterable) {
+    _removeWhere(_element, iterable.toSet().contains, false);
+  }
+
+  void removeWhere(bool test(String name)) {
+    _removeWhere(_element, test, true);
+  }
+
+  void retainWhere(bool test(String name)) {
+    _removeWhere(_element, test, false);
+  }
+
+  static bool _contains(Element _element, Object value) {
+    return value is String && _classListContains(_classListOf(_element), value);
+  }
+
+  @pragma('dart2js:tryInline')
+  static bool _add(Element _element, String value) {
+    DomTokenList list = _classListOf(_element);
+    // Compute returned result independently of action upon the set.
+    bool added = !_classListContainsBeforeAddOrRemove(list, value);
+    _classListAdd(list, value);
+    return added;
+  }
+
+  @pragma('dart2js:tryInline')
+  static bool _remove(Element _element, String value) {
+    DomTokenList list = _classListOf(_element);
+    bool removed = _classListContainsBeforeAddOrRemove(list, value);
+    _classListRemove(list, value);
+    return removed;
+  }
+
+  static bool _toggle(Element _element, String value, bool shouldAdd) {
+    // There is no value that can be passed as the second argument of
+    // DomTokenList.toggle that behaves the same as passing one argument.
+    // `null` is seen as false, meaning 'remove'.
+    return shouldAdd == null
+        ? _toggleDefault(_element, value)
+        : _toggleOnOff(_element, value, shouldAdd);
+  }
+
+  static bool _toggleDefault(Element _element, String value) {
+    DomTokenList list = _classListOf(_element);
+    return _classListToggle1(list, value);
+  }
+
+  static bool _toggleOnOff(Element _element, String value, bool shouldAdd) {
+    DomTokenList list = _classListOf(_element);
+    // IE's toggle does not take a second parameter. We would prefer:
+    //
+    //    return _classListToggle2(list, value, shouldAdd);
+    //
+    if (shouldAdd) {
+      _classListAdd(list, value);
+      return true;
+    } else {
+      _classListRemove(list, value);
+      return false;
+    }
+  }
+
+  static void _addAll(Element _element, Iterable<String> iterable) {
+    DomTokenList list = _classListOf(_element);
+    for (String value in iterable) {
+      _classListAdd(list, value);
+    }
+  }
+
+  static void _removeAll(Element _element, Iterable<Object> iterable) {
+    DomTokenList list = _classListOf(_element);
+    for (String value in iterable) {
+      _classListRemove(list, value);
+    }
+  }
+
+  static void _removeWhere(
+      Element _element, bool test(String name), bool doRemove) {
+    DomTokenList list = _classListOf(_element);
+    int i = 0;
+    while (i < _classListLength(list)) {
+      String item = list.item(i);
+      if (doRemove == test(item)) {
+        _classListRemove(list, item);
+      } else {
+        ++i;
+      }
+    }
+  }
+
+  // A collection of static methods for DomTokenList. These methods are a
+  // work-around for the lack of annotations to express the full behaviour of
+  // the DomTokenList methods.
+
+  static DomTokenList _classListOf(Element e) => JS(
+      'returns:DomTokenList;creates:DomTokenList;effects:none;depends:all;',
+      '#.classList',
+      e);
+
+  static int _classListLength(DomTokenList list) =>
+      JS('returns:JSUInt31;effects:none;depends:all;', '#.length', list);
+
+  static bool _classListContains(DomTokenList list, String value) =>
+      JS('returns:bool;effects:none;depends:all', '#.contains(#)', list, value);
+
+  static bool _classListContainsBeforeAddOrRemove(
+          DomTokenList list, String value) =>
+      // 'throws:never' is a lie, since 'contains' will throw on an illegal
+      // token.  However, we always call this function immediately prior to
+      // add/remove/toggle with the same token.  Often the result of 'contains'
+      // is unused and the lie makes it possible for the 'contains' instruction
+      // to be removed.
+      JS('returns:bool;effects:none;depends:all;throws:null(1)',
+          '#.contains(#)', list, value);
+
+  static void _classListAdd(DomTokenList list, String value) {
+    // list.add(value);
+    JS('', '#.add(#)', list, value);
+  }
+
+  static void _classListRemove(DomTokenList list, String value) {
+    // list.remove(value);
+    JS('', '#.remove(#)', list, value);
+  }
+
+  static bool _classListToggle1(DomTokenList list, String value) {
+    return JS('bool', '#.toggle(#)', list, value);
+  }
+
+  static bool _classListToggle2(
+      DomTokenList list, String value, bool shouldAdd) {
+    return JS('bool', '#.toggle(#, #)', list, value, shouldAdd);
+  }
+}
+
+/**
+ * Class representing a
+ * [length measurement](https://developer.mozilla.org/en-US/docs/Web/CSS/length)
+ * in CSS.
+ */
+class Dimension {
+  num _value;
+  String _unit;
+
+  /** Set this CSS Dimension to a percentage `value`. */
+  Dimension.percent(this._value) : _unit = '%';
+
+  /** Set this CSS Dimension to a pixel `value`. */
+  Dimension.px(this._value) : _unit = 'px';
+
+  /** Set this CSS Dimension to a pica `value`. */
+  Dimension.pc(this._value) : _unit = 'pc';
+
+  /** Set this CSS Dimension to a point `value`. */
+  Dimension.pt(this._value) : _unit = 'pt';
+
+  /** Set this CSS Dimension to an inch `value`. */
+  Dimension.inch(this._value) : _unit = 'in';
+
+  /** Set this CSS Dimension to a centimeter `value`. */
+  Dimension.cm(this._value) : _unit = 'cm';
+
+  /** Set this CSS Dimension to a millimeter `value`. */
+  Dimension.mm(this._value) : _unit = 'mm';
+
+  /**
+   * Set this CSS Dimension to the specified number of ems.
+   *
+   * 1em is equal to the current font size. (So 2ems is equal to double the font
+   * size). This is useful for producing website layouts that scale nicely with
+   * the user's desired font size.
+   */
+  Dimension.em(this._value) : _unit = 'em';
+
+  /**
+   * Set this CSS Dimension to the specified number of x-heights.
+   *
+   * One ex is equal to the x-height of a font's baseline to its mean line,
+   * generally the height of the letter "x" in the font, which is usually about
+   * half the font-size.
+   */
+  Dimension.ex(this._value) : _unit = 'ex';
+
+  /**
+   * Construct a Dimension object from the valid, simple CSS string `cssValue`
+   * that represents a distance measurement.
+   *
+   * This constructor is intended as a convenience method for working with
+   * simplistic CSS length measurements. Non-numeric values such as `auto` or
+   * `inherit` or invalid CSS will cause this constructor to throw a
+   * FormatError.
+   */
+  Dimension.css(String cssValue) {
+    if (cssValue == '') cssValue = '0px';
+    if (cssValue.endsWith('%')) {
+      _unit = '%';
+    } else {
+      _unit = cssValue.substring(cssValue.length - 2);
+    }
+    if (cssValue.contains('.')) {
+      _value =
+          double.parse(cssValue.substring(0, cssValue.length - _unit.length));
+    } else {
+      _value = int.parse(cssValue.substring(0, cssValue.length - _unit.length));
+    }
+  }
+
+  /** Print out the CSS String representation of this value. */
+  String toString() {
+    return '${_value}${_unit}';
+  }
+
+  /** Return a unitless, numerical value of this CSS value. */
+  num get value => this._value;
+}
+// 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.
+
+typedef EventListener(Event event);
+// 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 factory to expose DOM events as Streams.
+ */
+class EventStreamProvider<T extends Event> {
+  final String _eventType;
+
+  const EventStreamProvider(this._eventType);
+
+  /**
+   * Gets a [Stream] for this event type, on the specified target.
+   *
+   * This will always return a broadcast stream so multiple listeners can be
+   * used simultaneously.
+   *
+   * This may be used to capture DOM events:
+   *
+   *     Element.keyDownEvent.forTarget(element, useCapture: true).listen(...);
+   *
+   *     // Alternate method:
+   *     Element.keyDownEvent.forTarget(element).capture(...);
+   *
+   * Or for listening to an event which will bubble through the DOM tree:
+   *
+   *     MediaElement.pauseEvent.forTarget(document.body).listen(...);
+   *
+   * See also:
+   *
+   * * [EventTarget.addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)
+   *   from MDN.
+   */
+  Stream<T> forTarget(EventTarget e, {bool useCapture: false}) =>
+      new _EventStream<T>(e, _eventType, useCapture);
+
+  /**
+   * Gets an [ElementEventStream] for this event type, on the specified element.
+   *
+   * This will always return a broadcast stream so multiple listeners can be
+   * used simultaneously.
+   *
+   * This may be used to capture DOM events:
+   *
+   *     Element.keyDownEvent.forElement(element, useCapture: true).listen(...);
+   *
+   *     // Alternate method:
+   *     Element.keyDownEvent.forElement(element).capture(...);
+   *
+   * Or for listening to an event which will bubble through the DOM tree:
+   *
+   *     MediaElement.pauseEvent.forElement(document.body).listen(...);
+   *
+   * See also:
+   *
+   * * [EventTarget.addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)
+   *   from MDN.
+   */
+  ElementStream<T> forElement(Element e, {bool useCapture: false}) {
+    return new _ElementEventStreamImpl<T>(e, _eventType, useCapture);
+  }
+
+  /**
+   * Gets an [ElementEventStream] for this event type, on the list of elements.
+   *
+   * This will always return a broadcast stream so multiple listeners can be
+   * used simultaneously.
+   *
+   * This may be used to capture DOM events:
+   *
+   *     Element.keyDownEvent._forElementList(element, useCapture: true).listen(...);
+   *
+   * See also:
+   *
+   * * [EventTarget.addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)
+   *   from MDN.
+   */
+  ElementStream<T> _forElementList(ElementList<Element> e,
+      {bool useCapture: false}) {
+    return new _ElementListEventStreamImpl<T>(e, _eventType, useCapture);
+  }
+
+  /**
+   * Gets the type of the event which this would listen for on the specified
+   * event target.
+   *
+   * The target is necessary because some browsers may use different event names
+   * for the same purpose and the target allows differentiating browser support.
+   */
+  String getEventType(EventTarget target) {
+    return _eventType;
+  }
+}
+
+/** A specialized Stream available to [Element]s to enable event delegation. */
+abstract class ElementStream<T extends Event> implements Stream<T> {
+  /**
+   * Return a stream that only fires when the particular event fires for
+   * elements matching the specified CSS selector.
+   *
+   * This is the Dart equivalent to jQuery's
+   * [delegate](http://api.jquery.com/delegate/).
+   */
+  Stream<T> matches(String selector);
+
+  /**
+   * Adds a capturing subscription to this stream.
+   *
+   * If the target of the event is a descendant of the element from which this
+   * stream derives then [onData] is called before the event propagates down to
+   * the target. This is the opposite of bubbling behavior, where the event
+   * is first processed for the event target and then bubbles upward.
+   *
+   * ## Other resources
+   *
+   * * [Event Capture](http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
+   *   from the W3C DOM Events specification.
+   */
+  StreamSubscription<T> capture(void onData(T event));
+}
+
+/**
+ * Adapter for exposing DOM events as Dart streams.
+ */
+class _EventStream<T extends Event> extends Stream<T> {
+  final EventTarget _target;
+  final String _eventType;
+  final bool _useCapture;
+
+  _EventStream(this._target, this._eventType, this._useCapture);
+
+  // DOM events are inherently multi-subscribers.
+  Stream<T> asBroadcastStream(
+          {void onListen(StreamSubscription<T> subscription),
+          void onCancel(StreamSubscription<T> subscription)}) =>
+      this;
+  bool get isBroadcast => true;
+
+  // TODO(9757): Inlining should be smart and inline only when inlining would
+  // enable scalar replacement of an immediately allocated receiver.
+  @pragma('dart2js:tryInline')
+  StreamSubscription<T> listen(void onData(T event),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    return new _EventStreamSubscription<T>(
+        this._target, this._eventType, onData, this._useCapture);
+  }
+}
+
+bool _matchesWithAncestors(Event event, String selector) {
+  var target = event.target;
+  return target is Element ? target.matchesWithAncestors(selector) : false;
+}
+
+/**
+ * Adapter for exposing DOM Element events as streams, while also allowing
+ * event delegation.
+ */
+class _ElementEventStreamImpl<T extends Event> extends _EventStream<T>
+    implements ElementStream<T> {
+  _ElementEventStreamImpl(target, eventType, useCapture)
+      : super(target, eventType, useCapture);
+
+  Stream<T> matches(String selector) =>
+      this.where((event) => _matchesWithAncestors(event, selector)).map((e) {
+        e._selector = selector;
+        return e;
+      });
+
+  StreamSubscription<T> capture(void onData(T event)) =>
+      new _EventStreamSubscription<T>(
+          this._target, this._eventType, onData, true);
+}
+
+/**
+ * Adapter for exposing events on a collection of DOM Elements as streams,
+ * while also allowing event delegation.
+ */
+class _ElementListEventStreamImpl<T extends Event> extends Stream<T>
+    implements ElementStream<T> {
+  final Iterable<Element> _targetList;
+  final bool _useCapture;
+  final String _eventType;
+
+  _ElementListEventStreamImpl(
+      this._targetList, this._eventType, this._useCapture);
+
+  Stream<T> matches(String selector) =>
+      this.where((event) => _matchesWithAncestors(event, selector)).map((e) {
+        e._selector = selector;
+        return e;
+      });
+
+  // Delegate all regular Stream behavior to a wrapped Stream.
+  StreamSubscription<T> listen(void onData(T event),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    var pool = new _StreamPool<T>.broadcast();
+    for (var target in _targetList) {
+      pool.add(new _EventStream<T>(target, _eventType, _useCapture));
+    }
+    return pool.stream.listen(onData,
+        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+  }
+
+  StreamSubscription<T> capture(void onData(T event)) {
+    var pool = new _StreamPool<T>.broadcast();
+    for (var target in _targetList) {
+      pool.add(new _EventStream<T>(target, _eventType, true));
+    }
+    return pool.stream.listen(onData);
+  }
+
+  Stream<T> asBroadcastStream(
+          {void onListen(StreamSubscription<T> subscription),
+          void onCancel(StreamSubscription<T> subscription)}) =>
+      this;
+  bool get isBroadcast => true;
+}
+
+// We would like this to just be EventListener<T> but that typdef cannot
+// use generics until dartbug/26276 is fixed.
+typedef _EventListener<T extends Event>(T event);
+
+class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
+  int _pauseCount = 0;
+  EventTarget _target;
+  final String _eventType;
+  EventListener _onData;
+  final bool _useCapture;
+
+  // TODO(leafp): It would be better to write this as
+  // _onData = onData == null ? null :
+  //   onData is void Function(Event)
+  //     ? _wrapZone<Event>(onData)
+  //     : _wrapZone<Event>((e) => onData(e as T))
+  // In order to support existing tests which pass the wrong type of events but
+  // use a more general listener, without causing as much slowdown for things
+  // which are typed correctly.  But this currently runs afoul of restrictions
+  // on is checks for compatibility with the VM.
+  _EventStreamSubscription(
+      this._target, this._eventType, void onData(T event), this._useCapture)
+      : _onData = onData == null
+            ? null
+            : _wrapZone<Event>((e) => (onData as dynamic)(e)) {
+    _tryResume();
+  }
+
+  Future cancel() {
+    if (_canceled) return null;
+
+    _unlisten();
+    // Clear out the target to indicate this is complete.
+    _target = null;
+    _onData = null;
+    return null;
+  }
+
+  bool get _canceled => _target == null;
+
+  void onData(void handleData(T event)) {
+    if (_canceled) {
+      throw new StateError("Subscription has been canceled.");
+    }
+    // Remove current event listener.
+    _unlisten();
+    _onData = _wrapZone<Event>(handleData);
+    _tryResume();
+  }
+
+  /// Has no effect.
+  void onError(Function handleError) {}
+
+  /// Has no effect.
+  void onDone(void handleDone()) {}
+
+  void pause([Future resumeSignal]) {
+    if (_canceled) return;
+    ++_pauseCount;
+    _unlisten();
+
+    if (resumeSignal != null) {
+      resumeSignal.whenComplete(resume);
+    }
+  }
+
+  bool get isPaused => _pauseCount > 0;
+
+  void resume() {
+    if (_canceled || !isPaused) return;
+    --_pauseCount;
+    _tryResume();
+  }
+
+  void _tryResume() {
+    if (_onData != null && !isPaused) {
+      _target.addEventListener(_eventType, _onData, _useCapture);
+    }
+  }
+
+  void _unlisten() {
+    if (_onData != null) {
+      _target.removeEventListener(_eventType, _onData, _useCapture);
+    }
+  }
+
+  Future<E> asFuture<E>([E futureValue]) {
+    // We just need a future that will never succeed or fail.
+    var completer = new Completer<E>();
+    return completer.future;
+  }
+}
+
+/**
+ * A stream of custom events, which enables the user to "fire" (add) their own
+ * custom events to a stream.
+ */
+abstract class CustomStream<T extends Event> implements Stream<T> {
+  /**
+   * Add the following custom event to the stream for dispatching to interested
+   * listeners.
+   */
+  void add(T event);
+}
+
+class _CustomEventStreamImpl<T extends Event> extends Stream<T>
+    implements CustomStream<T> {
+  StreamController<T> _streamController;
+  /** The type of event this stream is providing (e.g. "keydown"). */
+  String _type;
+
+  _CustomEventStreamImpl(String type) {
+    _type = type;
+    _streamController = new StreamController.broadcast(sync: true);
+  }
+
+  // Delegate all regular Stream behavior to our wrapped Stream.
+  StreamSubscription<T> listen(void onData(T event),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    return _streamController.stream.listen(onData,
+        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+  }
+
+  Stream<T> asBroadcastStream(
+          {void onListen(StreamSubscription<T> subscription),
+          void onCancel(StreamSubscription<T> subscription)}) =>
+      _streamController.stream;
+
+  bool get isBroadcast => true;
+
+  void add(T event) {
+    if (event.type == _type) _streamController.add(event);
+  }
+}
+
+class _CustomKeyEventStreamImpl extends _CustomEventStreamImpl<KeyEvent>
+    implements CustomStream<KeyEvent> {
+  _CustomKeyEventStreamImpl(String type) : super(type);
+
+  void add(KeyEvent event) {
+    if (event.type == _type) {
+      event.currentTarget.dispatchEvent(event._parent);
+      _streamController.add(event);
+    }
+  }
+}
+
+/**
+ * A pool of streams whose events are unified and emitted through a central
+ * stream.
+ */
+// TODO (efortuna): Remove this when Issue 12218 is addressed.
+class _StreamPool<T> {
+  StreamController<T> _controller;
+
+  /// Subscriptions to the streams that make up the pool.
+  var _subscriptions = new Map<Stream<T>, StreamSubscription<T>>();
+
+  /**
+   * Creates a new stream pool where [stream] can be listened to more than
+   * once.
+   *
+   * Any events from buffered streams in the pool will be emitted immediately,
+   * regardless of whether [stream] has any subscribers.
+   */
+  _StreamPool.broadcast() {
+    _controller =
+        new StreamController<T>.broadcast(sync: true, onCancel: close);
+  }
+
+  /**
+   * The stream through which all events from streams in the pool are emitted.
+   */
+  Stream<T> get stream => _controller.stream;
+
+  /**
+   * Adds [stream] as a member of this pool.
+   *
+   * Any events from [stream] will be emitted through [this.stream]. If
+   * [stream] is sync, they'll be emitted synchronously; if [stream] is async,
+   * they'll be emitted asynchronously.
+   */
+  void add(Stream<T> stream) {
+    if (_subscriptions.containsKey(stream)) return;
+    _subscriptions[stream] = stream.listen(_controller.add,
+        onError: _controller.addError, onDone: () => remove(stream));
+  }
+
+  /** Removes [stream] as a member of this pool. */
+  void remove(Stream<T> stream) {
+    var subscription = _subscriptions.remove(stream);
+    if (subscription != null) subscription.cancel();
+  }
+
+  /** Removes all streams from this pool and closes [stream]. */
+  void close() {
+    for (var subscription in _subscriptions.values) {
+      subscription.cancel();
+    }
+    _subscriptions.clear();
+    _controller.close();
+  }
+}
+
+/**
+ * A factory to expose DOM events as streams, where the DOM event name has to
+ * be determined on the fly (for example, mouse wheel events).
+ */
+class _CustomEventStreamProvider<T extends Event>
+    implements EventStreamProvider<T> {
+  final _eventTypeGetter;
+  const _CustomEventStreamProvider(this._eventTypeGetter);
+
+  Stream<T> forTarget(EventTarget e, {bool useCapture: false}) {
+    return new _EventStream<T>(e, _eventTypeGetter(e), useCapture);
+  }
+
+  ElementStream<T> forElement(Element e, {bool useCapture: false}) {
+    return new _ElementEventStreamImpl<T>(e, _eventTypeGetter(e), useCapture);
+  }
+
+  ElementStream<T> _forElementList(ElementList<Element> e,
+      {bool useCapture: false}) {
+    return new _ElementListEventStreamImpl<T>(
+        e, _eventTypeGetter(e), useCapture);
+  }
+
+  String getEventType(EventTarget target) {
+    return _eventTypeGetter(target);
+  }
+
+  String get _eventType =>
+      throw new UnsupportedError('Access type through getEventType method.');
+}
+// DO NOT EDIT- this file is generated from running tool/generator.sh.
+
+// 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 Dart DOM validator generated from Caja whitelists.
+ *
+ * This contains a whitelist of known HTML tagNames and attributes and will only
+ * accept known good values.
+ *
+ * See also:
+ *
+ * * <https://code.google.com/p/google-caja/wiki/CajaWhitelists>
+ */
+class _Html5NodeValidator implements NodeValidator {
+  static final Set<String> _allowedElements = new Set.from([
+    'A',
+    'ABBR',
+    'ACRONYM',
+    'ADDRESS',
+    'AREA',
+    'ARTICLE',
+    'ASIDE',
+    'AUDIO',
+    'B',
+    'BDI',
+    'BDO',
+    'BIG',
+    'BLOCKQUOTE',
+    'BR',
+    'BUTTON',
+    'CANVAS',
+    'CAPTION',
+    'CENTER',
+    'CITE',
+    'CODE',
+    'COL',
+    'COLGROUP',
+    'COMMAND',
+    'DATA',
+    'DATALIST',
+    'DD',
+    'DEL',
+    'DETAILS',
+    'DFN',
+    'DIR',
+    'DIV',
+    'DL',
+    'DT',
+    'EM',
+    'FIELDSET',
+    'FIGCAPTION',
+    'FIGURE',
+    'FONT',
+    'FOOTER',
+    'FORM',
+    'H1',
+    'H2',
+    'H3',
+    'H4',
+    'H5',
+    'H6',
+    'HEADER',
+    'HGROUP',
+    'HR',
+    'I',
+    'IFRAME',
+    'IMG',
+    'INPUT',
+    'INS',
+    'KBD',
+    'LABEL',
+    'LEGEND',
+    'LI',
+    'MAP',
+    'MARK',
+    'MENU',
+    'METER',
+    'NAV',
+    'NOBR',
+    'OL',
+    'OPTGROUP',
+    'OPTION',
+    'OUTPUT',
+    'P',
+    'PRE',
+    'PROGRESS',
+    'Q',
+    'S',
+    'SAMP',
+    'SECTION',
+    'SELECT',
+    'SMALL',
+    'SOURCE',
+    'SPAN',
+    'STRIKE',
+    'STRONG',
+    'SUB',
+    'SUMMARY',
+    'SUP',
+    'TABLE',
+    'TBODY',
+    'TD',
+    'TEXTAREA',
+    'TFOOT',
+    'TH',
+    'THEAD',
+    'TIME',
+    'TR',
+    'TRACK',
+    'TT',
+    'U',
+    'UL',
+    'VAR',
+    'VIDEO',
+    'WBR',
+  ]);
+
+  static const _standardAttributes = const <String>[
+    '*::class',
+    '*::dir',
+    '*::draggable',
+    '*::hidden',
+    '*::id',
+    '*::inert',
+    '*::itemprop',
+    '*::itemref',
+    '*::itemscope',
+    '*::lang',
+    '*::spellcheck',
+    '*::title',
+    '*::translate',
+    'A::accesskey',
+    'A::coords',
+    'A::hreflang',
+    'A::name',
+    'A::shape',
+    'A::tabindex',
+    'A::target',
+    'A::type',
+    'AREA::accesskey',
+    'AREA::alt',
+    'AREA::coords',
+    'AREA::nohref',
+    'AREA::shape',
+    'AREA::tabindex',
+    'AREA::target',
+    'AUDIO::controls',
+    'AUDIO::loop',
+    'AUDIO::mediagroup',
+    'AUDIO::muted',
+    'AUDIO::preload',
+    'BDO::dir',
+    'BODY::alink',
+    'BODY::bgcolor',
+    'BODY::link',
+    'BODY::text',
+    'BODY::vlink',
+    'BR::clear',
+    'BUTTON::accesskey',
+    'BUTTON::disabled',
+    'BUTTON::name',
+    'BUTTON::tabindex',
+    'BUTTON::type',
+    'BUTTON::value',
+    'CANVAS::height',
+    'CANVAS::width',
+    'CAPTION::align',
+    'COL::align',
+    'COL::char',
+    'COL::charoff',
+    'COL::span',
+    'COL::valign',
+    'COL::width',
+    'COLGROUP::align',
+    'COLGROUP::char',
+    'COLGROUP::charoff',
+    'COLGROUP::span',
+    'COLGROUP::valign',
+    'COLGROUP::width',
+    'COMMAND::checked',
+    'COMMAND::command',
+    'COMMAND::disabled',
+    'COMMAND::label',
+    'COMMAND::radiogroup',
+    'COMMAND::type',
+    'DATA::value',
+    'DEL::datetime',
+    'DETAILS::open',
+    'DIR::compact',
+    'DIV::align',
+    'DL::compact',
+    'FIELDSET::disabled',
+    'FONT::color',
+    'FONT::face',
+    'FONT::size',
+    'FORM::accept',
+    'FORM::autocomplete',
+    'FORM::enctype',
+    'FORM::method',
+    'FORM::name',
+    'FORM::novalidate',
+    'FORM::target',
+    'FRAME::name',
+    'H1::align',
+    'H2::align',
+    'H3::align',
+    'H4::align',
+    'H5::align',
+    'H6::align',
+    'HR::align',
+    'HR::noshade',
+    'HR::size',
+    'HR::width',
+    'HTML::version',
+    'IFRAME::align',
+    'IFRAME::frameborder',
+    'IFRAME::height',
+    'IFRAME::marginheight',
+    'IFRAME::marginwidth',
+    'IFRAME::width',
+    'IMG::align',
+    'IMG::alt',
+    'IMG::border',
+    'IMG::height',
+    'IMG::hspace',
+    'IMG::ismap',
+    'IMG::name',
+    'IMG::usemap',
+    'IMG::vspace',
+    'IMG::width',
+    'INPUT::accept',
+    'INPUT::accesskey',
+    'INPUT::align',
+    'INPUT::alt',
+    'INPUT::autocomplete',
+    'INPUT::autofocus',
+    'INPUT::checked',
+    'INPUT::disabled',
+    'INPUT::inputmode',
+    'INPUT::ismap',
+    'INPUT::list',
+    'INPUT::max',
+    'INPUT::maxlength',
+    'INPUT::min',
+    'INPUT::multiple',
+    'INPUT::name',
+    'INPUT::placeholder',
+    'INPUT::readonly',
+    'INPUT::required',
+    'INPUT::size',
+    'INPUT::step',
+    'INPUT::tabindex',
+    'INPUT::type',
+    'INPUT::usemap',
+    'INPUT::value',
+    'INS::datetime',
+    'KEYGEN::disabled',
+    'KEYGEN::keytype',
+    'KEYGEN::name',
+    'LABEL::accesskey',
+    'LABEL::for',
+    'LEGEND::accesskey',
+    'LEGEND::align',
+    'LI::type',
+    'LI::value',
+    'LINK::sizes',
+    'MAP::name',
+    'MENU::compact',
+    'MENU::label',
+    'MENU::type',
+    'METER::high',
+    'METER::low',
+    'METER::max',
+    'METER::min',
+    'METER::value',
+    'OBJECT::typemustmatch',
+    'OL::compact',
+    'OL::reversed',
+    'OL::start',
+    'OL::type',
+    'OPTGROUP::disabled',
+    'OPTGROUP::label',
+    'OPTION::disabled',
+    'OPTION::label',
+    'OPTION::selected',
+    'OPTION::value',
+    'OUTPUT::for',
+    'OUTPUT::name',
+    'P::align',
+    'PRE::width',
+    'PROGRESS::max',
+    'PROGRESS::min',
+    'PROGRESS::value',
+    'SELECT::autocomplete',
+    'SELECT::disabled',
+    'SELECT::multiple',
+    'SELECT::name',
+    'SELECT::required',
+    'SELECT::size',
+    'SELECT::tabindex',
+    'SOURCE::type',
+    'TABLE::align',
+    'TABLE::bgcolor',
+    'TABLE::border',
+    'TABLE::cellpadding',
+    'TABLE::cellspacing',
+    'TABLE::frame',
+    'TABLE::rules',
+    'TABLE::summary',
+    'TABLE::width',
+    'TBODY::align',
+    'TBODY::char',
+    'TBODY::charoff',
+    'TBODY::valign',
+    'TD::abbr',
+    'TD::align',
+    'TD::axis',
+    'TD::bgcolor',
+    'TD::char',
+    'TD::charoff',
+    'TD::colspan',
+    'TD::headers',
+    'TD::height',
+    'TD::nowrap',
+    'TD::rowspan',
+    'TD::scope',
+    'TD::valign',
+    'TD::width',
+    'TEXTAREA::accesskey',
+    'TEXTAREA::autocomplete',
+    'TEXTAREA::cols',
+    'TEXTAREA::disabled',
+    'TEXTAREA::inputmode',
+    'TEXTAREA::name',
+    'TEXTAREA::placeholder',
+    'TEXTAREA::readonly',
+    'TEXTAREA::required',
+    'TEXTAREA::rows',
+    'TEXTAREA::tabindex',
+    'TEXTAREA::wrap',
+    'TFOOT::align',
+    'TFOOT::char',
+    'TFOOT::charoff',
+    'TFOOT::valign',
+    'TH::abbr',
+    'TH::align',
+    'TH::axis',
+    'TH::bgcolor',
+    'TH::char',
+    'TH::charoff',
+    'TH::colspan',
+    'TH::headers',
+    'TH::height',
+    'TH::nowrap',
+    'TH::rowspan',
+    'TH::scope',
+    'TH::valign',
+    'TH::width',
+    'THEAD::align',
+    'THEAD::char',
+    'THEAD::charoff',
+    'THEAD::valign',
+    'TR::align',
+    'TR::bgcolor',
+    'TR::char',
+    'TR::charoff',
+    'TR::valign',
+    'TRACK::default',
+    'TRACK::kind',
+    'TRACK::label',
+    'TRACK::srclang',
+    'UL::compact',
+    'UL::type',
+    'VIDEO::controls',
+    'VIDEO::height',
+    'VIDEO::loop',
+    'VIDEO::mediagroup',
+    'VIDEO::muted',
+    'VIDEO::preload',
+    'VIDEO::width',
+  ];
+
+  static const _uriAttributes = const <String>[
+    'A::href',
+    'AREA::href',
+    'BLOCKQUOTE::cite',
+    'BODY::background',
+    'COMMAND::icon',
+    'DEL::cite',
+    'FORM::action',
+    'IMG::src',
+    'INPUT::src',
+    'INS::cite',
+    'Q::cite',
+    'VIDEO::poster',
+  ];
+
+  final UriPolicy uriPolicy;
+
+  static final Map<String, Function> _attributeValidators = {};
+
+  /**
+   * All known URI attributes will be validated against the UriPolicy, if
+   * [uriPolicy] is null then a default UriPolicy will be used.
+   */
+  _Html5NodeValidator({UriPolicy uriPolicy})
+      : uriPolicy = uriPolicy != null ? uriPolicy : new UriPolicy() {
+    if (_attributeValidators.isEmpty) {
+      for (var attr in _standardAttributes) {
+        _attributeValidators[attr] = _standardAttributeValidator;
+      }
+
+      for (var attr in _uriAttributes) {
+        _attributeValidators[attr] = _uriAttributeValidator;
+      }
+    }
+  }
+
+  bool allowsElement(Element element) {
+    return _allowedElements.contains(Element._safeTagName(element));
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    var tagName = Element._safeTagName(element);
+    var validator = _attributeValidators['$tagName::$attributeName'];
+    if (validator == null) {
+      validator = _attributeValidators['*::$attributeName'];
+    }
+    if (validator == null) {
+      return false;
+    }
+    return validator(element, attributeName, value, this);
+  }
+
+  static bool _standardAttributeValidator(Element element, String attributeName,
+      String value, _Html5NodeValidator context) {
+    return true;
+  }
+
+  static bool _uriAttributeValidator(Element element, String attributeName,
+      String value, _Html5NodeValidator context) {
+    return context.uriPolicy.allowsUri(value);
+  }
+}
+// Copyright (c) 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.
+
+abstract class ImmutableListMixin<E> implements List<E> {
+  // From Iterable<$E>:
+  Iterator<E> get iterator {
+    // Note: NodeLists are not fixed size. And most probably length shouldn't
+    // be cached in both iterator _and_ forEach method. For now caching it
+    // for consistency.
+    return new FixedSizeListIterator<E>(this);
+  }
+
+  // From List<E>:
+  void add(E value) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void addAll(Iterable<E> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void sort([int compare(E a, E b)]) {
+    throw new UnsupportedError("Cannot sort immutable List.");
+  }
+
+  void shuffle([Random random]) {
+    throw new UnsupportedError("Cannot shuffle immutable List.");
+  }
+
+  void insert(int index, E element) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void insertAll(int index, Iterable<E> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<E> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  E removeAt(int pos) {
+    throw new UnsupportedError("Cannot remove from immutable List.");
+  }
+
+  E removeLast() {
+    throw new UnsupportedError("Cannot remove from immutable List.");
+  }
+
+  bool remove(Object object) {
+    throw new UnsupportedError("Cannot remove from immutable List.");
+  }
+
+  void removeWhere(bool test(E element)) {
+    throw new UnsupportedError("Cannot remove from immutable List.");
+  }
+
+  void retainWhere(bool test(E element)) {
+    throw new UnsupportedError("Cannot remove from immutable List.");
+  }
+
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+    throw new UnsupportedError("Cannot setRange on immutable List.");
+  }
+
+  void removeRange(int start, int end) {
+    throw new UnsupportedError("Cannot removeRange on immutable List.");
+  }
+
+  void replaceRange(int start, int end, Iterable<E> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [E fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+}
+// Copyright (c) 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.
+
+/**
+ * Defines the keycode values for keys that are returned by
+ * KeyboardEvent.keyCode.
+ *
+ * Important note: There is substantial divergence in how different browsers
+ * handle keycodes and their variants in different locales/keyboard layouts. We
+ * provide these constants to help make code processing keys more readable.
+ */
+abstract class KeyCode {
+  // These constant names were borrowed from Closure's Keycode enumeration
+  // class.
+  // https://github.com/google/closure-library/blob/master/closure/goog/events/keycodes.js
+  static const int WIN_KEY_FF_LINUX = 0;
+  static const int MAC_ENTER = 3;
+  static const int BACKSPACE = 8;
+  static const int TAB = 9;
+  /** NUM_CENTER is also NUMLOCK for FF and Safari on Mac. */
+  static const int NUM_CENTER = 12;
+  static const int ENTER = 13;
+  static const int SHIFT = 16;
+  static const int CTRL = 17;
+  static const int ALT = 18;
+  static const int PAUSE = 19;
+  static const int CAPS_LOCK = 20;
+  static const int ESC = 27;
+  static const int SPACE = 32;
+  static const int PAGE_UP = 33;
+  static const int PAGE_DOWN = 34;
+  static const int END = 35;
+  static const int HOME = 36;
+  static const int LEFT = 37;
+  static const int UP = 38;
+  static const int RIGHT = 39;
+  static const int DOWN = 40;
+  static const int NUM_NORTH_EAST = 33;
+  static const int NUM_SOUTH_EAST = 34;
+  static const int NUM_SOUTH_WEST = 35;
+  static const int NUM_NORTH_WEST = 36;
+  static const int NUM_WEST = 37;
+  static const int NUM_NORTH = 38;
+  static const int NUM_EAST = 39;
+  static const int NUM_SOUTH = 40;
+  static const int PRINT_SCREEN = 44;
+  static const int INSERT = 45;
+  static const int NUM_INSERT = 45;
+  static const int DELETE = 46;
+  static const int NUM_DELETE = 46;
+  static const int ZERO = 48;
+  static const int ONE = 49;
+  static const int TWO = 50;
+  static const int THREE = 51;
+  static const int FOUR = 52;
+  static const int FIVE = 53;
+  static const int SIX = 54;
+  static const int SEVEN = 55;
+  static const int EIGHT = 56;
+  static const int NINE = 57;
+  static const int FF_SEMICOLON = 59;
+  static const int FF_EQUALS = 61;
+  /**
+   * CAUTION: The question mark is for US-keyboard layouts. It varies
+   * for other locales and keyboard layouts.
+   */
+  static const int QUESTION_MARK = 63;
+  static const int A = 65;
+  static const int B = 66;
+  static const int C = 67;
+  static const int D = 68;
+  static const int E = 69;
+  static const int F = 70;
+  static const int G = 71;
+  static const int H = 72;
+  static const int I = 73;
+  static const int J = 74;
+  static const int K = 75;
+  static const int L = 76;
+  static const int M = 77;
+  static const int N = 78;
+  static const int O = 79;
+  static const int P = 80;
+  static const int Q = 81;
+  static const int R = 82;
+  static const int S = 83;
+  static const int T = 84;
+  static const int U = 85;
+  static const int V = 86;
+  static const int W = 87;
+  static const int X = 88;
+  static const int Y = 89;
+  static const int Z = 90;
+  static const int META = 91;
+  static const int WIN_KEY_LEFT = 91;
+  static const int WIN_KEY_RIGHT = 92;
+  static const int CONTEXT_MENU = 93;
+  static const int NUM_ZERO = 96;
+  static const int NUM_ONE = 97;
+  static const int NUM_TWO = 98;
+  static const int NUM_THREE = 99;
+  static const int NUM_FOUR = 100;
+  static const int NUM_FIVE = 101;
+  static const int NUM_SIX = 102;
+  static const int NUM_SEVEN = 103;
+  static const int NUM_EIGHT = 104;
+  static const int NUM_NINE = 105;
+  static const int NUM_MULTIPLY = 106;
+  static const int NUM_PLUS = 107;
+  static const int NUM_MINUS = 109;
+  static const int NUM_PERIOD = 110;
+  static const int NUM_DIVISION = 111;
+  static const int F1 = 112;
+  static const int F2 = 113;
+  static const int F3 = 114;
+  static const int F4 = 115;
+  static const int F5 = 116;
+  static const int F6 = 117;
+  static const int F7 = 118;
+  static const int F8 = 119;
+  static const int F9 = 120;
+  static const int F10 = 121;
+  static const int F11 = 122;
+  static const int F12 = 123;
+  static const int NUMLOCK = 144;
+  static const int SCROLL_LOCK = 145;
+
+  // OS-specific media keys like volume controls and browser controls.
+  static const int FIRST_MEDIA_KEY = 166;
+  static const int LAST_MEDIA_KEY = 183;
+
+  /**
+   * CAUTION: This constant requires localization for other locales and keyboard
+   * layouts.
+   */
+  static const int SEMICOLON = 186;
+  /**
+   * CAUTION: This constant requires localization for other locales and keyboard
+   * layouts.
+   */
+  static const int DASH = 189;
+  /**
+   * CAUTION: This constant requires localization for other locales and keyboard
+   * layouts.
+   */
+  static const int EQUALS = 187;
+  /**
+   * CAUTION: This constant requires localization for other locales and keyboard
+   * layouts.
+   */
+  static const int COMMA = 188;
+  /**
+   * CAUTION: This constant requires localization for other locales and keyboard
+   * layouts.
+   */
+  static const int PERIOD = 190;
+  /**
+   * CAUTION: This constant requires localization for other locales and keyboard
+   * layouts.
+   */
+  static const int SLASH = 191;
+  /**
+   * CAUTION: This constant requires localization for other locales and keyboard
+   * layouts.
+   */
+  static const int APOSTROPHE = 192;
+  /**
+   * CAUTION: This constant requires localization for other locales and keyboard
+   * layouts.
+   */
+  static const int TILDE = 192;
+  /**
+   * CAUTION: This constant requires localization for other locales and keyboard
+   * layouts.
+   */
+  static const int SINGLE_QUOTE = 222;
+  /**
+   * CAUTION: This constant requires localization for other locales and keyboard
+   * layouts.
+   */
+  static const int OPEN_SQUARE_BRACKET = 219;
+  /**
+   * CAUTION: This constant requires localization for other locales and keyboard
+   * layouts.
+   */
+  static const int BACKSLASH = 220;
+  /**
+   * CAUTION: This constant requires localization for other locales and keyboard
+   * layouts.
+   */
+  static const int CLOSE_SQUARE_BRACKET = 221;
+  static const int WIN_KEY = 224;
+  static const int MAC_FF_META = 224;
+  static const int WIN_IME = 229;
+
+  /** A sentinel value if the keycode could not be determined. */
+  static const int UNKNOWN = -1;
+
+  /**
+   * Returns true if the keyCode produces a (US keyboard) character.
+   * Note: This does not (yet) cover characters on non-US keyboards (Russian,
+   * Hebrew, etc.).
+   */
+  static bool isCharacterKey(int keyCode) {
+    if ((keyCode >= ZERO && keyCode <= NINE) ||
+        (keyCode >= NUM_ZERO && keyCode <= NUM_MULTIPLY) ||
+        (keyCode >= A && keyCode <= Z)) {
+      return true;
+    }
+
+    // Safari sends zero key code for non-latin characters.
+    if (Device.isWebKit && keyCode == 0) {
+      return true;
+    }
+
+    return (keyCode == SPACE ||
+        keyCode == QUESTION_MARK ||
+        keyCode == NUM_PLUS ||
+        keyCode == NUM_MINUS ||
+        keyCode == NUM_PERIOD ||
+        keyCode == NUM_DIVISION ||
+        keyCode == SEMICOLON ||
+        keyCode == FF_SEMICOLON ||
+        keyCode == DASH ||
+        keyCode == EQUALS ||
+        keyCode == FF_EQUALS ||
+        keyCode == COMMA ||
+        keyCode == PERIOD ||
+        keyCode == SLASH ||
+        keyCode == APOSTROPHE ||
+        keyCode == SINGLE_QUOTE ||
+        keyCode == OPEN_SQUARE_BRACKET ||
+        keyCode == BACKSLASH ||
+        keyCode == CLOSE_SQUARE_BRACKET);
+  }
+
+  /**
+   * Experimental helper function for converting keyCodes to keyNames for the
+   * keyIdentifier attribute still used in browsers not updated with current
+   * spec. This is an imperfect conversion! It will need to be refined, but
+   * hopefully it can just completely go away once all the browsers update to
+   * follow the DOM3 spec.
+   */
+  static String _convertKeyCodeToKeyName(int keyCode) {
+    switch (keyCode) {
+      case KeyCode.ALT:
+        return _KeyName.ALT;
+      case KeyCode.BACKSPACE:
+        return _KeyName.BACKSPACE;
+      case KeyCode.CAPS_LOCK:
+        return _KeyName.CAPS_LOCK;
+      case KeyCode.CTRL:
+        return _KeyName.CONTROL;
+      case KeyCode.DELETE:
+        return _KeyName.DEL;
+      case KeyCode.DOWN:
+        return _KeyName.DOWN;
+      case KeyCode.END:
+        return _KeyName.END;
+      case KeyCode.ENTER:
+        return _KeyName.ENTER;
+      case KeyCode.ESC:
+        return _KeyName.ESC;
+      case KeyCode.F1:
+        return _KeyName.F1;
+      case KeyCode.F2:
+        return _KeyName.F2;
+      case KeyCode.F3:
+        return _KeyName.F3;
+      case KeyCode.F4:
+        return _KeyName.F4;
+      case KeyCode.F5:
+        return _KeyName.F5;
+      case KeyCode.F6:
+        return _KeyName.F6;
+      case KeyCode.F7:
+        return _KeyName.F7;
+      case KeyCode.F8:
+        return _KeyName.F8;
+      case KeyCode.F9:
+        return _KeyName.F9;
+      case KeyCode.F10:
+        return _KeyName.F10;
+      case KeyCode.F11:
+        return _KeyName.F11;
+      case KeyCode.F12:
+        return _KeyName.F12;
+      case KeyCode.HOME:
+        return _KeyName.HOME;
+      case KeyCode.INSERT:
+        return _KeyName.INSERT;
+      case KeyCode.LEFT:
+        return _KeyName.LEFT;
+      case KeyCode.META:
+        return _KeyName.META;
+      case KeyCode.NUMLOCK:
+        return _KeyName.NUM_LOCK;
+      case KeyCode.PAGE_DOWN:
+        return _KeyName.PAGE_DOWN;
+      case KeyCode.PAGE_UP:
+        return _KeyName.PAGE_UP;
+      case KeyCode.PAUSE:
+        return _KeyName.PAUSE;
+      case KeyCode.PRINT_SCREEN:
+        return _KeyName.PRINT_SCREEN;
+      case KeyCode.RIGHT:
+        return _KeyName.RIGHT;
+      case KeyCode.SCROLL_LOCK:
+        return _KeyName.SCROLL;
+      case KeyCode.SHIFT:
+        return _KeyName.SHIFT;
+      case KeyCode.SPACE:
+        return _KeyName.SPACEBAR;
+      case KeyCode.TAB:
+        return _KeyName.TAB;
+      case KeyCode.UP:
+        return _KeyName.UP;
+      case KeyCode.WIN_IME:
+      case KeyCode.WIN_KEY:
+      case KeyCode.WIN_KEY_LEFT:
+      case KeyCode.WIN_KEY_RIGHT:
+        return _KeyName.WIN;
+      default:
+        return _KeyName.UNIDENTIFIED;
+    }
+    return _KeyName.UNIDENTIFIED;
+  }
+}
+// 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.
+
+/**
+ * Defines the standard key locations returned by
+ * KeyboardEvent.getKeyLocation.
+ */
+abstract class KeyLocation {
+  /**
+   * The event key is not distinguished as the left or right version
+   * of the key, and did not originate from the numeric keypad (or did not
+   * originate with a virtual key corresponding to the numeric keypad).
+   */
+  static const int STANDARD = 0;
+
+  /**
+   * The event key is in the left key location.
+   */
+  static const int LEFT = 1;
+
+  /**
+   * The event key is in the right key location.
+   */
+  static const int RIGHT = 2;
+
+  /**
+   * The event key originated on the numeric keypad or with a virtual key
+   * corresponding to the numeric keypad.
+   */
+  static const int NUMPAD = 3;
+
+  /**
+   * The event key originated on a mobile device, either on a physical
+   * keypad or a virtual keyboard.
+   */
+  static const int MOBILE = 4;
+
+  /**
+   * The event key originated on a game controller or a joystick on a mobile
+   * device.
+   */
+  static const int JOYSTICK = 5;
+}
+// Copyright (c) 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.
+
+/**
+ * Defines the standard keyboard identifier names for keys that are returned
+ * by KeyboardEvent.getKeyboardIdentifier when the key does not have a direct
+ * unicode mapping.
+ */
+abstract class _KeyName {
+  /** The Accept (Commit, OK) key */
+  static const String ACCEPT = "Accept";
+
+  /** The Add key */
+  static const String ADD = "Add";
+
+  /** The Again key */
+  static const String AGAIN = "Again";
+
+  /** The All Candidates key */
+  static const String ALL_CANDIDATES = "AllCandidates";
+
+  /** The Alphanumeric key */
+  static const String ALPHANUMERIC = "Alphanumeric";
+
+  /** The Alt (Menu) key */
+  static const String ALT = "Alt";
+
+  /** The Alt-Graph key */
+  static const String ALT_GRAPH = "AltGraph";
+
+  /** The Application key */
+  static const String APPS = "Apps";
+
+  /** The ATTN key */
+  static const String ATTN = "Attn";
+
+  /** The Browser Back key */
+  static const String BROWSER_BACK = "BrowserBack";
+
+  /** The Browser Favorites key */
+  static const String BROWSER_FAVORTIES = "BrowserFavorites";
+
+  /** The Browser Forward key */
+  static const String BROWSER_FORWARD = "BrowserForward";
+
+  /** The Browser Home key */
+  static const String BROWSER_NAME = "BrowserHome";
+
+  /** The Browser Refresh key */
+  static const String BROWSER_REFRESH = "BrowserRefresh";
+
+  /** The Browser Search key */
+  static const String BROWSER_SEARCH = "BrowserSearch";
+
+  /** The Browser Stop key */
+  static const String BROWSER_STOP = "BrowserStop";
+
+  /** The Camera key */
+  static const String CAMERA = "Camera";
+
+  /** The Caps Lock (Capital) key */
+  static const String CAPS_LOCK = "CapsLock";
+
+  /** The Clear key */
+  static const String CLEAR = "Clear";
+
+  /** The Code Input key */
+  static const String CODE_INPUT = "CodeInput";
+
+  /** The Compose key */
+  static const String COMPOSE = "Compose";
+
+  /** The Control (Ctrl) key */
+  static const String CONTROL = "Control";
+
+  /** The Crsel key */
+  static const String CRSEL = "Crsel";
+
+  /** The Convert key */
+  static const String CONVERT = "Convert";
+
+  /** The Copy key */
+  static const String COPY = "Copy";
+
+  /** The Cut key */
+  static const String CUT = "Cut";
+
+  /** The Decimal key */
+  static const String DECIMAL = "Decimal";
+
+  /** The Divide key */
+  static const String DIVIDE = "Divide";
+
+  /** The Down Arrow key */
+  static const String DOWN = "Down";
+
+  /** The diagonal Down-Left Arrow key */
+  static const String DOWN_LEFT = "DownLeft";
+
+  /** The diagonal Down-Right Arrow key */
+  static const String DOWN_RIGHT = "DownRight";
+
+  /** The Eject key */
+  static const String EJECT = "Eject";
+
+  /** The End key */
+  static const String END = "End";
+
+  /**
+   * The Enter key. Note: This key value must also be used for the Return
+   *  (Macintosh numpad) key
+   */
+  static const String ENTER = "Enter";
+
+  /** The Erase EOF key */
+  static const String ERASE_EOF = "EraseEof";
+
+  /** The Execute key */
+  static const String EXECUTE = "Execute";
+
+  /** The Exsel key */
+  static const String EXSEL = "Exsel";
+
+  /** The Function switch key */
+  static const String FN = "Fn";
+
+  /** The F1 key */
+  static const String F1 = "F1";
+
+  /** The F2 key */
+  static const String F2 = "F2";
+
+  /** The F3 key */
+  static const String F3 = "F3";
+
+  /** The F4 key */
+  static const String F4 = "F4";
+
+  /** The F5 key */
+  static const String F5 = "F5";
+
+  /** The F6 key */
+  static const String F6 = "F6";
+
+  /** The F7 key */
+  static const String F7 = "F7";
+
+  /** The F8 key */
+  static const String F8 = "F8";
+
+  /** The F9 key */
+  static const String F9 = "F9";
+
+  /** The F10 key */
+  static const String F10 = "F10";
+
+  /** The F11 key */
+  static const String F11 = "F11";
+
+  /** The F12 key */
+  static const String F12 = "F12";
+
+  /** The F13 key */
+  static const String F13 = "F13";
+
+  /** The F14 key */
+  static const String F14 = "F14";
+
+  /** The F15 key */
+  static const String F15 = "F15";
+
+  /** The F16 key */
+  static const String F16 = "F16";
+
+  /** The F17 key */
+  static const String F17 = "F17";
+
+  /** The F18 key */
+  static const String F18 = "F18";
+
+  /** The F19 key */
+  static const String F19 = "F19";
+
+  /** The F20 key */
+  static const String F20 = "F20";
+
+  /** The F21 key */
+  static const String F21 = "F21";
+
+  /** The F22 key */
+  static const String F22 = "F22";
+
+  /** The F23 key */
+  static const String F23 = "F23";
+
+  /** The F24 key */
+  static const String F24 = "F24";
+
+  /** The Final Mode (Final) key used on some asian keyboards */
+  static const String FINAL_MODE = "FinalMode";
+
+  /** The Find key */
+  static const String FIND = "Find";
+
+  /** The Full-Width Characters key */
+  static const String FULL_WIDTH = "FullWidth";
+
+  /** The Half-Width Characters key */
+  static const String HALF_WIDTH = "HalfWidth";
+
+  /** The Hangul (Korean characters) Mode key */
+  static const String HANGUL_MODE = "HangulMode";
+
+  /** The Hanja (Korean characters) Mode key */
+  static const String HANJA_MODE = "HanjaMode";
+
+  /** The Help key */
+  static const String HELP = "Help";
+
+  /** The Hiragana (Japanese Kana characters) key */
+  static const String HIRAGANA = "Hiragana";
+
+  /** The Home key */
+  static const String HOME = "Home";
+
+  /** The Insert (Ins) key */
+  static const String INSERT = "Insert";
+
+  /** The Japanese-Hiragana key */
+  static const String JAPANESE_HIRAGANA = "JapaneseHiragana";
+
+  /** The Japanese-Katakana key */
+  static const String JAPANESE_KATAKANA = "JapaneseKatakana";
+
+  /** The Japanese-Romaji key */
+  static const String JAPANESE_ROMAJI = "JapaneseRomaji";
+
+  /** The Junja Mode key */
+  static const String JUNJA_MODE = "JunjaMode";
+
+  /** The Kana Mode (Kana Lock) key */
+  static const String KANA_MODE = "KanaMode";
+
+  /**
+   * The Kanji (Japanese name for ideographic characters of Chinese origin)
+   * Mode key
+   */
+  static const String KANJI_MODE = "KanjiMode";
+
+  /** The Katakana (Japanese Kana characters) key */
+  static const String KATAKANA = "Katakana";
+
+  /** The Start Application One key */
+  static const String LAUNCH_APPLICATION_1 = "LaunchApplication1";
+
+  /** The Start Application Two key */
+  static const String LAUNCH_APPLICATION_2 = "LaunchApplication2";
+
+  /** The Start Mail key */
+  static const String LAUNCH_MAIL = "LaunchMail";
+
+  /** The Left Arrow key */
+  static const String LEFT = "Left";
+
+  /** The Menu key */
+  static const String MENU = "Menu";
+
+  /**
+   * The Meta key. Note: This key value shall be also used for the Apple
+   * Command key
+   */
+  static const String META = "Meta";
+
+  /** The Media Next Track key */
+  static const String MEDIA_NEXT_TRACK = "MediaNextTrack";
+
+  /** The Media Play Pause key */
+  static const String MEDIA_PAUSE_PLAY = "MediaPlayPause";
+
+  /** The Media Previous Track key */
+  static const String MEDIA_PREVIOUS_TRACK = "MediaPreviousTrack";
+
+  /** The Media Stop key */
+  static const String MEDIA_STOP = "MediaStop";
+
+  /** The Mode Change key */
+  static const String MODE_CHANGE = "ModeChange";
+
+  /** The Next Candidate function key */
+  static const String NEXT_CANDIDATE = "NextCandidate";
+
+  /** The Nonconvert (Don't Convert) key */
+  static const String NON_CONVERT = "Nonconvert";
+
+  /** The Number Lock key */
+  static const String NUM_LOCK = "NumLock";
+
+  /** The Page Down (Next) key */
+  static const String PAGE_DOWN = "PageDown";
+
+  /** The Page Up key */
+  static const String PAGE_UP = "PageUp";
+
+  /** The Paste key */
+  static const String PASTE = "Paste";
+
+  /** The Pause key */
+  static const String PAUSE = "Pause";
+
+  /** The Play key */
+  static const String PLAY = "Play";
+
+  /**
+   * The Power key. Note: Some devices may not expose this key to the
+   * operating environment
+   */
+  static const String POWER = "Power";
+
+  /** The Previous Candidate function key */
+  static const String PREVIOUS_CANDIDATE = "PreviousCandidate";
+
+  /** The Print Screen (PrintScrn, SnapShot) key */
+  static const String PRINT_SCREEN = "PrintScreen";
+
+  /** The Process key */
+  static const String PROCESS = "Process";
+
+  /** The Props key */
+  static const String PROPS = "Props";
+
+  /** The Right Arrow key */
+  static const String RIGHT = "Right";
+
+  /** The Roman Characters function key */
+  static const String ROMAN_CHARACTERS = "RomanCharacters";
+
+  /** The Scroll Lock key */
+  static const String SCROLL = "Scroll";
+
+  /** The Select key */
+  static const String SELECT = "Select";
+
+  /** The Select Media key */
+  static const String SELECT_MEDIA = "SelectMedia";
+
+  /** The Separator key */
+  static const String SEPARATOR = "Separator";
+
+  /** The Shift key */
+  static const String SHIFT = "Shift";
+
+  /** The Soft1 key */
+  static const String SOFT_1 = "Soft1";
+
+  /** The Soft2 key */
+  static const String SOFT_2 = "Soft2";
+
+  /** The Soft3 key */
+  static const String SOFT_3 = "Soft3";
+
+  /** The Soft4 key */
+  static const String SOFT_4 = "Soft4";
+
+  /** The Stop key */
+  static const String STOP = "Stop";
+
+  /** The Subtract key */
+  static const String SUBTRACT = "Subtract";
+
+  /** The Symbol Lock key */
+  static const String SYMBOL_LOCK = "SymbolLock";
+
+  /** The Up Arrow key */
+  static const String UP = "Up";
+
+  /** The diagonal Up-Left Arrow key */
+  static const String UP_LEFT = "UpLeft";
+
+  /** The diagonal Up-Right Arrow key */
+  static const String UP_RIGHT = "UpRight";
+
+  /** The Undo key */
+  static const String UNDO = "Undo";
+
+  /** The Volume Down key */
+  static const String VOLUME_DOWN = "VolumeDown";
+
+  /** The Volume Mute key */
+  static const String VOLUMN_MUTE = "VolumeMute";
+
+  /** The Volume Up key */
+  static const String VOLUMN_UP = "VolumeUp";
+
+  /** The Windows Logo key */
+  static const String WIN = "Win";
+
+  /** The Zoom key */
+  static const String ZOOM = "Zoom";
+
+  /**
+   * The Backspace (Back) key. Note: This key value shall be also used for the
+   * key labeled 'delete' MacOS keyboards when not modified by the 'Fn' key
+   */
+  static const String BACKSPACE = "Backspace";
+
+  /** The Horizontal Tabulation (Tab) key */
+  static const String TAB = "Tab";
+
+  /** The Cancel key */
+  static const String CANCEL = "Cancel";
+
+  /** The Escape (Esc) key */
+  static const String ESC = "Esc";
+
+  /** The Space (Spacebar) key:   */
+  static const String SPACEBAR = "Spacebar";
+
+  /**
+   * The Delete (Del) Key. Note: This key value shall be also used for the key
+   * labeled 'delete' MacOS keyboards when modified by the 'Fn' key
+   */
+  static const String DEL = "Del";
+
+  /** The Combining Grave Accent (Greek Varia, Dead Grave) key */
+  static const String DEAD_GRAVE = "DeadGrave";
+
+  /**
+   * The Combining Acute Accent (Stress Mark, Greek Oxia, Tonos, Dead Eacute)
+   * key
+   */
+  static const String DEAD_EACUTE = "DeadEacute";
+
+  /** The Combining Circumflex Accent (Hat, Dead Circumflex) key */
+  static const String DEAD_CIRCUMFLEX = "DeadCircumflex";
+
+  /** The Combining Tilde (Dead Tilde) key */
+  static const String DEAD_TILDE = "DeadTilde";
+
+  /** The Combining Macron (Long, Dead Macron) key */
+  static const String DEAD_MACRON = "DeadMacron";
+
+  /** The Combining Breve (Short, Dead Breve) key */
+  static const String DEAD_BREVE = "DeadBreve";
+
+  /** The Combining Dot Above (Derivative, Dead Above Dot) key */
+  static const String DEAD_ABOVE_DOT = "DeadAboveDot";
+
+  /**
+   * The Combining Diaeresis (Double Dot Abode, Umlaut, Greek Dialytika,
+   * Double Derivative, Dead Diaeresis) key
+   */
+  static const String DEAD_UMLAUT = "DeadUmlaut";
+
+  /** The Combining Ring Above (Dead Above Ring) key */
+  static const String DEAD_ABOVE_RING = "DeadAboveRing";
+
+  /** The Combining Double Acute Accent (Dead Doubleacute) key */
+  static const String DEAD_DOUBLEACUTE = "DeadDoubleacute";
+
+  /** The Combining Caron (Hacek, V Above, Dead Caron) key */
+  static const String DEAD_CARON = "DeadCaron";
+
+  /** The Combining Cedilla (Dead Cedilla) key */
+  static const String DEAD_CEDILLA = "DeadCedilla";
+
+  /** The Combining Ogonek (Nasal Hook, Dead Ogonek) key */
+  static const String DEAD_OGONEK = "DeadOgonek";
+
+  /**
+   * The Combining Greek Ypogegrammeni (Greek Non-Spacing Iota Below, Iota
+   * Subscript, Dead Iota) key
+   */
+  static const String DEAD_IOTA = "DeadIota";
+
+  /**
+   * The Combining Katakana-Hiragana Voiced Sound Mark (Dead Voiced Sound) key
+   */
+  static const String DEAD_VOICED_SOUND = "DeadVoicedSound";
+
+  /**
+   * The Combining Katakana-Hiragana Semi-Voiced Sound Mark (Dead Semivoiced
+   * Sound) key
+   */
+  static const String DEC_SEMIVOICED_SOUND = "DeadSemivoicedSound";
+
+  /**
+   * Key value used when an implementation is unable to identify another key
+   * value, due to either hardware, platform, or software constraints
+   */
+  static const String UNIDENTIFIED = "Unidentified";
+}
+// Copyright (c) 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.
+
+/**
+ * Internal class that does the actual calculations to determine keyCode and
+ * charCode for keydown, keypress, and keyup events for all browsers.
+ */
+class _KeyboardEventHandler extends EventStreamProvider<KeyEvent> {
+  // This code inspired by Closure's KeyHandling library.
+  // https://github.com/google/closure-library/blob/master/closure/goog/events/keyhandler.js
+
+  /**
+   * The set of keys that have been pressed down without seeing their
+   * corresponding keyup event.
+   */
+  final List<KeyEvent> _keyDownList = <KeyEvent>[];
+
+  /** The type of KeyEvent we are tracking (keyup, keydown, keypress). */
+  final String _type;
+
+  /** The element we are watching for events to happen on. */
+  final EventTarget _target;
+
+  // The distance to shift from upper case alphabet Roman letters to lower case.
+  static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0];
+
+  /** Custom Stream (Controller) to produce KeyEvents for the stream. */
+  _CustomKeyEventStreamImpl _stream;
+
+  static const _EVENT_TYPE = 'KeyEvent';
+
+  /**
+   * An enumeration of key identifiers currently part of the W3C draft for DOM3
+   * and their mappings to keyCodes.
+   * https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/keyset.html#KeySet-Set
+   */
+  static const Map<String, int> _keyIdentifier = const {
+    'Up': KeyCode.UP,
+    'Down': KeyCode.DOWN,
+    'Left': KeyCode.LEFT,
+    'Right': KeyCode.RIGHT,
+    'Enter': KeyCode.ENTER,
+    'F1': KeyCode.F1,
+    'F2': KeyCode.F2,
+    'F3': KeyCode.F3,
+    'F4': KeyCode.F4,
+    'F5': KeyCode.F5,
+    'F6': KeyCode.F6,
+    'F7': KeyCode.F7,
+    'F8': KeyCode.F8,
+    'F9': KeyCode.F9,
+    'F10': KeyCode.F10,
+    'F11': KeyCode.F11,
+    'F12': KeyCode.F12,
+    'U+007F': KeyCode.DELETE,
+    'Home': KeyCode.HOME,
+    'End': KeyCode.END,
+    'PageUp': KeyCode.PAGE_UP,
+    'PageDown': KeyCode.PAGE_DOWN,
+    'Insert': KeyCode.INSERT
+  };
+
+  /** Return a stream for KeyEvents for the specified target. */
+  // Note: this actually functions like a factory constructor.
+  CustomStream<KeyEvent> forTarget(EventTarget e, {bool useCapture: false}) {
+    var handler =
+        new _KeyboardEventHandler.initializeAllEventListeners(_type, e);
+    return handler._stream;
+  }
+
+  /**
+   * General constructor, performs basic initialization for our improved
+   * KeyboardEvent controller.
+   */
+  _KeyboardEventHandler(this._type)
+      : _stream = new _CustomKeyEventStreamImpl('event'),
+        _target = null,
+        super(_EVENT_TYPE);
+
+  /**
+   * Hook up all event listeners under the covers so we can estimate keycodes
+   * and charcodes when they are not provided.
+   */
+  _KeyboardEventHandler.initializeAllEventListeners(this._type, this._target)
+      : super(_EVENT_TYPE) {
+    Element.keyDownEvent
+        .forTarget(_target, useCapture: true)
+        .listen(processKeyDown);
+    Element.keyPressEvent
+        .forTarget(_target, useCapture: true)
+        .listen(processKeyPress);
+    Element.keyUpEvent
+        .forTarget(_target, useCapture: true)
+        .listen(processKeyUp);
+    _stream = new _CustomKeyEventStreamImpl(_type);
+  }
+
+  /** Determine if caps lock is one of the currently depressed keys. */
+  bool get _capsLockOn =>
+      _keyDownList.any((var element) => element.keyCode == KeyCode.CAPS_LOCK);
+
+  /**
+   * Given the previously recorded keydown key codes, see if we can determine
+   * the keycode of this keypress [event]. (Generally browsers only provide
+   * charCode information for keypress events, but with a little
+   * reverse-engineering, we can also determine the keyCode.) Returns
+   * KeyCode.UNKNOWN if the keycode could not be determined.
+   */
+  int _determineKeyCodeForKeypress(KeyboardEvent event) {
+    // Note: This function is a work in progress. We'll expand this function
+    // once we get more information about other keyboards.
+    for (var prevEvent in _keyDownList) {
+      if (prevEvent._shadowCharCode == event.charCode) {
+        return prevEvent.keyCode;
+      }
+      if ((event.shiftKey || _capsLockOn) &&
+          event.charCode >= "A".codeUnits[0] &&
+          event.charCode <= "Z".codeUnits[0] &&
+          event.charCode + _ROMAN_ALPHABET_OFFSET ==
+              prevEvent._shadowCharCode) {
+        return prevEvent.keyCode;
+      }
+    }
+    return KeyCode.UNKNOWN;
+  }
+
+  /**
+   * Given the character code returned from a keyDown [event], try to ascertain
+   * and return the corresponding charCode for the character that was pressed.
+   * This information is not shown to the user, but used to help polyfill
+   * keypress events.
+   */
+  int _findCharCodeKeyDown(KeyboardEvent event) {
+    if (event.location == 3) {
+      // Numpad keys.
+      switch (event.keyCode) {
+        case KeyCode.NUM_ZERO:
+          // Even though this function returns _charCodes_, for some cases the
+          // KeyCode == the charCode we want, in which case we use the keycode
+          // constant for readability.
+          return KeyCode.ZERO;
+        case KeyCode.NUM_ONE:
+          return KeyCode.ONE;
+        case KeyCode.NUM_TWO:
+          return KeyCode.TWO;
+        case KeyCode.NUM_THREE:
+          return KeyCode.THREE;
+        case KeyCode.NUM_FOUR:
+          return KeyCode.FOUR;
+        case KeyCode.NUM_FIVE:
+          return KeyCode.FIVE;
+        case KeyCode.NUM_SIX:
+          return KeyCode.SIX;
+        case KeyCode.NUM_SEVEN:
+          return KeyCode.SEVEN;
+        case KeyCode.NUM_EIGHT:
+          return KeyCode.EIGHT;
+        case KeyCode.NUM_NINE:
+          return KeyCode.NINE;
+        case KeyCode.NUM_MULTIPLY:
+          return 42; // Char code for *
+        case KeyCode.NUM_PLUS:
+          return 43; // +
+        case KeyCode.NUM_MINUS:
+          return 45; // -
+        case KeyCode.NUM_PERIOD:
+          return 46; // .
+        case KeyCode.NUM_DIVISION:
+          return 47; // /
+      }
+    } else if (event.keyCode >= 65 && event.keyCode <= 90) {
+      // Set the "char code" for key down as the lower case letter. Again, this
+      // will not show up for the user, but will be helpful in estimating
+      // keyCode locations and other information during the keyPress event.
+      return event.keyCode + _ROMAN_ALPHABET_OFFSET;
+    }
+    switch (event.keyCode) {
+      case KeyCode.SEMICOLON:
+        return KeyCode.FF_SEMICOLON;
+      case KeyCode.EQUALS:
+        return KeyCode.FF_EQUALS;
+      case KeyCode.COMMA:
+        return 44; // Ascii value for ,
+      case KeyCode.DASH:
+        return 45; // -
+      case KeyCode.PERIOD:
+        return 46; // .
+      case KeyCode.SLASH:
+        return 47; // /
+      case KeyCode.APOSTROPHE:
+        return 96; // `
+      case KeyCode.OPEN_SQUARE_BRACKET:
+        return 91; // [
+      case KeyCode.BACKSLASH:
+        return 92; // \
+      case KeyCode.CLOSE_SQUARE_BRACKET:
+        return 93; // ]
+      case KeyCode.SINGLE_QUOTE:
+        return 39; // '
+    }
+    return event.keyCode;
+  }
+
+  /**
+   * Returns true if the key fires a keypress event in the current browser.
+   */
+  bool _firesKeyPressEvent(KeyEvent event) {
+    if (!Device.isIE && !Device.isWebKit) {
+      return true;
+    }
+
+    if (Device.userAgent.contains('Mac') && event.altKey) {
+      return KeyCode.isCharacterKey(event.keyCode);
+    }
+
+    // Alt but not AltGr which is represented as Alt+Ctrl.
+    if (event.altKey && !event.ctrlKey) {
+      return false;
+    }
+
+    // Saves Ctrl or Alt + key for IE and WebKit, which won't fire keypress.
+    if (!event.shiftKey &&
+        (_keyDownList.last.keyCode == KeyCode.CTRL ||
+            _keyDownList.last.keyCode == KeyCode.ALT ||
+            Device.userAgent.contains('Mac') &&
+                _keyDownList.last.keyCode == KeyCode.META)) {
+      return false;
+    }
+
+    // Some keys with Ctrl/Shift do not issue keypress in WebKit.
+    if (Device.isWebKit &&
+        event.ctrlKey &&
+        event.shiftKey &&
+        (event.keyCode == KeyCode.BACKSLASH ||
+            event.keyCode == KeyCode.OPEN_SQUARE_BRACKET ||
+            event.keyCode == KeyCode.CLOSE_SQUARE_BRACKET ||
+            event.keyCode == KeyCode.TILDE ||
+            event.keyCode == KeyCode.SEMICOLON ||
+            event.keyCode == KeyCode.DASH ||
+            event.keyCode == KeyCode.EQUALS ||
+            event.keyCode == KeyCode.COMMA ||
+            event.keyCode == KeyCode.PERIOD ||
+            event.keyCode == KeyCode.SLASH ||
+            event.keyCode == KeyCode.APOSTROPHE ||
+            event.keyCode == KeyCode.SINGLE_QUOTE)) {
+      return false;
+    }
+
+    switch (event.keyCode) {
+      case KeyCode.ENTER:
+        // IE9 does not fire keypress on ENTER.
+        return !Device.isIE;
+      case KeyCode.ESC:
+        return !Device.isWebKit;
+    }
+
+    return KeyCode.isCharacterKey(event.keyCode);
+  }
+
+  /**
+   * Normalize the keycodes to the IE KeyCodes (this is what Chrome, IE, and
+   * Opera all use).
+   */
+  int _normalizeKeyCodes(KeyboardEvent event) {
+    // Note: This may change once we get input about non-US keyboards.
+    if (Device.isFirefox) {
+      switch (event.keyCode) {
+        case KeyCode.FF_EQUALS:
+          return KeyCode.EQUALS;
+        case KeyCode.FF_SEMICOLON:
+          return KeyCode.SEMICOLON;
+        case KeyCode.MAC_FF_META:
+          return KeyCode.META;
+        case KeyCode.WIN_KEY_FF_LINUX:
+          return KeyCode.WIN_KEY;
+      }
+    }
+    return event.keyCode;
+  }
+
+  /** Handle keydown events. */
+  void processKeyDown(KeyboardEvent e) {
+    // Ctrl-Tab and Alt-Tab can cause the focus to be moved to another window
+    // before we've caught a key-up event.  If the last-key was one of these
+    // we reset the state.
+    if (_keyDownList.length > 0 &&
+        (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey ||
+            _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey ||
+            Device.userAgent.contains('Mac') &&
+                _keyDownList.last.keyCode == KeyCode.META &&
+                !e.metaKey)) {
+      _keyDownList.clear();
+    }
+
+    var event = new KeyEvent.wrap(e);
+    event._shadowKeyCode = _normalizeKeyCodes(event);
+    // Technically a "keydown" event doesn't have a charCode. This is
+    // calculated nonetheless to provide us with more information in giving
+    // as much information as possible on keypress about keycode and also
+    // charCode.
+    event._shadowCharCode = _findCharCodeKeyDown(event);
+    if (_keyDownList.length > 0 &&
+        event.keyCode != _keyDownList.last.keyCode &&
+        !_firesKeyPressEvent(event)) {
+      // Some browsers have quirks not firing keypress events where all other
+      // browsers do. This makes them more consistent.
+      processKeyPress(e);
+    }
+    _keyDownList.add(event);
+    _stream.add(event);
+  }
+
+  /** Handle keypress events. */
+  void processKeyPress(KeyboardEvent event) {
+    var e = new KeyEvent.wrap(event);
+    // IE reports the character code in the keyCode field for keypress events.
+    // There are two exceptions however, Enter and Escape.
+    if (Device.isIE) {
+      if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) {
+        e._shadowCharCode = 0;
+      } else {
+        e._shadowCharCode = e.keyCode;
+      }
+    } else if (Device.isOpera) {
+      // Opera reports the character code in the keyCode field.
+      e._shadowCharCode = KeyCode.isCharacterKey(e.keyCode) ? e.keyCode : 0;
+    }
+    // Now we guesstimate about what the keycode is that was actually
+    // pressed, given previous keydown information.
+    e._shadowKeyCode = _determineKeyCodeForKeypress(e);
+
+    // Correct the key value for certain browser-specific quirks.
+    if (e._shadowKeyIdentifier != null &&
+        _keyIdentifier.containsKey(e._shadowKeyIdentifier)) {
+      // This is needed for Safari Windows because it currently doesn't give a
+      // keyCode/which for non printable keys.
+      e._shadowKeyCode = _keyIdentifier[e._shadowKeyIdentifier];
+    }
+    e._shadowAltKey = _keyDownList.any((var element) => element.altKey);
+    _stream.add(e);
+  }
+
+  /** Handle keyup events. */
+  void processKeyUp(KeyboardEvent event) {
+    var e = new KeyEvent.wrap(event);
+    KeyboardEvent toRemove = null;
+    for (var key in _keyDownList) {
+      if (key.keyCode == e.keyCode) {
+        toRemove = key;
+      }
+    }
+    if (toRemove != null) {
+      _keyDownList.removeWhere((element) => element == toRemove);
+    } else if (_keyDownList.length > 0) {
+      // This happens when we've reached some international keyboard case we
+      // haven't accounted for or we haven't correctly eliminated all browser
+      // inconsistencies. Filing bugs on when this is reached is welcome!
+      _keyDownList.removeLast();
+    }
+    _stream.add(e);
+  }
+}
+
+/**
+ * Records KeyboardEvents that occur on a particular element, and provides a
+ * stream of outgoing KeyEvents with cross-browser consistent keyCode and
+ * charCode values despite the fact that a multitude of browsers that have
+ * varying keyboard default behavior.
+ *
+ * Example usage:
+ *
+ *     KeyboardEventStream.onKeyDown(document.body).listen(
+ *         keydownHandlerTest);
+ *
+ * This class is very much a work in progress, and we'd love to get information
+ * on how we can make this class work with as many international keyboards as
+ * possible. Bugs welcome!
+ */
+class KeyboardEventStream {
+  /** Named constructor to produce a stream for onKeyPress events. */
+  static CustomStream<KeyEvent> onKeyPress(EventTarget target) =>
+      new _KeyboardEventHandler('keypress').forTarget(target);
+
+  /** Named constructor to produce a stream for onKeyUp events. */
+  static CustomStream<KeyEvent> onKeyUp(EventTarget target) =>
+      new _KeyboardEventHandler('keyup').forTarget(target);
+
+  /** Named constructor to produce a stream for onKeyDown events. */
+  static CustomStream<KeyEvent> onKeyDown(EventTarget target) =>
+      new _KeyboardEventHandler('keydown').forTarget(target);
+}
+// 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.
+
+/**
+ * Class which helps construct standard node validation policies.
+ *
+ * By default this will not accept anything, but the 'allow*' functions can be
+ * used to expand what types of elements or attributes are allowed.
+ *
+ * All allow functions are additive- elements will be accepted if they are
+ * accepted by any specific rule.
+ *
+ * It is important to remember that sanitization is not just intended to prevent
+ * cross-site scripting attacks, but also to prevent information from being
+ * displayed in unexpected ways. For example something displaying basic
+ * formatted text may not expect `<video>` tags to appear. In this case an
+ * empty NodeValidatorBuilder with just [allowTextElements] might be
+ * appropriate.
+ */
+class NodeValidatorBuilder implements NodeValidator {
+  final List<NodeValidator> _validators = <NodeValidator>[];
+
+  NodeValidatorBuilder() {}
+
+  /**
+   * Creates a new NodeValidatorBuilder which accepts common constructs.
+   *
+   * By default this will accept HTML5 elements and attributes with the default
+   * [UriPolicy] and templating elements.
+   *
+   * Notable syntax which is filtered:
+   *
+   * * Only known-good HTML5 elements and attributes are allowed.
+   * * All URLs must be same-origin, use [allowNavigation] and [allowImages] to
+   * specify additional URI policies.
+   * * Inline-styles are not allowed.
+   * * Custom element tags are disallowed, use [allowCustomElement].
+   * * Custom tags extensions are disallowed, use [allowTagExtension].
+   * * SVG Elements are not allowed, use [allowSvg].
+   *
+   * For scenarios where the HTML should only contain formatted text
+   * [allowTextElements] is more appropriate.
+   *
+   * Use [allowSvg] to allow SVG elements.
+   */
+  NodeValidatorBuilder.common() {
+    allowHtml5();
+    allowTemplating();
+  }
+
+  /**
+   * Allows navigation elements- Form and Anchor tags, along with common
+   * attributes.
+   *
+   * The UriPolicy can be used to restrict the locations the navigation elements
+   * are allowed to direct to. By default this will use the default [UriPolicy].
+   */
+  void allowNavigation([UriPolicy uriPolicy]) {
+    if (uriPolicy == null) {
+      uriPolicy = new UriPolicy();
+    }
+    add(new _SimpleNodeValidator.allowNavigation(uriPolicy));
+  }
+
+  /**
+   * Allows image elements.
+   *
+   * The UriPolicy can be used to restrict the locations the images may be
+   * loaded from. By default this will use the default [UriPolicy].
+   */
+  void allowImages([UriPolicy uriPolicy]) {
+    if (uriPolicy == null) {
+      uriPolicy = new UriPolicy();
+    }
+    add(new _SimpleNodeValidator.allowImages(uriPolicy));
+  }
+
+  /**
+   * Allow basic text elements.
+   *
+   * This allows a subset of HTML5 elements, specifically just these tags and
+   * no attributes.
+   *
+   * * B
+   * * BLOCKQUOTE
+   * * BR
+   * * EM
+   * * H1
+   * * H2
+   * * H3
+   * * H4
+   * * H5
+   * * H6
+   * * HR
+   * * I
+   * * LI
+   * * OL
+   * * P
+   * * SPAN
+   * * UL
+   */
+  void allowTextElements() {
+    add(new _SimpleNodeValidator.allowTextElements());
+  }
+
+  /**
+   * Allow inline styles on elements.
+   *
+   * If [tagName] is not specified then this allows inline styles on all
+   * elements. Otherwise tagName limits the styles to the specified elements.
+   */
+  void allowInlineStyles({String tagName}) {
+    if (tagName == null) {
+      tagName = '*';
+    } else {
+      tagName = tagName.toUpperCase();
+    }
+    add(new _SimpleNodeValidator(null, allowedAttributes: ['$tagName::style']));
+  }
+
+  /**
+   * Allow common safe HTML5 elements and attributes.
+   *
+   * This list is based off of the Caja whitelists at:
+   * https://code.google.com/p/google-caja/wiki/CajaWhitelists.
+   *
+   * Common things which are not allowed are script elements, style attributes
+   * and any script handlers.
+   */
+  void allowHtml5({UriPolicy uriPolicy}) {
+    add(new _Html5NodeValidator(uriPolicy: uriPolicy));
+  }
+
+  /**
+   * Allow SVG elements and attributes except for known bad ones.
+   */
+  void allowSvg() {
+    add(new _SvgNodeValidator());
+  }
+
+  /**
+   * Allow custom elements with the specified tag name and specified attributes.
+   *
+   * This will allow the elements as custom tags (such as <x-foo></x-foo>),
+   * but will not allow tag extensions. Use [allowTagExtension] to allow
+   * tag extensions.
+   */
+  void allowCustomElement(String tagName,
+      {UriPolicy uriPolicy,
+      Iterable<String> attributes,
+      Iterable<String> uriAttributes}) {
+    var tagNameUpper = tagName.toUpperCase();
+    var attrs = attributes
+        ?.map<String>((name) => '$tagNameUpper::${name.toLowerCase()}');
+    var uriAttrs = uriAttributes
+        ?.map<String>((name) => '$tagNameUpper::${name.toLowerCase()}');
+    if (uriPolicy == null) {
+      uriPolicy = new UriPolicy();
+    }
+
+    add(new _CustomElementNodeValidator(
+        uriPolicy, [tagNameUpper], attrs, uriAttrs, false, true));
+  }
+
+  /**
+   * Allow custom tag extensions with the specified type name and specified
+   * attributes.
+   *
+   * This will allow tag extensions (such as <div is="x-foo"></div>),
+   * but will not allow custom tags. Use [allowCustomElement] to allow
+   * custom tags.
+   */
+  void allowTagExtension(String tagName, String baseName,
+      {UriPolicy uriPolicy,
+      Iterable<String> attributes,
+      Iterable<String> uriAttributes}) {
+    var baseNameUpper = baseName.toUpperCase();
+    var tagNameUpper = tagName.toUpperCase();
+    var attrs = attributes
+        ?.map<String>((name) => '$baseNameUpper::${name.toLowerCase()}');
+    var uriAttrs = uriAttributes
+        ?.map<String>((name) => '$baseNameUpper::${name.toLowerCase()}');
+    if (uriPolicy == null) {
+      uriPolicy = new UriPolicy();
+    }
+
+    add(new _CustomElementNodeValidator(uriPolicy,
+        [tagNameUpper, baseNameUpper], attrs, uriAttrs, true, false));
+  }
+
+  void allowElement(String tagName,
+      {UriPolicy uriPolicy,
+      Iterable<String> attributes,
+      Iterable<String> uriAttributes}) {
+    allowCustomElement(tagName,
+        uriPolicy: uriPolicy,
+        attributes: attributes,
+        uriAttributes: uriAttributes);
+  }
+
+  /**
+   * Allow templating elements (such as <template> and template-related
+   * attributes.
+   *
+   * This still requires other validators to allow regular attributes to be
+   * bound (such as [allowHtml5]).
+   */
+  void allowTemplating() {
+    add(new _TemplatingNodeValidator());
+  }
+
+  /**
+   * Add an additional validator to the current list of validators.
+   *
+   * Elements and attributes will be accepted if they are accepted by any
+   * validators.
+   */
+  void add(NodeValidator validator) {
+    _validators.add(validator);
+  }
+
+  bool allowsElement(Element element) {
+    return _validators.any((v) => v.allowsElement(element));
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    return _validators
+        .any((v) => v.allowsAttribute(element, attributeName, value));
+  }
+}
+
+class _SimpleNodeValidator implements NodeValidator {
+  final Set<String> allowedElements = new Set<String>();
+  final Set<String> allowedAttributes = new Set<String>();
+  final Set<String> allowedUriAttributes = new Set<String>();
+  final UriPolicy uriPolicy;
+
+  factory _SimpleNodeValidator.allowNavigation(UriPolicy uriPolicy) {
+    return new _SimpleNodeValidator(uriPolicy, allowedElements: const [
+      'A',
+      'FORM'
+    ], allowedAttributes: const [
+      'A::accesskey',
+      'A::coords',
+      'A::hreflang',
+      'A::name',
+      'A::shape',
+      'A::tabindex',
+      'A::target',
+      'A::type',
+      'FORM::accept',
+      'FORM::autocomplete',
+      'FORM::enctype',
+      'FORM::method',
+      'FORM::name',
+      'FORM::novalidate',
+      'FORM::target',
+    ], allowedUriAttributes: const [
+      'A::href',
+      'FORM::action',
+    ]);
+  }
+
+  factory _SimpleNodeValidator.allowImages(UriPolicy uriPolicy) {
+    return new _SimpleNodeValidator(uriPolicy, allowedElements: const [
+      'IMG'
+    ], allowedAttributes: const [
+      'IMG::align',
+      'IMG::alt',
+      'IMG::border',
+      'IMG::height',
+      'IMG::hspace',
+      'IMG::ismap',
+      'IMG::name',
+      'IMG::usemap',
+      'IMG::vspace',
+      'IMG::width',
+    ], allowedUriAttributes: const [
+      'IMG::src',
+    ]);
+  }
+
+  factory _SimpleNodeValidator.allowTextElements() {
+    return new _SimpleNodeValidator(null, allowedElements: const [
+      'B',
+      'BLOCKQUOTE',
+      'BR',
+      'EM',
+      'H1',
+      'H2',
+      'H3',
+      'H4',
+      'H5',
+      'H6',
+      'HR',
+      'I',
+      'LI',
+      'OL',
+      'P',
+      'SPAN',
+      'UL',
+    ]);
+  }
+
+  /**
+   * Elements must be uppercased tag names. For example `'IMG'`.
+   * Attributes must be uppercased tag name followed by :: followed by
+   * lowercase attribute name. For example `'IMG:src'`.
+   */
+  _SimpleNodeValidator(this.uriPolicy,
+      {Iterable<String> allowedElements,
+      Iterable<String> allowedAttributes,
+      Iterable<String> allowedUriAttributes}) {
+    this.allowedElements.addAll(allowedElements ?? const []);
+    allowedAttributes = allowedAttributes ?? const [];
+    allowedUriAttributes = allowedUriAttributes ?? const [];
+    var legalAttributes = allowedAttributes
+        .where((x) => !_Html5NodeValidator._uriAttributes.contains(x));
+    var extraUriAttributes = allowedAttributes
+        .where((x) => _Html5NodeValidator._uriAttributes.contains(x));
+    this.allowedAttributes.addAll(legalAttributes);
+    this.allowedUriAttributes.addAll(allowedUriAttributes);
+    this.allowedUriAttributes.addAll(extraUriAttributes);
+  }
+
+  bool allowsElement(Element element) {
+    return allowedElements.contains(Element._safeTagName(element));
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    var tagName = Element._safeTagName(element);
+    if (allowedUriAttributes.contains('$tagName::$attributeName')) {
+      return uriPolicy.allowsUri(value);
+    } else if (allowedUriAttributes.contains('*::$attributeName')) {
+      return uriPolicy.allowsUri(value);
+    } else if (allowedAttributes.contains('$tagName::$attributeName')) {
+      return true;
+    } else if (allowedAttributes.contains('*::$attributeName')) {
+      return true;
+    } else if (allowedAttributes.contains('$tagName::*')) {
+      return true;
+    } else if (allowedAttributes.contains('*::*')) {
+      return true;
+    }
+    return false;
+  }
+}
+
+class _CustomElementNodeValidator extends _SimpleNodeValidator {
+  final bool allowTypeExtension;
+  final bool allowCustomTag;
+
+  _CustomElementNodeValidator(
+      UriPolicy uriPolicy,
+      Iterable<String> allowedElements,
+      Iterable<String> allowedAttributes,
+      Iterable<String> allowedUriAttributes,
+      bool allowTypeExtension,
+      bool allowCustomTag)
+      : this.allowTypeExtension = allowTypeExtension == true,
+        this.allowCustomTag = allowCustomTag == true,
+        super(uriPolicy,
+            allowedElements: allowedElements,
+            allowedAttributes: allowedAttributes,
+            allowedUriAttributes: allowedUriAttributes);
+
+  bool allowsElement(Element element) {
+    if (allowTypeExtension) {
+      var isAttr = element.attributes['is'];
+      if (isAttr != null) {
+        return allowedElements.contains(isAttr.toUpperCase()) &&
+            allowedElements.contains(Element._safeTagName(element));
+      }
+    }
+    return allowCustomTag &&
+        allowedElements.contains(Element._safeTagName(element));
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    if (allowsElement(element)) {
+      if (allowTypeExtension &&
+          attributeName == 'is' &&
+          allowedElements.contains(value.toUpperCase())) {
+        return true;
+      }
+      return super.allowsAttribute(element, attributeName, value);
+    }
+    return false;
+  }
+}
+
+class _TemplatingNodeValidator extends _SimpleNodeValidator {
+  static const _TEMPLATE_ATTRS = const <String>[
+    'bind',
+    'if',
+    'ref',
+    'repeat',
+    'syntax'
+  ];
+
+  final Set<String> _templateAttrs;
+
+  _TemplatingNodeValidator()
+      : _templateAttrs = new Set<String>.from(_TEMPLATE_ATTRS),
+        super(null,
+            allowedElements: ['TEMPLATE'],
+            allowedAttributes:
+                _TEMPLATE_ATTRS.map((attr) => 'TEMPLATE::$attr')) {}
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    if (super.allowsAttribute(element, attributeName, value)) {
+      return true;
+    }
+
+    if (attributeName == 'template' && value == "") {
+      return true;
+    }
+
+    if (element.attributes['template'] == "") {
+      return _templateAttrs.contains(attributeName);
+    }
+    return false;
+  }
+}
+
+class _SvgNodeValidator implements NodeValidator {
+  bool allowsElement(Element element) {
+    if (element is svg.ScriptElement) {
+      return false;
+    }
+    // Firefox 37 has issues with creating foreign elements inside a
+    // foreignobject tag as SvgElement. We don't want foreignobject contents
+    // anyway, so just remove the whole tree outright. And we can't rely
+    // on IE recognizing the SvgForeignObject type, so go by tagName. Bug 23144
+    if (element is svg.SvgElement &&
+        Element._safeTagName(element) == 'foreignObject') {
+      return false;
+    }
+    if (element is svg.SvgElement) {
+      return true;
+    }
+    return false;
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    if (attributeName == 'is' || attributeName.startsWith('on')) {
+      return false;
+    }
+    return allowsElement(element);
+  }
+}
+// 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.
+
+/**
+ * Contains the set of standard values returned by HTMLDocument.getReadyState.
+ */
+abstract class ReadyState {
+  /**
+   * Indicates the document is still loading and parsing.
+   */
+  static const String LOADING = "loading";
+
+  /**
+   * Indicates the document is finished parsing but is still loading
+   * subresources.
+   */
+  static const String INTERACTIVE = "interactive";
+
+  /**
+   * Indicates the document and all subresources have been loaded.
+   */
+  static const String COMPLETE = "complete";
+}
+// 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 list which just wraps another list, for either intercepting list calls or
+ * retyping the list (for example, from List<A> to List<B> where B extends A).
+ */
+class _WrappedList<E extends Node> extends ListBase<E>
+    implements NodeListWrapper {
+  final List<Node> _list;
+
+  _WrappedList(this._list);
+
+  // Iterable APIs
+
+  Iterator<E> get iterator => new _WrappedIterator<E>(_list.iterator);
+
+  int get length => _list.length;
+
+  // Collection APIs
+
+  void add(E element) {
+    _list.add(element);
+  }
+
+  bool remove(Object element) => _list.remove(element);
+
+  void clear() {
+    _list.clear();
+  }
+
+  // List APIs
+
+  E operator [](int index) => _list[index];
+
+  void operator []=(int index, E value) {
+    _list[index] = value;
+  }
+
+  set length(int newLength) {
+    _list.length = newLength;
+  }
+
+  void sort([int compare(E a, E b)]) {
+    // Implicit downcast on argument from Node to E-extends-Node.
+    _list.sort((Node a, Node b) => compare(a, b));
+  }
+
+  int indexOf(Object element, [int start = 0]) => _list.indexOf(element, start);
+
+  int lastIndexOf(Object element, [int start]) =>
+      _list.lastIndexOf(element, start);
+
+  void insert(int index, E element) => _list.insert(index, element);
+
+  E removeAt(int index) => _list.removeAt(index);
+
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+    _list.setRange(start, end, iterable, skipCount);
+  }
+
+  void removeRange(int start, int end) {
+    _list.removeRange(start, end);
+  }
+
+  void replaceRange(int start, int end, Iterable<E> iterable) {
+    _list.replaceRange(start, end, iterable);
+  }
+
+  void fillRange(int start, int end, [E fillValue]) {
+    _list.fillRange(start, end, fillValue);
+  }
+
+  List<Node> get rawList => _list;
+}
+
+/**
+ * Iterator wrapper for _WrappedList.
+ */
+class _WrappedIterator<E extends Node> implements Iterator<E> {
+  Iterator<Node> _iterator;
+
+  _WrappedIterator(this._iterator);
+
+  bool moveNext() {
+    return _iterator.moveNext();
+  }
+
+  E get current => _iterator.current;
+}
+// Copyright (c) 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.
+
+class _HttpRequestUtils {
+  // Helper for factory HttpRequest.get
+  static HttpRequest get(
+      String url, onComplete(HttpRequest request), bool withCredentials) {
+    final request = new HttpRequest();
+    request.open('GET', url, async: true);
+
+    request.withCredentials = withCredentials;
+
+    request.onReadyStateChange.listen((e) {
+      if (request.readyState == HttpRequest.DONE) {
+        onComplete(request);
+      }
+    });
+
+    request.send();
+
+    return request;
+  }
+}
+// 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.
+
+// Iterator for arrays with fixed size.
+class FixedSizeListIterator<T> implements Iterator<T> {
+  final List<T> _array;
+  final int _length; // Cache array length for faster access.
+  int _position;
+  T _current;
+
+  FixedSizeListIterator(List<T> array)
+      : _array = array,
+        _position = -1,
+        _length = array.length;
+
+  bool moveNext() {
+    int nextPosition = _position + 1;
+    if (nextPosition < _length) {
+      _current = _array[nextPosition];
+      _position = nextPosition;
+      return true;
+    }
+    _current = null;
+    _position = _length;
+    return false;
+  }
+
+  T get current => _current;
+}
+
+// Iterator for arrays with variable size.
+class _VariableSizeListIterator<T> implements Iterator<T> {
+  final List<T> _array;
+  int _position;
+  T _current;
+
+  _VariableSizeListIterator(List<T> array)
+      : _array = array,
+        _position = -1;
+
+  bool moveNext() {
+    int nextPosition = _position + 1;
+    if (nextPosition < _array.length) {
+      _current = _array[nextPosition];
+      _position = nextPosition;
+      return true;
+    }
+    _current = null;
+    _position = _array.length;
+    return false;
+  }
+
+  T get current => _current;
+}
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Console {
+  const Console._safe();
+  static const Console _safeConsole = const Console._safe();
+
+  bool get _isConsoleDefined => JS('bool', 'typeof console != "undefined"');
+
+  MemoryInfo get memory =>
+      _isConsoleDefined ? JS('MemoryInfo', 'window.console.memory') : null;
+
+  void assertCondition(bool condition, Object arg) => _isConsoleDefined
+      ? JS('void', 'window.console.assertCondition(#, #)', condition, arg)
+      : null;
+
+  void clear(Object arg) =>
+      _isConsoleDefined ? JS('void', 'window.console.clear(#)', arg) : null;
+
+  void count(Object arg) =>
+      _isConsoleDefined ? JS('void', 'window.console.count(#)', arg) : null;
+
+  void debug(Object arg) =>
+      _isConsoleDefined ? JS('void', 'window.console.debug(#)', arg) : null;
+
+  void dir(Object arg) =>
+      _isConsoleDefined ? JS('void', 'window.console.dir(#)', arg) : null;
+
+  void dirxml(Object arg) =>
+      _isConsoleDefined ? JS('void', 'window.console.dirxml(#)', arg) : null;
+
+  void error(Object arg) =>
+      _isConsoleDefined ? JS('void', 'window.console.error(#)', arg) : null;
+
+  void group(Object arg) =>
+      _isConsoleDefined ? JS('void', 'window.console.group(#)', arg) : null;
+
+  void groupCollapsed(Object arg) => _isConsoleDefined
+      ? JS('void', 'window.console.groupCollapsed(#)', arg)
+      : null;
+
+  void groupEnd() =>
+      _isConsoleDefined ? JS('void', 'window.console.groupEnd()') : null;
+
+  void info(Object arg) =>
+      _isConsoleDefined ? JS('void', 'window.console.info(#)', arg) : null;
+
+  void log(Object arg) =>
+      _isConsoleDefined ? JS('void', 'window.console.log(#)', arg) : null;
+
+  void markTimeline(Object arg) => _isConsoleDefined
+      ? JS('void', 'window.console.markTimeline(#)', arg)
+      : null;
+
+  void profile(String title) =>
+      _isConsoleDefined ? JS('void', 'window.console.profile(#)', title) : null;
+
+  void profileEnd(String title) => _isConsoleDefined
+      ? JS('void', 'window.console.profileEnd(#)', title)
+      : null;
+
+  void table(Object arg) =>
+      _isConsoleDefined ? JS('void', 'window.console.table(#)', arg) : null;
+
+  void time(String title) =>
+      _isConsoleDefined ? JS('void', 'window.console.time(#)', title) : null;
+
+  void timeEnd(String title) =>
+      _isConsoleDefined ? JS('void', 'window.console.timeEnd(#)', title) : null;
+
+  void timeStamp(Object arg) =>
+      _isConsoleDefined ? JS('void', 'window.console.timeStamp(#)', arg) : null;
+
+  void trace(Object arg) =>
+      _isConsoleDefined ? JS('void', 'window.console.trace(#)', arg) : null;
+
+  void warn(Object arg) =>
+      _isConsoleDefined ? JS('void', 'window.console.warn(#)', arg) : null;
+}
+// Copyright (c) 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.
+
+// Conversions for Window.  These check if the window is the local
+// window, and if it's not, wraps or unwraps it with a secure wrapper.
+// We need to test for EventTarget here as well as it's a base type.
+// We omit an unwrapper for Window as no methods take a non-local
+// window as a parameter.
+
+WindowBase _convertNativeToDart_Window(win) {
+  if (win == null) return null;
+  return _DOMWindowCrossFrame._createSafe(win);
+}
+
+EventTarget _convertNativeToDart_EventTarget(e) {
+  if (e == null) {
+    return null;
+  }
+  // Assume it's a Window if it contains the postMessage property.  It may be
+  // from a different frame - without a patched prototype - so we cannot
+  // rely on Dart type checking.
+  if (JS('bool', r'"postMessage" in #', e)) {
+    var window = _DOMWindowCrossFrame._createSafe(e);
+    // If it's a native window.
+    if (window is EventTarget) {
+      return window;
+    }
+    return null;
+  } else
+    return e;
+}
+
+EventTarget _convertDartToNative_EventTarget(e) {
+  if (e is _DOMWindowCrossFrame) {
+    return e._window;
+  } else {
+    return e;
+  }
+}
+
+_convertNativeToDart_XHR_Response(o) {
+  if (o is Document) {
+    return o;
+  }
+  return convertNativeToDart_SerializedScriptValue(o);
+}
+// 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.
+
+_callConstructor(constructor, interceptor) {
+  return (receiver) {
+    setNativeSubclassDispatchRecord(receiver, interceptor);
+
+    // Mirrors uses the constructor property to cache lookups, so we need it to
+    // be set correctly, including on IE where it is not automatically picked
+    // up from the __proto__.
+    JS('', '#.constructor = #.__proto__.constructor', receiver, receiver);
+    return JS('', '#(#)', constructor, receiver);
+  };
+}
+
+_callAttached(receiver) {
+  return receiver.attached();
+}
+
+_callDetached(receiver) {
+  return receiver.detached();
+}
+
+_callAttributeChanged(receiver, name, oldValue, newValue) {
+  return receiver.attributeChanged(name, oldValue, newValue);
+}
+
+_makeCallbackMethod(callback) {
+  return JS(
+      '',
+      '''((function(invokeCallback) {
+             return function() {
+               return invokeCallback(this);
+             };
+          })(#))''',
+      convertDartClosureToJS(callback, 1));
+}
+
+_makeCallbackMethod3(callback) {
+  return JS(
+      '',
+      '''((function(invokeCallback) {
+             return function(arg1, arg2, arg3) {
+               return invokeCallback(this, arg1, arg2, arg3);
+             };
+          })(#))''',
+      convertDartClosureToJS(callback, 4));
+}
+
+/// Checks whether the given [element] correctly extends from the native class
+/// with the given [baseClassName]. This method will throw if the base class
+/// doesn't match, except when the element extends from `template` and it's base
+/// class is `HTMLUnknownElement`. This exclusion is needed to support extension
+/// of template elements (used heavily in Polymer 1.0) on IE11 when using the
+/// webcomponents-lite.js polyfill.
+void _checkExtendsNativeClassOrTemplate(
+    Element element, String extendsTag, String baseClassName) {
+  if (!JS('bool', '(# instanceof window[#])', element, baseClassName) &&
+      !((extendsTag == 'template' &&
+          JS('bool', '(# instanceof window["HTMLUnknownElement"])',
+              element)))) {
+    throw new UnsupportedError('extendsTag does not match base native class');
+  }
+}
+
+Function _registerCustomElement(context, document, String tag, [Map options]) {
+  // Function follows the same pattern as the following JavaScript code for
+  // registering a custom element.
+  //
+  //    var proto = Object.create(HTMLElement.prototype, {
+  //        createdCallback: {
+  //          value: function() {
+  //            window.console.log('here');
+  //          }
+  //        }
+  //    });
+  //    document.registerElement('x-foo', { prototype: proto });
+  //    ...
+  //    var e = document.createElement('x-foo');
+
+  var extendsTagName = '';
+  Type type;
+  if (options != null) {
+    extendsTagName = options['extends'];
+    type = options['prototype'];
+  }
+
+  var interceptorClass = findInterceptorConstructorForType(type);
+  if (interceptorClass == null) {
+    throw new ArgumentError(type);
+  }
+
+  var interceptor = JS('=Object', '#.prototype', interceptorClass);
+
+  var constructor = findConstructorForNativeSubclassType(type, 'created');
+  if (constructor == null) {
+    throw new ArgumentError("$type has no constructor called 'created'");
+  }
+
+  // Workaround for 13190- use an article element to ensure that HTMLElement's
+  // interceptor is resolved correctly.
+  getNativeInterceptor(new Element.tag('article'));
+
+  String baseClassName = findDispatchTagForInterceptorClass(interceptorClass);
+  if (baseClassName == null) {
+    throw new ArgumentError(type);
+  }
+
+  if (extendsTagName == null) {
+    if (baseClassName != 'HTMLElement') {
+      throw new UnsupportedError('Class must provide extendsTag if base '
+          'native class is not HtmlElement');
+    }
+  } else {
+    var element = document.createElement(extendsTagName);
+    _checkExtendsNativeClassOrTemplate(element, extendsTagName, baseClassName);
+  }
+
+  var baseConstructor = JS('=Object', '#[#]', context, baseClassName);
+
+  var properties = JS('=Object', '{}');
+
+  JS(
+      'void',
+      '#.createdCallback = #',
+      properties,
+      JS('=Object', '{value: #}',
+          _makeCallbackMethod(_callConstructor(constructor, interceptor))));
+  JS('void', '#.attachedCallback = #', properties,
+      JS('=Object', '{value: #}', _makeCallbackMethod(_callAttached)));
+  JS('void', '#.detachedCallback = #', properties,
+      JS('=Object', '{value: #}', _makeCallbackMethod(_callDetached)));
+  JS('void', '#.attributeChangedCallback = #', properties,
+      JS('=Object', '{value: #}', _makeCallbackMethod3(_callAttributeChanged)));
+
+  var baseProto = JS('=Object', '#.prototype', baseConstructor);
+  var proto = JS('=Object', 'Object.create(#, #)', baseProto, properties);
+
+  setNativeSubclassDispatchRecord(proto, interceptor);
+
+  var opts = JS('=Object', '{prototype: #}', proto);
+
+  if (extendsTagName != null) {
+    JS('=Object', '#.extends = #', opts, extendsTagName);
+  }
+
+  return JS(
+      'JavaScriptFunction', '#.registerElement(#, #)', document, tag, opts);
+}
+
+//// Called by Element.created to do validation & initialization.
+void _initializeCustomElement(Element e) {
+  // TODO(blois): Add validation that this is only in response to an upgrade.
+}
+
+/// Dart2JS implementation of ElementUpgrader
+class _JSElementUpgrader implements ElementUpgrader {
+  var _interceptor;
+  var _constructor;
+  var _nativeType;
+
+  _JSElementUpgrader(Document document, Type type, String extendsTag) {
+    var interceptorClass = findInterceptorConstructorForType(type);
+    if (interceptorClass == null) {
+      throw new ArgumentError(type);
+    }
+
+    _constructor = findConstructorForNativeSubclassType(type, 'created');
+    if (_constructor == null) {
+      throw new ArgumentError("$type has no constructor called 'created'");
+    }
+
+    // Workaround for 13190- use an article element to ensure that HTMLElement's
+    // interceptor is resolved correctly.
+    getNativeInterceptor(new Element.tag('article'));
+
+    var baseClassName = findDispatchTagForInterceptorClass(interceptorClass);
+    if (baseClassName == null) {
+      throw new ArgumentError(type);
+    }
+
+    if (extendsTag == null) {
+      if (baseClassName != 'HTMLElement') {
+        throw new UnsupportedError('Class must provide extendsTag if base '
+            'native class is not HtmlElement');
+      }
+      _nativeType = HtmlElement;
+    } else {
+      var element = document.createElement(extendsTag);
+      _checkExtendsNativeClassOrTemplate(element, extendsTag, baseClassName);
+      _nativeType = element.runtimeType;
+    }
+
+    _interceptor = JS('=Object', '#.prototype', interceptorClass);
+  }
+
+  Element upgrade(Element element) {
+    // Only exact type matches are supported- cannot be a subclass.
+    if (element.runtimeType != _nativeType) {
+      // Some browsers may represent non-upgraded elements <x-foo> as
+      // UnknownElement and not a plain HtmlElement.
+      if (_nativeType != HtmlElement || element.runtimeType != UnknownElement) {
+        throw new ArgumentError('element is not subclass of $_nativeType');
+      }
+    }
+
+    setNativeSubclassDispatchRecord(element, _interceptor);
+    JS('', '#(#)', _constructor, element);
+    return element;
+  }
+}
+// Copyright (c) 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.
+
+// TODO(vsm): Unify with Dartium version.
+class _DOMWindowCrossFrame implements WindowBase {
+  // Private window.  Note, this is a window in another frame, so it
+  // cannot be typed as "Window" as its prototype is not patched
+  // properly.  Its fields and methods can only be accessed via JavaScript.
+  final _window;
+
+  // Fields.
+  HistoryBase get history =>
+      _HistoryCrossFrame._createSafe(JS('HistoryBase', '#.history', _window));
+  LocationBase get location => _LocationCrossFrame._createSafe(
+      JS('LocationBase', '#.location', _window));
+
+  // TODO(vsm): Add frames to navigate subframes.  See 2312.
+
+  bool get closed => JS('bool', '#.closed', _window);
+
+  WindowBase get opener => _createSafe(JS('WindowBase', '#.opener', _window));
+
+  WindowBase get parent => _createSafe(JS('WindowBase', '#.parent', _window));
+
+  WindowBase get top => _createSafe(JS('WindowBase', '#.top', _window));
+
+  // Methods.
+  void close() => JS('void', '#.close()', _window);
+
+  void postMessage(var message, String targetOrigin,
+      [List messagePorts = null]) {
+    if (messagePorts == null) {
+      JS('void', '#.postMessage(#,#)', _window,
+          convertDartToNative_SerializedScriptValue(message), targetOrigin);
+    } else {
+      JS(
+          'void',
+          '#.postMessage(#,#,#)',
+          _window,
+          convertDartToNative_SerializedScriptValue(message),
+          targetOrigin,
+          messagePorts);
+    }
+  }
+
+  // Implementation support.
+  _DOMWindowCrossFrame(this._window);
+
+  static WindowBase _createSafe(w) {
+    if (identical(w, window)) {
+      return w;
+    } else {
+      // TODO(vsm): Cache or implement equality.
+      registerGlobalObject(w);
+      return new _DOMWindowCrossFrame(w);
+    }
+  }
+
+  // TODO(efortuna): Remove this method. dartbug.com/16814
+  Events get on => throw new UnsupportedError(
+      'You can only attach EventListeners to your own window.');
+  // TODO(efortuna): Remove this method. dartbug.com/16814
+  void _addEventListener(String type, EventListener listener,
+          [bool useCapture]) =>
+      throw new UnsupportedError(
+          'You can only attach EventListeners to your own window.');
+  // TODO(efortuna): Remove this method. dartbug.com/16814
+  void addEventListener(String type, EventListener listener,
+          [bool useCapture]) =>
+      throw new UnsupportedError(
+          'You can only attach EventListeners to your own window.');
+  // TODO(efortuna): Remove this method. dartbug.com/16814
+  bool dispatchEvent(Event event) => throw new UnsupportedError(
+      'You can only attach EventListeners to your own window.');
+  // TODO(efortuna): Remove this method. dartbug.com/16814
+  void _removeEventListener(String type, EventListener listener,
+          [bool useCapture]) =>
+      throw new UnsupportedError(
+          'You can only attach EventListeners to your own window.');
+  // TODO(efortuna): Remove this method. dartbug.com/16814
+  void removeEventListener(String type, EventListener listener,
+          [bool useCapture]) =>
+      throw new UnsupportedError(
+          'You can only attach EventListeners to your own window.');
+}
+
+class _LocationCrossFrame implements LocationBase {
+  // Private location.  Note, this is a location object in another frame, so it
+  // cannot be typed as "Location" as its prototype is not patched
+  // properly.  Its fields and methods can only be accessed via JavaScript.
+  var _location;
+
+  set href(String val) => _setHref(_location, val);
+  static void _setHref(location, val) {
+    JS('void', '#.href = #', location, val);
+  }
+
+  // Implementation support.
+  _LocationCrossFrame(this._location);
+
+  static LocationBase _createSafe(location) {
+    if (identical(location, window.location)) {
+      return location;
+    } else {
+      // TODO(vsm): Cache or implement equality.
+      return new _LocationCrossFrame(location);
+    }
+  }
+}
+
+class _HistoryCrossFrame implements HistoryBase {
+  // Private history.  Note, this is a history object in another frame, so it
+  // cannot be typed as "History" as its prototype is not patched
+  // properly.  Its fields and methods can only be accessed via JavaScript.
+  var _history;
+
+  void back() => JS('void', '#.back()', _history);
+
+  void forward() => JS('void', '#.forward()', _history);
+
+  void go(int distance) => JS('void', '#.go(#)', _history, distance);
+
+  // Implementation support.
+  _HistoryCrossFrame(this._history);
+
+  static HistoryBase _createSafe(h) {
+    if (identical(h, window.history)) {
+      return h;
+    } else {
+      // TODO(vsm): Cache or implement equality.
+      return new _HistoryCrossFrame(h);
+    }
+  }
+}
+
+/**
+ * A custom KeyboardEvent that attempts to eliminate cross-browser
+ * inconsistencies, and also provide both keyCode and charCode information
+ * for all key events (when such information can be determined).
+ *
+ * KeyEvent tries to provide a higher level, more polished keyboard event
+ * information on top of the "raw" [KeyboardEvent].
+ *
+ * The mechanics of using KeyEvents is a little different from the underlying
+ * [KeyboardEvent]. To use KeyEvents, you need to create a stream and then add
+ * KeyEvents to the stream, rather than using the [EventTarget.dispatchEvent].
+ * Here's an example usage:
+ *
+ *     // Initialize a stream for the KeyEvents:
+ *     var stream = KeyEvent.keyPressEvent.forTarget(document.body);
+ *     // Start listening to the stream of KeyEvents.
+ *     stream.listen((keyEvent) =>
+ *         window.console.log('KeyPress event detected ${keyEvent.charCode}'));
+ *     ...
+ *     // Add a new KeyEvent of someone pressing the 'A' key to the stream so
+ *     // listeners can know a KeyEvent happened.
+ *     stream.add(new KeyEvent('keypress', keyCode: 65, charCode: 97));
+ *
+ * This class is very much a work in progress, and we'd love to get information
+ * on how we can make this class work with as many international keyboards as
+ * possible. Bugs welcome!
+ */
+class KeyEvent extends _WrappedEvent implements KeyboardEvent {
+  /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */
+  KeyboardEvent _parent;
+
+  /** The "fixed" value of whether the alt key is being pressed. */
+  bool _shadowAltKey;
+
+  /** Calculated value of what the estimated charCode is for this event. */
+  int _shadowCharCode;
+
+  /** Calculated value of what the estimated keyCode is for this event. */
+  int _shadowKeyCode;
+
+  /** Calculated value of what the estimated keyCode is for this event. */
+  int get keyCode => _shadowKeyCode;
+
+  /** Calculated value of what the estimated charCode is for this event. */
+  int get charCode => this.type == 'keypress' ? _shadowCharCode : 0;
+
+  /** Calculated value of whether the alt key is pressed is for this event. */
+  bool get altKey => _shadowAltKey;
+
+  /** Calculated value of what the estimated keyCode is for this event. */
+  int get which => keyCode;
+
+  /** Accessor to the underlying keyCode value is the parent event. */
+  int get _realKeyCode => JS('int', '#.keyCode', _parent);
+
+  /** Accessor to the underlying charCode value is the parent event. */
+  int get _realCharCode => JS('int', '#.charCode', _parent);
+
+  /** Accessor to the underlying altKey value is the parent event. */
+  bool get _realAltKey => JS('bool', '#.altKey', _parent);
+
+  /** Shadows on top of the parent's currentTarget. */
+  EventTarget _currentTarget;
+
+  final InputDeviceCapabilities sourceCapabilities;
+
+  /**
+   * The value we want to use for this object's dispatch. Created here so it is
+   * only invoked once.
+   */
+  static final _keyboardEventDispatchRecord = _makeRecord();
+
+  /** Helper to statically create the dispatch record. */
+  static _makeRecord() {
+    var interceptor = JS_INTERCEPTOR_CONSTANT(KeyboardEvent);
+    return makeLeafDispatchRecord(interceptor);
+  }
+
+  /** Construct a KeyEvent with [parent] as the event we're emulating. */
+  KeyEvent.wrap(KeyboardEvent parent) : super(parent) {
+    _parent = parent;
+    _shadowAltKey = _realAltKey;
+    _shadowCharCode = _realCharCode;
+    _shadowKeyCode = _realKeyCode;
+    _currentTarget = _parent.currentTarget;
+  }
+
+  /** Programmatically create a new KeyEvent (and KeyboardEvent). */
+  factory KeyEvent(String type,
+      {Window view,
+      bool canBubble: true,
+      bool cancelable: true,
+      int keyCode: 0,
+      int charCode: 0,
+      int location: 1,
+      bool ctrlKey: false,
+      bool altKey: false,
+      bool shiftKey: false,
+      bool metaKey: false,
+      EventTarget currentTarget}) {
+    if (view == null) {
+      view = window;
+    }
+
+    var eventObj;
+
+    // Currently this works on everything but Safari. Safari throws an
+    // "Attempting to change access mechanism for an unconfigurable property"
+    // TypeError when trying to do the Object.defineProperty hack, so we avoid
+    // this branch if possible.
+    // Also, if we want this branch to work in FF, we also need to modify
+    // _initKeyboardEvent to also take charCode and keyCode values to
+    // initialize initKeyEvent.
+
+    eventObj = new Event.eventType('KeyboardEvent', type,
+        canBubble: canBubble, cancelable: cancelable);
+
+    // Chromium Hack
+    JS(
+        'void',
+        "Object.defineProperty(#, 'keyCode', {"
+            "  get : function() { return this.keyCodeVal; } })",
+        eventObj);
+    JS(
+        'void',
+        "Object.defineProperty(#, 'which', {"
+            "  get : function() { return this.keyCodeVal; } })",
+        eventObj);
+    JS(
+        'void',
+        "Object.defineProperty(#, 'charCode', {"
+            "  get : function() { return this.charCodeVal; } })",
+        eventObj);
+
+    var keyIdentifier = _convertToHexString(charCode, keyCode);
+    eventObj._initKeyboardEvent(type, canBubble, cancelable, view,
+        keyIdentifier, location, ctrlKey, altKey, shiftKey, metaKey);
+    JS('void', '#.keyCodeVal = #', eventObj, keyCode);
+    JS('void', '#.charCodeVal = #', eventObj, charCode);
+
+    // Tell dart2js that it smells like a KeyboardEvent!
+    setDispatchProperty(eventObj, _keyboardEventDispatchRecord);
+
+    var keyEvent = new KeyEvent.wrap(eventObj);
+    if (keyEvent._currentTarget == null) {
+      keyEvent._currentTarget = currentTarget == null ? window : currentTarget;
+    }
+    return keyEvent;
+  }
+
+  // Currently known to work on all browsers but IE.
+  static bool get canUseDispatchEvent => JS(
+      'bool',
+      '(typeof document.body.dispatchEvent == "function")'
+          '&& document.body.dispatchEvent.length > 0');
+
+  /** The currently registered target for this event. */
+  EventTarget get currentTarget => _currentTarget;
+
+  // This is an experimental method to be sure.
+  static String _convertToHexString(int charCode, int keyCode) {
+    if (charCode != -1) {
+      var hex = charCode.toRadixString(16); // Convert to hexadecimal.
+      StringBuffer sb = new StringBuffer('U+');
+      for (int i = 0; i < 4 - hex.length; i++) sb.write('0');
+      sb.write(hex);
+      return sb.toString();
+    } else {
+      return KeyCode._convertKeyCodeToKeyName(keyCode);
+    }
+  }
+
+  // TODO(efortuna): If KeyEvent is sufficiently successful that we want to make
+  // it the default keyboard event handling, move these methods over to Element.
+  /** Accessor to provide a stream of KeyEvents on the desired target. */
+  static EventStreamProvider<KeyEvent> keyDownEvent =
+      new _KeyboardEventHandler('keydown');
+  /** Accessor to provide a stream of KeyEvents on the desired target. */
+  static EventStreamProvider<KeyEvent> keyUpEvent =
+      new _KeyboardEventHandler('keyup');
+  /** Accessor to provide a stream of KeyEvents on the desired target. */
+  static EventStreamProvider<KeyEvent> keyPressEvent =
+      new _KeyboardEventHandler('keypress');
+
+  String get code => _parent.code;
+  /** True if the ctrl key is pressed during this event. */
+  bool get ctrlKey => _parent.ctrlKey;
+  int get detail => _parent.detail;
+  bool get isComposing => _parent.isComposing;
+  String get key => _parent.key;
+  /**
+   * Accessor to the part of the keyboard that the key was pressed from (one of
+   * KeyLocation.STANDARD, KeyLocation.RIGHT, KeyLocation.LEFT,
+   * KeyLocation.NUMPAD, KeyLocation.MOBILE, KeyLocation.JOYSTICK).
+   */
+  int get location => _parent.location;
+  /** True if the Meta (or Mac command) key is pressed during this event. */
+  bool get metaKey => _parent.metaKey;
+  /** True if the shift key was pressed during this event. */
+  bool get shiftKey => _parent.shiftKey;
+  Window get view => _parent.view;
+  void _initUIEvent(
+      String type, bool canBubble, bool cancelable, Window view, int detail) {
+    throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
+  }
+
+  String get _shadowKeyIdentifier => JS('String', '#.keyIdentifier', _parent);
+
+  int get _charCode => charCode;
+  int get _keyCode => keyCode;
+  int get _which => which;
+
+  String get _keyIdentifier {
+    throw new UnsupportedError("keyIdentifier is unsupported.");
+  }
+
+  void _initKeyboardEvent(
+      String type,
+      bool canBubble,
+      bool cancelable,
+      Window view,
+      String keyIdentifier,
+      int location,
+      bool ctrlKey,
+      bool altKey,
+      bool shiftKey,
+      bool metaKey) {
+    throw new UnsupportedError(
+        "Cannot initialize a KeyboardEvent from a KeyEvent.");
+  }
+
+  bool getModifierState(String keyArgument) => throw new UnimplementedError();
+
+  bool get repeat => throw new UnimplementedError();
+  bool get isComposed => throw new UnimplementedError();
+  dynamic get _get_view => throw new UnimplementedError();
+}
+// 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.
+
+class Platform {
+  /**
+   * Returns true if dart:typed_data types are supported on this
+   * browser.  If false, using these types will generate a runtime
+   * error.
+   */
+  static final supportsTypedData = JS('bool', '!!(window.ArrayBuffer)');
+
+  /**
+   * Returns true if SIMD types in dart:typed_data types are supported
+   * on this browser.  If false, using these types will generate a runtime
+   * error.
+   */
+  static final supportsSimd = false;
+}
+// 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.
+
+/**
+ * Helper class to implement custom events which wrap DOM events.
+ */
+class _WrappedEvent implements Event {
+  final Event wrapped;
+
+  /** The CSS selector involved with event delegation. */
+  String _selector;
+
+  _WrappedEvent(this.wrapped);
+
+  bool get bubbles => wrapped.bubbles;
+
+  bool get cancelable => wrapped.cancelable;
+
+  bool get composed => wrapped.composed;
+
+  EventTarget get currentTarget => wrapped.currentTarget;
+
+  bool get defaultPrevented => wrapped.defaultPrevented;
+
+  int get eventPhase => wrapped.eventPhase;
+
+  bool get isTrusted => wrapped.isTrusted;
+
+  EventTarget get target => wrapped.target;
+
+  double get timeStamp => wrapped.timeStamp;
+
+  String get type => wrapped.type;
+
+  void _initEvent(String type, [bool bubbles, bool cancelable]) {
+    throw new UnsupportedError('Cannot initialize this Event.');
+  }
+
+  void preventDefault() {
+    wrapped.preventDefault();
+  }
+
+  void stopImmediatePropagation() {
+    wrapped.stopImmediatePropagation();
+  }
+
+  void stopPropagation() {
+    wrapped.stopPropagation();
+  }
+
+  List<EventTarget> composedPath() => wrapped.composedPath();
+
+  /**
+   * A pointer to the element whose CSS selector matched within which an event
+   * was fired. If this Event was not associated with any Event delegation,
+   * accessing this value will throw an [UnsupportedError].
+   */
+  Element get matchingTarget {
+    if (_selector == null) {
+      throw new UnsupportedError('Cannot call matchingTarget if this Event did'
+          ' not arise as a result of event delegation.');
+    }
+    Element currentTarget = this.currentTarget;
+    Element target = this.target;
+    var matchedTarget;
+    do {
+      if (target.matches(_selector)) return target;
+      target = target.parent;
+    } while (target != null && target != currentTarget.parent);
+    throw new StateError('No selector matched for populating matchedTarget.');
+  }
+
+  /**
+   * This event's path, taking into account shadow DOM.
+   *
+   * ## Other resources
+   *
+   * * [Shadow DOM extensions to
+   *   Event](http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event)
+   *   from W3C.
+   */
+  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event
+  List<Node> get path => wrapped.path;
+
+  dynamic get _get_currentTarget => wrapped._get_currentTarget;
+
+  dynamic get _get_target => wrapped._get_target;
+}
+// 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.
+
+void Function(T) _wrapZone<T>(void Function(T) callback) {
+  // For performance reasons avoid wrapping if we are in the root zone.
+  if (Zone.current == Zone.root) return callback;
+  if (callback == null) return null;
+  return Zone.current.bindUnaryCallbackGuarded(callback);
+}
+
+void Function(T1, T2) _wrapBinaryZone<T1, T2>(void Function(T1, T2) callback) {
+  // For performance reasons avoid wrapping if we are in the root zone.
+  if (Zone.current == Zone.root) return callback;
+  if (callback == null) return null;
+  return Zone.current.bindBinaryCallbackGuarded(callback);
+}
+
+/**
+ * Finds the first descendant element of this document that matches the
+ * specified group of selectors.
+ *
+ * Unless your webpage contains multiple documents, the top-level
+ * [querySelector]
+ * method behaves the same as this method, so you should use it instead to
+ * save typing a few characters.
+ *
+ * [selectors] should be a string using CSS selector syntax.
+ *
+ *     var element1 = document.querySelector('.className');
+ *     var element2 = document.querySelector('#id');
+ *
+ * For details about CSS selector syntax, see the
+ * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
+ */
+Element querySelector(String selectors) => document.querySelector(selectors);
+
+/**
+ * Finds all descendant elements of this document that match the specified
+ * group of selectors.
+ *
+ * Unless your webpage contains multiple documents, the top-level
+ * [querySelectorAll]
+ * method behaves the same as this method, so you should use it instead to
+ * save typing a few characters.
+ *
+ * [selectors] should be a string using CSS selector syntax.
+ *
+ *     var items = document.querySelectorAll('.itemClassName');
+ *
+ * For details about CSS selector syntax, see the
+ * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
+ */
+ElementList<T> querySelectorAll<T extends Element>(String selectors) =>
+    document.querySelectorAll(selectors);
+
+/// A utility for changing the Dart wrapper type for elements.
+abstract class ElementUpgrader {
+  /// Upgrade the specified element to be of the Dart type this was created for.
+  ///
+  /// After upgrading the element passed in is invalid and the returned value
+  /// should be used instead.
+  Element upgrade(Element element);
+}
+// 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.
+
+/**
+ * Interface used to validate that only accepted elements and attributes are
+ * allowed while parsing HTML strings into DOM nodes.
+ *
+ * In general, customization of validation behavior should be done via the
+ * [NodeValidatorBuilder] class to mitigate the chances of incorrectly
+ * implementing validation rules.
+ */
+abstract class NodeValidator {
+  /**
+   * Construct a default NodeValidator which only accepts whitelisted HTML5
+   * elements and attributes.
+   *
+   * If a uriPolicy is not specified then the default uriPolicy will be used.
+   */
+  factory NodeValidator({UriPolicy uriPolicy}) =>
+      new _Html5NodeValidator(uriPolicy: uriPolicy);
+
+  factory NodeValidator.throws(NodeValidator base) =>
+      new _ThrowsNodeValidator(base);
+
+  /**
+   * Returns true if the tagName is an accepted type.
+   */
+  bool allowsElement(Element element);
+
+  /**
+   * Returns true if the attribute is allowed.
+   *
+   * The attributeName parameter will always be in lowercase.
+   *
+   * See [allowsElement] for format of tagName.
+   */
+  bool allowsAttribute(Element element, String attributeName, String value);
+}
+
+/**
+ * Performs sanitization of a node tree after construction to ensure that it
+ * does not contain any disallowed elements or attributes.
+ *
+ * In general custom implementations of this class should not be necessary and
+ * all validation customization should be done in custom NodeValidators, but
+ * custom implementations of this class can be created to perform more complex
+ * tree sanitization.
+ */
+abstract class NodeTreeSanitizer {
+  /**
+   * Constructs a default tree sanitizer which will remove all elements and
+   * attributes which are not allowed by the provided validator.
+   */
+  factory NodeTreeSanitizer(NodeValidator validator) =>
+      new _ValidatingTreeSanitizer(validator);
+
+  /**
+   * Called with the root of the tree which is to be sanitized.
+   *
+   * This method needs to walk the entire tree and either remove elements and
+   * attributes which are not recognized as safe or throw an exception which
+   * will mark the entire tree as unsafe.
+   */
+  void sanitizeTree(Node node);
+
+  /**
+   * A sanitizer for trees that we trust. It does no validation and allows
+   * any elements. It is also more efficient, since it can pass the text
+   * directly through to the underlying APIs without creating a document
+   * fragment to be sanitized.
+   */
+  static const trusted = const _TrustedHtmlTreeSanitizer();
+}
+
+/**
+ * A sanitizer for trees that we trust. It does no validation and allows
+ * any elements.
+ */
+class _TrustedHtmlTreeSanitizer implements NodeTreeSanitizer {
+  const _TrustedHtmlTreeSanitizer();
+
+  sanitizeTree(Node node) {}
+}
+
+/**
+ * Defines the policy for what types of uris are allowed for particular
+ * attribute values.
+ *
+ * This can be used to provide custom rules such as allowing all http:// URIs
+ * for image attributes but only same-origin URIs for anchor tags.
+ */
+abstract class UriPolicy {
+  /**
+   * Constructs the default UriPolicy which is to only allow Uris to the same
+   * origin as the application was launched from.
+   *
+   * This will block all ftp: mailto: URIs. It will also block accessing
+   * https://example.com if the app is running from http://example.com.
+   */
+  factory UriPolicy() => new _SameOriginUriPolicy();
+
+  /**
+   * Checks if the uri is allowed on the specified attribute.
+   *
+   * The uri provided may or may not be a relative path.
+   */
+  bool allowsUri(String uri);
+}
+
+/**
+ * Allows URIs to the same origin as the current application was loaded from
+ * (such as https://example.com:80).
+ */
+class _SameOriginUriPolicy implements UriPolicy {
+  final AnchorElement _hiddenAnchor = new AnchorElement();
+  final Location _loc = window.location;
+
+  bool allowsUri(String uri) {
+    _hiddenAnchor.href = uri;
+    // IE leaves an empty hostname for same-origin URIs.
+    return (_hiddenAnchor.hostname == _loc.hostname &&
+            _hiddenAnchor.port == _loc.port &&
+            _hiddenAnchor.protocol == _loc.protocol) ||
+        (_hiddenAnchor.hostname == '' &&
+            _hiddenAnchor.port == '' &&
+            (_hiddenAnchor.protocol == ':' || _hiddenAnchor.protocol == ''));
+  }
+}
+
+class _ThrowsNodeValidator implements NodeValidator {
+  final NodeValidator validator;
+
+  _ThrowsNodeValidator(this.validator) {}
+
+  bool allowsElement(Element element) {
+    if (!validator.allowsElement(element)) {
+      throw new ArgumentError(Element._safeTagName(element));
+    }
+    return true;
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    if (!validator.allowsAttribute(element, attributeName, value)) {
+      throw new ArgumentError(
+          '${Element._safeTagName(element)}[$attributeName="$value"]');
+    }
+  }
+}
+
+/**
+ * Standard tree sanitizer which validates a node tree against the provided
+ * validator and removes any nodes or attributes which are not allowed.
+ */
+class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
+  NodeValidator validator;
+  _ValidatingTreeSanitizer(this.validator) {}
+
+  void sanitizeTree(Node node) {
+    void walk(Node node, Node parent) {
+      sanitizeNode(node, parent);
+
+      var child = node.lastChild;
+      while (null != child) {
+        var nextChild;
+        try {
+          // Child may be removed during the walk, and we may not
+          // even be able to get its previousNode.
+          nextChild = child.previousNode;
+        } catch (e) {
+          // Child appears bad, remove it. We want to check the rest of the
+          // children of node and, but we have no way of getting to the next
+          // child, so start again from the last child.
+          _removeNode(child, node);
+          child = null;
+          nextChild = node.lastChild;
+        }
+        if (child != null) walk(child, node);
+        child = nextChild;
+      }
+    }
+
+    walk(node, null);
+  }
+
+  /// Aggressively try to remove node.
+  void _removeNode(Node node, Node parent) {
+    // If we have the parent, it's presumably already passed more sanitization
+    // or is the fragment, so ask it to remove the child. And if that fails
+    // try to set the outer html.
+    if (parent == null) {
+      node.remove();
+    } else {
+      parent._removeChild(node);
+    }
+  }
+
+  /// Sanitize the element, assuming we can't trust anything about it.
+  void _sanitizeUntrustedElement(/* Element */ element, Node parent) {
+    // If the _hasCorruptedAttributes does not successfully return false,
+    // then we consider it corrupted and remove.
+    // TODO(alanknight): This is a workaround because on Firefox
+    // embed/object
+    // tags typeof is "function", not "object". We don't recognize them, and
+    // can't call methods. This does mean that you can't explicitly allow an
+    // embed tag. The only thing that will let it through is a null
+    // sanitizer that doesn't traverse the tree at all. But sanitizing while
+    // allowing embeds seems quite unlikely. This is also the reason that we
+    // can't declare the type of element, as an embed won't pass any type
+    // check in dart2js.
+    var corrupted = true;
+    var attrs;
+    var isAttr;
+    try {
+      // If getting/indexing attributes throws, count that as corrupt.
+      attrs = element.attributes;
+      isAttr = attrs['is'];
+      var corruptedTest1 = Element._hasCorruptedAttributes(element);
+
+      // On IE, erratically, the hasCorruptedAttributes test can return false,
+      // even though it clearly is corrupted. A separate copy of the test
+      // inlining just the basic check seems to help.
+      corrupted = corruptedTest1
+          ? true
+          : Element._hasCorruptedAttributesAdditionalCheck(element);
+    } catch (e) {}
+    var elementText = 'element unprintable';
+    try {
+      elementText = element.toString();
+    } catch (e) {}
+    try {
+      var elementTagName = Element._safeTagName(element);
+      _sanitizeElement(element, parent, corrupted, elementText, elementTagName,
+          attrs, isAttr);
+    } on ArgumentError {
+      // Thrown by _ThrowsNodeValidator
+      rethrow;
+    } catch (e) {
+      // Unexpected exception sanitizing -> remove
+      _removeNode(element, parent);
+      window.console.warn('Removing corrupted element $elementText');
+    }
+  }
+
+  /// Having done basic sanity checking on the element, and computed the
+  /// important attributes we want to check, remove it if it's not valid
+  /// or not allowed, either as a whole or particular attributes.
+  void _sanitizeElement(Element element, Node parent, bool corrupted,
+      String text, String tag, Map attrs, String isAttr) {
+    if (false != corrupted) {
+      _removeNode(element, parent);
+      window.console
+          .warn('Removing element due to corrupted attributes on <$text>');
+      return;
+    }
+    if (!validator.allowsElement(element)) {
+      _removeNode(element, parent);
+      window.console.warn('Removing disallowed element <$tag> from $parent');
+      return;
+    }
+
+    if (isAttr != null) {
+      if (!validator.allowsAttribute(element, 'is', isAttr)) {
+        _removeNode(element, parent);
+        window.console.warn('Removing disallowed type extension '
+            '<$tag is="$isAttr">');
+        return;
+      }
+    }
+
+    // TODO(blois): Need to be able to get all attributes, irrespective of
+    // XMLNS.
+    var keys = attrs.keys.toList();
+    for (var i = attrs.length - 1; i >= 0; --i) {
+      var name = keys[i];
+      if (!validator.allowsAttribute(
+          element, name.toLowerCase(), attrs[name])) {
+        window.console.warn('Removing disallowed attribute '
+            '<$tag $name="${attrs[name]}">');
+        attrs.remove(name);
+      }
+    }
+
+    if (element is TemplateElement) {
+      TemplateElement template = element;
+      sanitizeTree(template.content);
+    }
+  }
+
+  /// Sanitize the node and its children recursively.
+  void sanitizeNode(Node node, Node parent) {
+    switch (node.nodeType) {
+      case Node.ELEMENT_NODE:
+        _sanitizeUntrustedElement(node, parent);
+        break;
+      case Node.COMMENT_NODE:
+      case Node.DOCUMENT_FRAGMENT_NODE:
+      case Node.TEXT_NODE:
+      case Node.CDATA_SECTION_NODE:
+        break;
+      default:
+        _removeNode(node, parent);
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/html/dartium/nativewrappers.dart b/sdk_nnbd/lib/html/dartium/nativewrappers.dart
new file mode 100644
index 0000000..b6d2dc4
--- /dev/null
+++ b/sdk_nnbd/lib/html/dartium/nativewrappers.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library nativewrappers;
+
+class NativeFieldWrapperClass1 {}
+
+class NativeFieldWrapperClass2 {}
+
+class NativeFieldWrapperClass3 {}
+
+class NativeFieldWrapperClass4 {}
diff --git a/sdk_nnbd/lib/html/html_common/conversions.dart b/sdk_nnbd/lib/html/html_common/conversions.dart
new file mode 100644
index 0000000..4c31efb
--- /dev/null
+++ b/sdk_nnbd/lib/html/html_common/conversions.dart
@@ -0,0 +1,359 @@
+// Copyright (c) 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.
+
+// Conversions for IDBKey.
+//
+// Per http://www.w3.org/TR/IndexedDB/#key-construct
+//
+// "A value is said to be a valid key if it is one of the following types: Array
+// JavaScript objects [ECMA-262], DOMString [WEBIDL], Date [ECMA-262] or float
+// [WEBIDL]. However Arrays are only valid keys if every item in the array is
+// defined and is a valid key (i.e. sparse arrays can not be valid keys) and if
+// the Array doesn't directly or indirectly contain itself. Any non-numeric
+// properties are ignored, and thus does not affect whether the Array is a valid
+// key. Additionally, if the value is of type float, it is only a valid key if
+// it is not NaN, and if the value is of type Date it is only a valid key if its
+// [[PrimitiveValue]] internal property, as defined by [ECMA-262], is not NaN."
+
+// What is required is to ensure that an Lists in the key are actually
+// JavaScript arrays, and any Dates are JavaScript Dates.
+
+// Conversions for Window.  These check if the window is the local
+// window, and if it's not, wraps or unwraps it with a secure wrapper.
+// We need to test for EventTarget here as well as it's a base type.
+// We omit an unwrapper for Window as no methods take a non-local
+// window as a parameter.
+
+part of html_common;
+
+/// Converts a Dart value into a JavaScript SerializedScriptValue.
+convertDartToNative_SerializedScriptValue(value) {
+  return convertDartToNative_PrepareForStructuredClone(value);
+}
+
+/// Since the source object may be viewed via a JavaScript event listener the
+/// original may not be modified.
+convertNativeToDart_SerializedScriptValue(object) {
+  return convertNativeToDart_AcceptStructuredClone(object, mustCopy: true);
+}
+
+/**
+ * Converts a Dart value into a JavaScript SerializedScriptValue.  Returns the
+ * original input or a functional 'copy'.  Does not mutate the original.
+ *
+ * The main transformation is the translation of Dart Maps are converted to
+ * JavaScript Objects.
+ *
+ * The algorithm is essentially a dry-run of the structured clone algorithm
+ * described at
+ * http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#structured-clone
+ * https://www.khronos.org/registry/typedarray/specs/latest/#9
+ *
+ * Since the result of this function is expected to be passed only to JavaScript
+ * operations that perform the structured clone algorithm which does not mutate
+ * its output, the result may share structure with the input [value].
+ */
+abstract class _StructuredClone {
+  // TODO(sra): Replace slots with identity hash table.
+  var values = [];
+  var copies = []; // initially 'null', 'true' during initial DFS, then a copy.
+
+  int findSlot(value) {
+    int length = values.length;
+    for (int i = 0; i < length; i++) {
+      if (identical(values[i], value)) return i;
+    }
+    values.add(value);
+    copies.add(null);
+    return length;
+  }
+
+  readSlot(int i) => copies[i];
+  writeSlot(int i, x) {
+    copies[i] = x;
+  }
+
+  cleanupSlots() {} // Will be needed if we mark objects with a property.
+  bool cloneNotRequired(object);
+  newJsMap();
+  List newJsList(length);
+  void putIntoMap(map, key, value);
+
+  // Returns the input, or a clone of the input.
+  walk(e) {
+    if (e == null) return e;
+    if (e is bool) return e;
+    if (e is num) return e;
+    if (e is String) return e;
+    if (e is DateTime) {
+      return convertDartToNative_DateTime(e);
+    }
+    if (e is RegExp) {
+      // TODO(sra).
+      throw new UnimplementedError('structured clone of RegExp');
+    }
+
+    // The browser's internal structured cloning algorithm will copy certain
+    // types of object, but it will copy only its own implementations and not
+    // just any Dart implementations of the interface.
+
+    // TODO(sra): The JavaScript objects suitable for direct cloning by the
+    // structured clone algorithm could be tagged with an private interface.
+
+    if (e is File) return e;
+    if (e is Blob) return e;
+    if (e is FileList) return e;
+
+    // TODO(sra): Firefox: How to convert _TypedImageData on the other end?
+    if (e is ImageData) return e;
+    if (cloneNotRequired(e)) return e;
+
+    if (e is Map) {
+      var slot = findSlot(e);
+      var copy = readSlot(slot);
+      if (copy != null) return copy;
+      copy = newJsMap();
+      writeSlot(slot, copy);
+      e.forEach((key, value) {
+        putIntoMap(copy, key, walk(value));
+      });
+      return copy;
+    }
+
+    if (e is List) {
+      // Since a JavaScript Array is an instance of Dart List it is tempting
+      // in dart2js to avoid making a copy of the list if there is no need
+      // to copy anything reachable from the array.  However, the list may have
+      // non-native properties or methods from interceptors and such, e.g.
+      // an immutability marker. So we  had to stop doing that.
+      var slot = findSlot(e);
+      var copy = JS('returns:List|Null;creates:;', '#', readSlot(slot));
+      if (copy != null) return copy;
+      copy = copyList(e, slot);
+      return copy;
+    }
+
+    throw new UnimplementedError('structured clone of other type');
+  }
+
+  List copyList(List e, int slot) {
+    int i = 0;
+    int length = e.length;
+    var copy = newJsList(length);
+    writeSlot(slot, copy);
+    for (; i < length; i++) {
+      copy[i] = walk(e[i]);
+    }
+    return copy;
+  }
+
+  convertDartToNative_PrepareForStructuredClone(value) {
+    var copy = walk(value);
+    cleanupSlots();
+    return copy;
+  }
+}
+
+/**
+ * Converts a native value into a Dart object.
+ *
+ * If [mustCopy] is [:false:], may return the original input.  May mutate the
+ * original input (but will be idempotent if mutation occurs).  It is assumed
+ * that this conversion happens on native serializable script values such values
+ * from native DOM calls.
+ *
+ * [object] is the result of a structured clone operation.
+ *
+ * If necessary, JavaScript Dates are converted into Dart Dates.
+ *
+ * If [mustCopy] is [:true:], the entire object is copied and the original input
+ * is not mutated.  This should be the case where Dart and JavaScript code can
+ * access the value, for example, via multiple event listeners for
+ * MessageEvents.  Mutating the object to make it more 'Dart-like' would corrupt
+ * the value as seen from the JavaScript listeners.
+ */
+abstract class _AcceptStructuredClone {
+  // TODO(sra): Replace slots with identity hash table.
+  var values = [];
+  var copies = []; // initially 'null', 'true' during initial DFS, then a copy.
+  bool mustCopy = false;
+
+  int findSlot(value) {
+    int length = values.length;
+    for (int i = 0; i < length; i++) {
+      if (identicalInJs(values[i], value)) return i;
+    }
+    values.add(value);
+    copies.add(null);
+    return length;
+  }
+
+  /// Are the two objects identical, but taking into account that two JsObject
+  /// wrappers may not be identical, but their underlying Js Object might be.
+  bool identicalInJs(a, b);
+  readSlot(int i) => copies[i];
+  writeSlot(int i, x) {
+    copies[i] = x;
+  }
+
+  /// Iterate over the JS properties.
+  forEachJsField(object, action(key, value));
+
+  /// Create a new Dart list of the given length. May create a native List or
+  /// a JsArray, depending if we're in Dartium or dart2js.
+  List newDartList(length);
+
+  walk(e) {
+    if (e == null) return e;
+    if (e is bool) return e;
+    if (e is num) return e;
+    if (e is String) return e;
+
+    if (isJavaScriptDate(e)) {
+      return convertNativeToDart_DateTime(e);
+    }
+
+    if (isJavaScriptRegExp(e)) {
+      // TODO(sra).
+      throw new UnimplementedError('structured clone of RegExp');
+    }
+
+    if (isJavaScriptPromise(e)) {
+      return convertNativePromiseToDartFuture(e);
+    }
+
+    if (isJavaScriptSimpleObject(e)) {
+      // TODO(sra): If mustCopy is false, swizzle the prototype for one of a Map
+      // implementation that uses the properties as storage.
+      var slot = findSlot(e);
+      var copy = readSlot(slot);
+      if (copy != null) return copy;
+      copy = {};
+
+      writeSlot(slot, copy);
+      forEachJsField(e, (key, value) => copy[key] = walk(value));
+      return copy;
+    }
+
+    if (isJavaScriptArray(e)) {
+      var l = JS<List>('returns:List;creates:;', '#', e);
+      var slot = findSlot(l);
+      var copy = JS<List>('returns:List|Null;creates:;', '#', readSlot(slot));
+      if (copy != null) return copy;
+
+      int length = l.length;
+      // Since a JavaScript Array is an instance of Dart List, we can modify it
+      // in-place unless we must copy.
+      copy = mustCopy ? newDartList(length) : l;
+      writeSlot(slot, copy);
+
+      for (int i = 0; i < length; i++) {
+        copy[i] = walk(l[i]);
+      }
+      return copy;
+    }
+
+    // Assume anything else is already a valid Dart object, either by having
+    // already been processed, or e.g. a cloneable native class.
+    return e;
+  }
+
+  convertNativeToDart_AcceptStructuredClone(object, {mustCopy: false}) {
+    this.mustCopy = mustCopy;
+    var copy = walk(object);
+    return copy;
+  }
+}
+
+// Conversions for ContextAttributes.
+//
+// On Firefox, the returned ContextAttributes is a plain object.
+class ContextAttributes {
+  bool alpha;
+  bool antialias;
+  bool depth;
+  bool premultipliedAlpha;
+  bool preserveDrawingBuffer;
+  bool stencil;
+  bool failIfMajorPerformanceCaveat;
+
+  ContextAttributes(
+      this.alpha,
+      this.antialias,
+      this.depth,
+      this.failIfMajorPerformanceCaveat,
+      this.premultipliedAlpha,
+      this.preserveDrawingBuffer,
+      this.stencil);
+}
+
+convertNativeToDart_ContextAttributes(nativeContextAttributes) {
+  // On Firefox the above test fails because ContextAttributes is a plain
+  // object so we create a _TypedContextAttributes.
+
+  return new ContextAttributes(
+      JS('var', '#.alpha', nativeContextAttributes),
+      JS('var', '#.antialias', nativeContextAttributes),
+      JS('var', '#.depth', nativeContextAttributes),
+      JS('var', '#.failIfMajorPerformanceCaveat', nativeContextAttributes),
+      JS('var', '#.premultipliedAlpha', nativeContextAttributes),
+      JS('var', '#.preserveDrawingBuffer', nativeContextAttributes),
+      JS('var', '#.stencil', nativeContextAttributes));
+}
+
+// Conversions for ImageData
+//
+// On Firefox, the returned ImageData is a plain object.
+
+class _TypedImageData implements ImageData {
+  final Uint8ClampedList data;
+  final int height;
+  final int width;
+
+  _TypedImageData(this.data, this.height, this.width);
+}
+
+ImageData convertNativeToDart_ImageData(nativeImageData) {
+  // None of the native getters that return ImageData are declared as returning
+  // [ImageData] since that is incorrect for FireFox, which returns a plain
+  // Object.  So we need something that tells the compiler that the ImageData
+  // class has been instantiated.
+  // TODO(sra): Remove this when all the ImageData returning APIs have been
+  // annotated as returning the union ImageData + Object.
+  JS('ImageData', '0');
+
+  if (nativeImageData is ImageData) {
+    // Fix for Issue 16069: on IE, the `data` field is a CanvasPixelArray which
+    // has Array as the constructor property.  This interferes with finding the
+    // correct interceptor.  Fix it by overwriting the constructor property.
+    var data = nativeImageData.data;
+    if (JS('bool', '#.constructor === Array', data)) {
+      if (JS('bool', 'typeof CanvasPixelArray !== "undefined"')) {
+        JS('void', '#.constructor = CanvasPixelArray', data);
+        // This TypedArray property is missing from CanvasPixelArray.
+        JS('void', '#.BYTES_PER_ELEMENT = 1', data);
+      }
+    }
+
+    return nativeImageData;
+  }
+
+  // On Firefox the above test fails because [nativeImageData] is a plain
+  // object.  So we create a _TypedImageData.
+
+  return new _TypedImageData(
+      JS('NativeUint8ClampedList', '#.data', nativeImageData),
+      JS('var', '#.height', nativeImageData),
+      JS('var', '#.width', nativeImageData));
+}
+
+// We can get rid of this conversion if _TypedImageData implements the fields
+// with native names.
+convertDartToNative_ImageData(ImageData imageData) {
+  if (imageData is _TypedImageData) {
+    return JS('', '{data: #, height: #, width: #}', imageData.data,
+        imageData.height, imageData.width);
+  }
+  return imageData;
+}
diff --git a/sdk_nnbd/lib/html/html_common/conversions_dart2js.dart b/sdk_nnbd/lib/html/html_common/conversions_dart2js.dart
new file mode 100644
index 0000000..36153cf
--- /dev/null
+++ b/sdk_nnbd/lib/html/html_common/conversions_dart2js.dart
@@ -0,0 +1,106 @@
+part of html_common;
+
+/// Converts a JavaScript object with properties into a Dart Map.
+/// Not suitable for nested objects.
+Map<String, dynamic> convertNativeToDart_Dictionary(object) {
+  if (object == null) return null;
+  var dict = <String, dynamic>{};
+  var keys = JS('JSExtendableArray', 'Object.getOwnPropertyNames(#)', object);
+  for (final key in keys) {
+    dict[key] = JS('var', '#[#]', object, key);
+  }
+  return dict;
+}
+
+/// Converts a flat Dart map into a JavaScript object with properties.
+convertDartToNative_Dictionary(Map dict, [void postCreate(Object f)]) {
+  if (dict == null) return null;
+  var object = JS('var', '{}');
+  if (postCreate != null) {
+    postCreate(object);
+  }
+  dict.forEach((key, value) {
+    JS('void', '#[#] = #', object, key, value);
+  });
+  return object;
+}
+
+/**
+ * Ensures that the input is a JavaScript Array.
+ *
+ * Creates a new JavaScript array if necessary, otherwise returns the original.
+ */
+List convertDartToNative_StringArray(List<String> input) {
+  // TODO(sra).  Implement this.
+  return input;
+}
+
+DateTime convertNativeToDart_DateTime(date) {
+  var millisSinceEpoch = JS('int', '#.getTime()', date);
+  return new DateTime.fromMillisecondsSinceEpoch(millisSinceEpoch, isUtc: true);
+}
+
+convertDartToNative_DateTime(DateTime date) {
+  return JS('', 'new Date(#)', date.millisecondsSinceEpoch);
+}
+
+convertDartToNative_PrepareForStructuredClone(value) =>
+    new _StructuredCloneDart2Js()
+        .convertDartToNative_PrepareForStructuredClone(value);
+
+convertNativeToDart_AcceptStructuredClone(object, {mustCopy: false}) =>
+    new _AcceptStructuredCloneDart2Js()
+        .convertNativeToDart_AcceptStructuredClone(object, mustCopy: mustCopy);
+
+class _StructuredCloneDart2Js extends _StructuredClone {
+  newJsMap() => JS('var', '{}');
+  putIntoMap(map, key, value) => JS('void', '#[#] = #', map, key, value);
+  newJsList(length) => JS('JSExtendableArray', 'new Array(#)', length);
+  cloneNotRequired(e) =>
+      (e is NativeByteBuffer || e is NativeTypedData || e is MessagePort);
+}
+
+class _AcceptStructuredCloneDart2Js extends _AcceptStructuredClone {
+  List newJsList(length) => JS('JSExtendableArray', 'new Array(#)', length);
+  List newDartList(length) => newJsList(length);
+  bool identicalInJs(a, b) => identical(a, b);
+
+  void forEachJsField(object, action(key, value)) {
+    for (final key in JS('JSExtendableArray', 'Object.keys(#)', object)) {
+      action(key, JS('var', '#[#]', object, key));
+    }
+  }
+}
+
+bool isJavaScriptDate(value) => JS('bool', '# instanceof Date', value);
+bool isJavaScriptRegExp(value) => JS('bool', '# instanceof RegExp', value);
+bool isJavaScriptArray(value) => JS('bool', '# instanceof Array', value);
+bool isJavaScriptSimpleObject(value) {
+  var proto = JS('', 'Object.getPrototypeOf(#)', value);
+  return JS('bool', '# === Object.prototype', proto) ||
+      JS('bool', '# === null', proto);
+}
+
+bool isImmutableJavaScriptArray(value) =>
+    JS('bool', r'!!(#.immutable$list)', value);
+bool isJavaScriptPromise(value) =>
+    JS('bool', r'typeof Promise != "undefined" && # instanceof Promise', value);
+
+Future convertNativePromiseToDartFuture(promise) {
+  var completer = new Completer();
+  var then = convertDartClosureToJS((result) => completer.complete(result), 1);
+  var error =
+      convertDartClosureToJS((result) => completer.completeError(result), 1);
+  var newPromise = JS('', '#.then(#)["catch"](#)', promise, then, error);
+  return completer.future;
+}
+
+const String _serializedScriptValue = 'num|String|bool|'
+    'JSExtendableArray|=Object|'
+    'Blob|File|NativeByteBuffer|NativeTypedData|MessagePort'
+    // TODO(sra): Add Date, RegExp.
+    ;
+const annotation_Creates_SerializedScriptValue =
+    const Creates(_serializedScriptValue);
+const annotation_Returns_SerializedScriptValue =
+    const Returns(_serializedScriptValue);
diff --git a/sdk_nnbd/lib/html/html_common/css_class_set.dart b/sdk_nnbd/lib/html/html_common/css_class_set.dart
new file mode 100644
index 0000000..2286057
--- /dev/null
+++ b/sdk_nnbd/lib/html/html_common/css_class_set.dart
@@ -0,0 +1,242 @@
+// Copyright (c) 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 html_common;
+
+abstract class CssClassSetImpl extends SetBase<String> implements CssClassSet {
+  static final RegExp _validTokenRE = new RegExp(r'^\S+$');
+
+  String _validateToken(String value) {
+    if (_validTokenRE.hasMatch(value)) return value;
+    throw new ArgumentError.value(value, 'value', 'Not a valid class token');
+  }
+
+  String toString() {
+    return readClasses().join(' ');
+  }
+
+  /**
+   * Adds the class [value] to the element if it is not on it, removes it if it
+   * is.
+   *
+   * If [shouldAdd] is true, then we always add that [value] to the element. If
+   * [shouldAdd] is false then we always remove [value] from the element.
+   */
+  bool toggle(String value, [bool shouldAdd]) {
+    _validateToken(value);
+    Set<String> s = readClasses();
+    bool result = false;
+    if (shouldAdd == null) shouldAdd = !s.contains(value);
+    if (shouldAdd) {
+      s.add(value);
+      result = true;
+    } else {
+      s.remove(value);
+    }
+    writeClasses(s);
+    return result;
+  }
+
+  /**
+   * Returns [:true:] if classes cannot be added or removed from this
+   * [:CssClassSet:].
+   */
+  bool get frozen => false;
+
+  // interface Iterable - BEGIN
+  Iterator<String> get iterator => readClasses().iterator;
+  // interface Iterable - END
+
+  // interface Collection - BEGIN
+  void forEach(void f(String element)) {
+    readClasses().forEach(f);
+  }
+
+  String join([String separator = ""]) => readClasses().join(separator);
+
+  Iterable<T> map<T>(T f(String e)) => readClasses().map<T>(f);
+
+  Iterable<String> where(bool f(String element)) => readClasses().where(f);
+
+  Iterable<T> expand<T>(Iterable<T> f(String element)) =>
+      readClasses().expand<T>(f);
+
+  bool every(bool f(String element)) => readClasses().every(f);
+
+  bool any(bool f(String element)) => readClasses().any(f);
+
+  bool get isEmpty => readClasses().isEmpty;
+
+  bool get isNotEmpty => readClasses().isNotEmpty;
+
+  int get length => readClasses().length;
+
+  String reduce(String combine(String value, String element)) {
+    return readClasses().reduce(combine);
+  }
+
+  T fold<T>(T initialValue, T combine(T previousValue, String element)) {
+    return readClasses().fold<T>(initialValue, combine);
+  }
+
+  // interface Collection - END
+
+  // interface Set - BEGIN
+  /**
+   * Determine if this element contains the class [value].
+   *
+   * This is the Dart equivalent of jQuery's
+   * [hasClass](http://api.jquery.com/hasClass/).
+   */
+  bool contains(Object value) {
+    if (value is! String) return false;
+    _validateToken(value);
+    return readClasses().contains(value);
+  }
+
+  /** Lookup from the Set interface. Not interesting for a String set. */
+  String lookup(Object value) => contains(value) ? value : null;
+
+  /**
+   * Add the class [value] to element.
+   *
+   * This is the Dart equivalent of jQuery's
+   * [addClass](http://api.jquery.com/addClass/).
+   */
+  bool add(String value) {
+    _validateToken(value);
+    // TODO - figure out if we need to do any validation here
+    // or if the browser natively does enough.
+    return modify((s) => s.add(value));
+  }
+
+  /**
+   * Remove the class [value] from element, and return true on successful
+   * removal.
+   *
+   * This is the Dart equivalent of jQuery's
+   * [removeClass](http://api.jquery.com/removeClass/).
+   */
+  bool remove(Object value) {
+    _validateToken(value);
+    if (value is! String) return false;
+    Set<String> s = readClasses();
+    bool result = s.remove(value);
+    writeClasses(s);
+    return result;
+  }
+
+  /**
+   * Add all classes specified in [iterable] to element.
+   *
+   * This is the Dart equivalent of jQuery's
+   * [addClass](http://api.jquery.com/addClass/).
+   */
+  void addAll(Iterable<String> iterable) {
+    // TODO - see comment above about validation.
+    modify((s) => s.addAll(iterable.map(_validateToken)));
+  }
+
+  /**
+   * Remove all classes specified in [iterable] from element.
+   *
+   * This is the Dart equivalent of jQuery's
+   * [removeClass](http://api.jquery.com/removeClass/).
+   */
+  void removeAll(Iterable<Object> iterable) {
+    modify((s) => s.removeAll(iterable));
+  }
+
+  /**
+   * Toggles all classes specified in [iterable] on element.
+   *
+   * Iterate through [iterable]'s items, and add it if it is not on it, or
+   * remove it if it is. This is the Dart equivalent of jQuery's
+   * [toggleClass](http://api.jquery.com/toggleClass/).
+   * If [shouldAdd] is true, then we always add all the classes in [iterable]
+   * element. If [shouldAdd] is false then we always remove all the classes in
+   * [iterable] from the element.
+   */
+  void toggleAll(Iterable<String> iterable, [bool shouldAdd]) {
+    iterable.forEach((e) => toggle(e, shouldAdd));
+  }
+
+  void retainAll(Iterable<Object> iterable) {
+    modify((s) => s.retainAll(iterable));
+  }
+
+  void removeWhere(bool test(String name)) {
+    modify((s) => s.removeWhere(test));
+  }
+
+  void retainWhere(bool test(String name)) {
+    modify((s) => s.retainWhere(test));
+  }
+
+  bool containsAll(Iterable<Object> collection) =>
+      readClasses().containsAll(collection);
+
+  Set<String> intersection(Set<Object> other) =>
+      readClasses().intersection(other);
+
+  Set<String> union(Set<String> other) => readClasses().union(other);
+
+  Set<String> difference(Set<Object> other) => readClasses().difference(other);
+
+  String get first => readClasses().first;
+  String get last => readClasses().last;
+  String get single => readClasses().single;
+  List<String> toList({bool growable: true}) =>
+      readClasses().toList(growable: growable);
+  Set<String> toSet() => readClasses().toSet();
+  Iterable<String> take(int n) => readClasses().take(n);
+  Iterable<String> takeWhile(bool test(String value)) =>
+      readClasses().takeWhile(test);
+  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()}) =>
+      readClasses().firstWhere(test, orElse: orElse);
+  String lastWhere(bool test(String value), {String orElse()}) =>
+      readClasses().lastWhere(test, orElse: orElse);
+  String singleWhere(bool test(String value), {String orElse()}) =>
+      readClasses().singleWhere(test, orElse: orElse);
+  String elementAt(int index) => readClasses().elementAt(index);
+
+  void clear() {
+    // TODO(sra): Do this without reading the classes.
+    modify((s) => s.clear());
+  }
+  // interface Set - END
+
+  /**
+   * Helper method used to modify the set of css classes on this element.
+   *
+   *   f - callback with:
+   *   s - a Set of all the css class name currently on this element.
+   *
+   *   After f returns, the modified set is written to the
+   *       className property of this element.
+   */
+  modify(f(Set<String> s)) {
+    Set<String> s = readClasses();
+    var ret = f(s);
+    writeClasses(s);
+    return ret;
+  }
+
+  /**
+   * Read the class names from the Element class property,
+   * and put them into a set (duplicates are discarded).
+   * This is intended to be overridden by specific implementations.
+   */
+  Set<String> readClasses();
+
+  /**
+   * Join all the elements of a set into one string and write
+   * back to the element.
+   * This is intended to be overridden by specific implementations.
+   */
+  void writeClasses(Set<String> s);
+}
diff --git a/sdk_nnbd/lib/html/html_common/device.dart b/sdk_nnbd/lib/html/html_common/device.dart
new file mode 100644
index 0000000..123a5db
--- /dev/null
+++ b/sdk_nnbd/lib/html/html_common/device.dart
@@ -0,0 +1,112 @@
+// 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.
+
+part of html_common;
+
+/**
+ * Utils for device detection.
+ */
+class Device {
+  static bool _isOpera;
+  static bool _isIE;
+  static bool _isFirefox;
+  static bool _isWebKit;
+  static String _cachedCssPrefix;
+  static String _cachedPropertyPrefix;
+
+  /**
+   * Gets the browser's user agent. Using this function allows tests to inject
+   * the user agent.
+ * Returns the user agent.
+   */
+  static String get userAgent => window.navigator.userAgent;
+
+  /**
+   * Determines if the current device is running Opera.
+   */
+  static bool get isOpera {
+    if (_isOpera == null) {
+      _isOpera = userAgent.contains("Opera", 0);
+    }
+    return _isOpera;
+  }
+
+  /**
+   * Determines if the current device is running Internet Explorer.
+   */
+  static bool get isIE {
+    if (_isIE == null) {
+      _isIE = !isOpera && userAgent.contains("Trident/", 0);
+    }
+    return _isIE;
+  }
+
+  /**
+   * Determines if the current device is running Firefox.
+   */
+  static bool get isFirefox {
+    if (_isFirefox == null) {
+      _isFirefox = userAgent.contains("Firefox", 0);
+    }
+    return _isFirefox;
+  }
+
+  /**
+   * Determines if the current device is running WebKit.
+   */
+  static bool get isWebKit {
+    if (_isWebKit == null) {
+      _isWebKit = !isOpera && userAgent.contains("WebKit", 0);
+    }
+    return _isWebKit;
+  }
+
+  /**
+   * Gets the CSS property prefix for the current platform.
+   */
+  static String get cssPrefix {
+    String prefix = _cachedCssPrefix;
+    if (prefix != null) return prefix;
+    if (isFirefox) {
+      prefix = '-moz-';
+    } else if (isIE) {
+      prefix = '-ms-';
+    } else if (isOpera) {
+      prefix = '-o-';
+    } else {
+      prefix = '-webkit-';
+    }
+    return _cachedCssPrefix = prefix;
+  }
+
+  /**
+   * Prefix as used for JS property names.
+   */
+  static String get propertyPrefix {
+    String prefix = _cachedPropertyPrefix;
+    if (prefix != null) return prefix;
+    if (isFirefox) {
+      prefix = 'moz';
+    } else if (isIE) {
+      prefix = 'ms';
+    } else if (isOpera) {
+      prefix = 'o';
+    } else {
+      prefix = 'webkit';
+    }
+    return _cachedPropertyPrefix = prefix;
+  }
+
+  /**
+   * Checks to see if the event class is supported by the current platform.
+   */
+  static bool isEventTypeSupported(String eventType) {
+    // Browsers throw for unsupported event names.
+    try {
+      var e = new Event.eventType(eventType, '');
+      return e is Event;
+    } catch (_) {}
+    return false;
+  }
+}
diff --git a/sdk_nnbd/lib/html/html_common/filtered_element_list.dart b/sdk_nnbd/lib/html/html_common/filtered_element_list.dart
new file mode 100644
index 0000000..fba6ad7
--- /dev/null
+++ b/sdk_nnbd/lib/html/html_common/filtered_element_list.dart
@@ -0,0 +1,150 @@
+// 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.
+
+part of html_common;
+
+/**
+ * An indexable collection of a node's direct descendants in the document tree,
+ * filtered so that only elements are in the collection.
+ */
+class FilteredElementList extends ListBase<Element> implements NodeListWrapper {
+  final Node _node;
+  final List<Node> _childNodes;
+
+  /**
+   * Creates a collection of the elements that descend from a node.
+   *
+   * Example usage:
+   *
+   *     var filteredElements = new FilteredElementList(query("#container"));
+   *     // filteredElements is [a, b, c].
+   */
+  FilteredElementList(Node node)
+      : _childNodes = node.nodes,
+        _node = node;
+
+  // We can't memoize this, since it's possible that children will be messed
+  // with externally to this class.
+  Iterable<Element> get _iterable =>
+      _childNodes.where((n) => n is Element).map<Element>((n) => n as Element);
+  List<Element> get _filtered =>
+      new List<Element>.from(_iterable, growable: false);
+
+  void forEach(void f(Element element)) {
+    // This cannot use the iterator, because operations during iteration might
+    // modify the collection, e.g. addAll might append a node to another parent.
+    _filtered.forEach(f);
+  }
+
+  void operator []=(int index, Element value) {
+    this[index].replaceWith(value);
+  }
+
+  set length(int newLength) {
+    final len = this.length;
+    if (newLength >= len) {
+      return;
+    } else if (newLength < 0) {
+      throw new ArgumentError("Invalid list length");
+    }
+
+    removeRange(newLength, len);
+  }
+
+  void add(Element value) {
+    _childNodes.add(value);
+  }
+
+  void addAll(Iterable<Element> iterable) {
+    for (Element element in iterable) {
+      add(element);
+    }
+  }
+
+  bool contains(Object needle) {
+    if (needle is! Element) return false;
+    Element element = needle;
+    return element.parentNode == _node;
+  }
+
+  Iterable<Element> get reversed => _filtered.reversed;
+
+  void sort([int compare(Element a, Element b)]) {
+    throw new UnsupportedError('Cannot sort filtered list');
+  }
+
+  void setRange(int start, int end, Iterable<Element> iterable,
+      [int skipCount = 0]) {
+    throw new UnsupportedError('Cannot setRange on filtered list');
+  }
+
+  void fillRange(int start, int end, [Element fillValue]) {
+    throw new UnsupportedError('Cannot fillRange on filtered list');
+  }
+
+  void replaceRange(int start, int end, Iterable<Element> iterable) {
+    throw new UnsupportedError('Cannot replaceRange on filtered list');
+  }
+
+  void removeRange(int start, int end) {
+    new List.from(_iterable.skip(start).take(end - start))
+        .forEach((el) => el.remove());
+  }
+
+  void clear() {
+    // Currently, ElementList#clear clears even non-element nodes, so we follow
+    // that behavior.
+    _childNodes.clear();
+  }
+
+  Element removeLast() {
+    final result = _iterable.last;
+    if (result != null) {
+      result.remove();
+    }
+    return result;
+  }
+
+  void insert(int index, Element value) {
+    if (index == length) {
+      add(value);
+    } else {
+      var element = _iterable.elementAt(index);
+      element.parentNode.insertBefore(value, element);
+    }
+  }
+
+  void insertAll(int index, Iterable<Element> iterable) {
+    if (index == length) {
+      addAll(iterable);
+    } else {
+      var element = _iterable.elementAt(index);
+      element.parentNode.insertAllBefore(iterable, element);
+    }
+  }
+
+  Element removeAt(int index) {
+    final result = this[index];
+    result.remove();
+    return result;
+  }
+
+  bool remove(Object element) {
+    if (element is! Element) return false;
+    if (contains(element)) {
+      (element as Element).remove(); // Placate the type checker
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  int get length => _iterable.length;
+  Element operator [](int index) => _iterable.elementAt(index);
+  // This cannot use the iterator, because operations during iteration might
+  // modify the collection, e.g. addAll might append a node to another parent.
+  Iterator<Element> get iterator => _filtered.iterator;
+
+  List<Node> get rawList => _node.childNodes;
+}
diff --git a/sdk_nnbd/lib/html/html_common/html_common.dart b/sdk_nnbd/lib/html/html_common/html_common.dart
new file mode 100644
index 0000000..e689c9a
--- /dev/null
+++ b/sdk_nnbd/lib/html/html_common/html_common.dart
@@ -0,0 +1,25 @@
+// for 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 html_common;
+
+import 'dart:async';
+import 'dart:collection';
+import 'dart:html';
+import 'dart:js' as js;
+import 'dart:_internal' show WhereIterable;
+import 'dart:mirrors';
+import 'dart:nativewrappers';
+import 'dart:typed_data';
+import 'dart:web_gl' as gl;
+
+import 'dart:_js_helper';
+
+import 'dart:_metadata';
+export 'dart:_metadata';
+
+part 'css_class_set.dart';
+part 'device.dart';
+part 'filtered_element_list.dart';
+part 'lists.dart';
+part 'conversions.dart';
diff --git a/sdk_nnbd/lib/html/html_common/html_common_dart2js.dart b/sdk_nnbd/lib/html/html_common/html_common_dart2js.dart
new file mode 100644
index 0000000..f162ad8
--- /dev/null
+++ b/sdk_nnbd/lib/html/html_common/html_common_dart2js.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.
+
+library html_common;
+
+import 'dart:async';
+import 'dart:collection';
+import 'dart:html';
+import 'dart:_internal' show WhereIterable;
+import 'dart:web_gl' as gl;
+import 'dart:typed_data';
+import 'dart:_native_typed_data';
+import 'dart:_js_helper' show Creates, Returns, convertDartClosureToJS;
+import 'dart:_foreign_helper' show JS;
+import 'dart:_interceptors' show Interceptor, JSExtendableArray;
+
+import 'dart:_metadata';
+export 'dart:_metadata';
+
+part 'css_class_set.dart';
+part 'conversions.dart';
+part 'conversions_dart2js.dart';
+part 'device.dart';
+part 'filtered_element_list.dart';
+part 'lists.dart';
diff --git a/sdk_nnbd/lib/html/html_common/lists.dart b/sdk_nnbd/lib/html/html_common/lists.dart
new file mode 100644
index 0000000..c7abc41
--- /dev/null
+++ b/sdk_nnbd/lib/html/html_common/lists.dart
@@ -0,0 +1,71 @@
+// 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.
+
+part of html_common;
+
+class Lists {
+  /**
+   * Returns the index in the array [a] of the given [element], starting
+   * the search at index [startIndex] to [endIndex] (exclusive).
+   * Returns -1 if [element] is not found.
+   */
+  static int indexOf(List a, Object element, int startIndex, int endIndex) {
+    if (startIndex >= a.length) {
+      return -1;
+    }
+    if (startIndex < 0) {
+      startIndex = 0;
+    }
+    for (int i = startIndex; i < endIndex; i++) {
+      if (a[i] == element) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * Returns the last index in the array [a] of the given [element], starting
+   * the search at index [startIndex] to 0.
+   * Returns -1 if [element] is not found.
+   */
+  static int lastIndexOf(List a, Object element, int startIndex) {
+    if (startIndex < 0) {
+      return -1;
+    }
+    if (startIndex >= a.length) {
+      startIndex = a.length - 1;
+    }
+    for (int i = startIndex; i >= 0; i--) {
+      if (a[i] == element) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * Returns a sub list copy of this list, from [start] to
+   * [end] ([end] not inclusive).
+   * Returns an empty list if [length] is 0.
+   * It is an error if indices are not valid for the list, or
+   * if [end] is before [start].
+   */
+  static List getRange(List a, int start, int end, List accumulator) {
+    if (start < 0) throw new RangeError.value(start);
+    if (end < start) throw new RangeError.value(end);
+    if (end > a.length) throw new RangeError.value(end);
+    for (int i = start; i < end; i++) {
+      accumulator.add(a[i]);
+    }
+    return accumulator;
+  }
+}
+
+/**
+ * For accessing underlying node lists, for dart:js interop.
+ */
+abstract class NodeListWrapper {
+  List<Node> get rawList;
+}
diff --git a/sdk_nnbd/lib/html/html_common/metadata.dart b/sdk_nnbd/lib/html/html_common/metadata.dart
new file mode 100644
index 0000000..b5542dc
--- /dev/null
+++ b/sdk_nnbd/lib/html/html_common/metadata.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library metadata;
+
+/**
+ * An annotation used to mark a feature as only being supported by a subset
+ * of the browsers that Dart supports by default.
+ *
+ * If an API is not annotated with [SupportedBrowser] then it is assumed to
+ * work on all browsers Dart supports.
+ */
+class SupportedBrowser {
+  static const String CHROME = "Chrome";
+  static const String FIREFOX = "Firefox";
+  static const String IE = "Internet Explorer";
+  static const String OPERA = "Opera";
+  static const String SAFARI = "Safari";
+
+  /// The name of the browser.
+  final String browserName;
+
+  /// The minimum version of the browser that supports the feature, or null
+  /// if supported on all versions.
+  final String minimumVersion;
+
+  const SupportedBrowser(this.browserName, [this.minimumVersion]);
+}
+
+/**
+ * An annotation used to mark an API as being experimental.
+ *
+ * An API is considered to be experimental if it is still going through the
+ * process of stabilizing and is subject to change or removal.
+ *
+ * See also:
+ *
+ * * [W3C recommendation](http://en.wikipedia.org/wiki/W3C_recommendation)
+ */
+class Experimental {
+  const Experimental();
+}
+
+/**
+ * Annotation that specifies that a member is editable through generate files.
+ *
+ * This is used for API generation.
+ *
+ * [name] should be formatted as `interface.member`.
+ */
+class DomName {
+  final String name;
+  const DomName(this.name);
+}
+
+/**
+ * Metadata that specifies that that member is editable through generated
+ * files.
+ */
+class DocsEditable {
+  const DocsEditable();
+}
+
+/**
+ * Annotation that indicates that an API is not expected to change but has
+ * not undergone enough testing to be considered stable.
+ */
+class Unstable {
+  const Unstable();
+}
diff --git a/sdk_nnbd/lib/indexed_db/dart2js/indexed_db_dart2js.dart b/sdk_nnbd/lib/indexed_db/dart2js/indexed_db_dart2js.dart
new file mode 100644
index 0000000..b664b7d
--- /dev/null
+++ b/sdk_nnbd/lib/indexed_db/dart2js/indexed_db_dart2js.dart
@@ -0,0 +1,1295 @@
+/**
+ * A client-side key-value store with support for indexes.
+ *
+ * Many browsers support IndexedDB&mdash;a web standard for
+ * an indexed database.
+ * By storing data on the client in an IndexedDB,
+ * a web app gets some advantages, such as faster performance and persistence.
+ * To find out which browsers support IndexedDB,
+ * refer to [Can I Use?](http://caniuse.com/#feat=indexeddb)
+ *
+ * In IndexedDB, each record is identified by a unique index or key,
+ * making data retrieval speedy.
+ * You can store structured data,
+ * such as images, arrays, and maps using IndexedDB.
+ * The standard does not specify size limits for individual data items
+ * or for the database itself, but browsers may impose storage limits.
+ *
+ * ## Using indexed_db
+ *
+ * The classes in this library provide an interface
+ * to the browser's IndexedDB, if it has one.
+ * To use this library in your code:
+ *
+ *     import 'dart:indexed_db';
+ *
+ * A web app can determine if the browser supports
+ * IndexedDB with [IdbFactory.supported]:
+ *
+ *     if (IdbFactory.supported)
+ *       // Use indexeddb.
+ *     else
+ *       // Find an alternative.
+ *
+ * Access to the browser's IndexedDB is provided by the app's top-level
+ * [Window] object, which your code can refer to with `window.indexedDB`.
+ * So, for example,
+ * here's how to use window.indexedDB to open a database:
+ *
+ *     Future open() {
+ *       return window.indexedDB.open('myIndexedDB',
+ *           version: 1,
+ *           onUpgradeNeeded: _initializeDatabase)
+ *         .then(_loadFromDB);
+ *     }
+ *     void _initializeDatabase(VersionChangeEvent e) {
+ *       ...
+ *     }
+ *     Future _loadFromDB(Database db) {
+ *       ...
+ *     }
+ *
+ *
+ * All data in an IndexedDB is stored within an [ObjectStore].
+ * To manipulate the database use [Transaction]s.
+ *
+ * ## Other resources
+ *
+ * Other options for client-side data storage include:
+ *
+ * * [Window.localStorage]&mdash;a
+ * basic mechanism that stores data as a [Map],
+ * and where both the keys and the values are strings.
+ *
+ * * [dart:web_sql]&mdash;a database that can be queried with SQL.
+ * 
+ * For a tutorial about using the indexed_db library with Dart,
+ * check out
+ * [Use IndexedDB](http://www.dartlang.org/docs/tutorials/indexeddb/).
+ *
+ * MDN provides [API
+ * documentation](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API).
+ *
+ * {@category Web}
+ */
+library dart.dom.indexed_db;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:html_common';
+import 'dart:_native_typed_data';
+import 'dart:typed_data';
+import 'dart:_js_helper' show Creates, Returns, JSName, Native;
+import 'dart:_foreign_helper' show JS;
+import 'dart:_interceptors' show Interceptor, JSExtendableArray;
+import 'dart:_js_helper' show convertDartClosureToJS;
+// Copyright (c) 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.
+
+// DO NOT EDIT - unless you are editing documentation as per:
+// https://code.google.com/p/dart/wiki/ContributingHTMLDocumentation
+// Auto-generated dart:svg library.
+
+class _KeyRangeFactoryProvider {
+  static KeyRange createKeyRange_only(/*Key*/ value) =>
+      _only(_class(), _translateKey(value));
+
+  static KeyRange createKeyRange_lowerBound(
+          /*Key*/ bound,
+          [bool open = false]) =>
+      _lowerBound(_class(), _translateKey(bound), open);
+
+  static KeyRange createKeyRange_upperBound(
+          /*Key*/ bound,
+          [bool open = false]) =>
+      _upperBound(_class(), _translateKey(bound), open);
+
+  static KeyRange createKeyRange_bound(/*Key*/ lower, /*Key*/ upper,
+          [bool lowerOpen = false, bool upperOpen = false]) =>
+      _bound(_class(), _translateKey(lower), _translateKey(upper), lowerOpen,
+          upperOpen);
+
+  static var _cachedClass;
+
+  static _class() {
+    if (_cachedClass != null) return _cachedClass;
+    return _cachedClass = _uncachedClass();
+  }
+
+  static _uncachedClass() =>
+      JS('var', '''window.webkitIDBKeyRange || window.mozIDBKeyRange ||
+          window.msIDBKeyRange || window.IDBKeyRange''');
+
+  static _translateKey(idbkey) => idbkey; // TODO: fixme.
+
+  static KeyRange _only(cls, value) => JS('KeyRange', '#.only(#)', cls, value);
+
+  static KeyRange _lowerBound(cls, bound, open) =>
+      JS('KeyRange', '#.lowerBound(#, #)', cls, bound, open);
+
+  static KeyRange _upperBound(cls, bound, open) =>
+      JS('KeyRange', '#.upperBound(#, #)', cls, bound, open);
+
+  static KeyRange _bound(cls, lower, upper, lowerOpen, upperOpen) => JS(
+      'KeyRange',
+      '#.bound(#, #, #, #)',
+      cls,
+      lower,
+      upper,
+      lowerOpen,
+      upperOpen);
+}
+
+// Conversions for IDBKey.
+//
+// Per http://www.w3.org/TR/IndexedDB/#key-construct
+//
+// "A value is said to be a valid key if it is one of the following types: Array
+// JavaScript objects [ECMA-262], DOMString [WEBIDL], Date [ECMA-262] or float
+// [WEBIDL]. However Arrays are only valid keys if every item in the array is
+// defined and is a valid key (i.e. sparse arrays can not be valid keys) and if
+// the Array doesn't directly or indirectly contain itself. Any non-numeric
+// properties are ignored, and thus does not affect whether the Array is a valid
+// key. Additionally, if the value is of type float, it is only a valid key if
+// it is not NaN, and if the value is of type Date it is only a valid key if its
+// [[PrimitiveValue]] internal property, as defined by [ECMA-262], is not NaN."
+
+// What is required is to ensure that an Lists in the key are actually
+// JavaScript arrays, and any Dates are JavaScript Dates.
+
+/**
+ * Converts a native IDBKey into a Dart object.
+ *
+ * May return the original input.  May mutate the original input (but will be
+ * idempotent if mutation occurs).  It is assumed that this conversion happens
+ * on native IDBKeys on all paths that return IDBKeys from native DOM calls.
+ *
+ * If necessary, JavaScript Dates are converted into Dart Dates.
+ */
+_convertNativeToDart_IDBKey(nativeKey) {
+  containsDate(object) {
+    if (isJavaScriptDate(object)) return true;
+    if (object is List) {
+      for (int i = 0; i < object.length; i++) {
+        if (containsDate(object[i])) return true;
+      }
+    }
+    return false; // number, string.
+  }
+
+  if (containsDate(nativeKey)) {
+    throw new UnimplementedError('Key containing DateTime');
+  }
+  // TODO: Cache conversion somewhere?
+  return nativeKey;
+}
+
+/**
+ * Converts a Dart object into a valid IDBKey.
+ *
+ * May return the original input.  Does not mutate input.
+ *
+ * If necessary, [dartKey] may be copied to ensure all lists are converted into
+ * JavaScript Arrays and Dart Dates into JavaScript Dates.
+ */
+_convertDartToNative_IDBKey(dartKey) {
+  // TODO: Implement.
+  return dartKey;
+}
+
+/// May modify original.  If so, action is idempotent.
+_convertNativeToDart_IDBAny(object) {
+  return convertNativeToDart_AcceptStructuredClone(object, mustCopy: false);
+}
+
+// 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
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("IDBCursor")
+class Cursor extends Interceptor {
+  Future delete() {
+    try {
+      return _completeRequest(_delete());
+    } catch (e, stacktrace) {
+      return new Future.error(e, stacktrace);
+    }
+  }
+
+  Future update(value) {
+    try {
+      return _completeRequest(_update(value));
+    } catch (e, stacktrace) {
+      return new Future.error(e, stacktrace);
+    }
+  }
+
+  @JSName('continue')
+  void next([Object key]) {
+    if (key == null) {
+      JS('void', '#.continue()', this);
+    } else {
+      JS('void', '#.continue(#)', this, key);
+    }
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory Cursor._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String direction;
+
+  @_annotation_Creates_IDBKey
+  @_annotation_Returns_IDBKey
+  final Object key;
+
+  @_annotation_Creates_IDBKey
+  @_annotation_Returns_IDBKey
+  final Object primaryKey;
+
+  @Creates('Null')
+  @Returns('ObjectStore|Index|Null')
+  final Object source;
+
+  void advance(int count) native;
+
+  void continuePrimaryKey(Object key, Object primaryKey) native;
+
+  @JSName('delete')
+  Request _delete() native;
+
+  Request _update(/*any*/ value) {
+    var value_1 = convertDartToNative_SerializedScriptValue(value);
+    return _update_1(value_1);
+  }
+
+  @JSName('update')
+  Request _update_1(value) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("IDBCursorWithValue")
+class CursorWithValue extends Cursor {
+  // To suppress missing implicit constructor warnings.
+  factory CursorWithValue._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  dynamic get value => _convertNativeToDart_IDBAny(this._get_value);
+  @JSName('value')
+  @annotation_Creates_SerializedScriptValue
+  @annotation_Returns_SerializedScriptValue
+  final dynamic _get_value;
+}
+// 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.
+
+/**
+ * An indexed database object for storing client-side data
+ * in web apps.
+ */
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX, '15')
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@Unstable()
+@Native("IDBDatabase")
+class Database extends EventTarget {
+  ObjectStore createObjectStore(String name, {keyPath, bool autoIncrement}) {
+    var options = {};
+    if (keyPath != null) {
+      options['keyPath'] = keyPath;
+    }
+    if (autoIncrement != null) {
+      options['autoIncrement'] = autoIncrement;
+    }
+
+    return _createObjectStore(name, options);
+  }
+
+  Transaction transaction(storeName_OR_storeNames, String mode) {
+    if (mode != 'readonly' && mode != 'readwrite') {
+      throw new ArgumentError(mode);
+    }
+
+    // TODO(sra): Ensure storeName_OR_storeNames is a string or List<String>,
+    // and copy to JavaScript array if necessary.
+
+    // Try and create a transaction with a string mode.  Browsers that expect a
+    // numeric mode tend to convert the string into a number.  This fails
+    // silently, resulting in zero ('readonly').
+    return _transaction(storeName_OR_storeNames, mode);
+  }
+
+  Transaction transactionStore(String storeName, String mode) {
+    if (mode != 'readonly' && mode != 'readwrite') {
+      throw new ArgumentError(mode);
+    }
+    // Try and create a transaction with a string mode.  Browsers that expect a
+    // numeric mode tend to convert the string into a number.  This fails
+    // silently, resulting in zero ('readonly').
+    return _transaction(storeName, mode);
+  }
+
+  Transaction transactionList(List<String> storeNames, String mode) {
+    if (mode != 'readonly' && mode != 'readwrite') {
+      throw new ArgumentError(mode);
+    }
+    List storeNames_1 = convertDartToNative_StringArray(storeNames);
+    return _transaction(storeNames_1, mode);
+  }
+
+  Transaction transactionStores(DomStringList storeNames, String mode) {
+    if (mode != 'readonly' && mode != 'readwrite') {
+      throw new ArgumentError(mode);
+    }
+    return _transaction(storeNames, mode);
+  }
+
+  @JSName('transaction')
+  Transaction _transaction(stores, mode) native;
+
+  // To suppress missing implicit constructor warnings.
+  factory Database._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `abort` events to event
+   * handlers that are not necessarily instances of [Database].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> abortEvent =
+      const EventStreamProvider<Event>('abort');
+
+  /**
+   * Static factory designed to expose `close` events to event
+   * handlers that are not necessarily instances of [Database].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> closeEvent =
+      const EventStreamProvider<Event>('close');
+
+  /**
+   * Static factory designed to expose `error` events to event
+   * handlers that are not necessarily instances of [Database].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  /**
+   * Static factory designed to expose `versionchange` events to event
+   * handlers that are not necessarily instances of [Database].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<VersionChangeEvent> versionChangeEvent =
+      const EventStreamProvider<VersionChangeEvent>('versionchange');
+
+  final String name;
+
+  @Returns('DomStringList|Null')
+  @Creates('DomStringList')
+  final List<String> objectStoreNames;
+
+  @Creates('int|String|Null')
+  @Returns('int|String|Null')
+  final int version;
+
+  void close() native;
+
+  ObjectStore _createObjectStore(String name, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return _createObjectStore_1(name, options_1);
+    }
+    return _createObjectStore_2(name);
+  }
+
+  @JSName('createObjectStore')
+  ObjectStore _createObjectStore_1(name, options) native;
+  @JSName('createObjectStore')
+  ObjectStore _createObjectStore_2(name) native;
+
+  void deleteObjectStore(String name) native;
+
+  /// Stream of `abort` events handled by this [Database].
+  Stream<Event> get onAbort => abortEvent.forTarget(this);
+
+  /// Stream of `close` events handled by this [Database].
+  Stream<Event> get onClose => closeEvent.forTarget(this);
+
+  /// Stream of `error` events handled by this [Database].
+  Stream<Event> get onError => errorEvent.forTarget(this);
+
+  /// Stream of `versionchange` events handled by this [Database].
+  Stream<VersionChangeEvent> get onVersionChange =>
+      versionChangeEvent.forTarget(this);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void ObserverCallback(ObserverChanges changes);
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX, '15')
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@Unstable()
+@Native("IDBFactory")
+class IdbFactory extends Interceptor {
+  /**
+   * Checks to see if Indexed DB is supported on the current platform.
+   */
+  static bool get supported {
+    return JS(
+        'bool',
+        '!!(window.indexedDB || '
+            'window.webkitIndexedDB || '
+            'window.mozIndexedDB)');
+  }
+
+  Future<Database> open(String name,
+      {int version,
+      void onUpgradeNeeded(VersionChangeEvent event),
+      void onBlocked(Event event)}) {
+    if ((version == null) != (onUpgradeNeeded == null)) {
+      return new Future.error(new ArgumentError(
+          'version and onUpgradeNeeded must be specified together'));
+    }
+    try {
+      var request;
+      if (version != null) {
+        request = _open(name, version);
+      } else {
+        request = _open(name);
+      }
+
+      if (onUpgradeNeeded != null) {
+        request.onUpgradeNeeded.listen(onUpgradeNeeded);
+      }
+      if (onBlocked != null) {
+        request.onBlocked.listen(onBlocked);
+      }
+      return _completeRequest(request);
+    } catch (e, stacktrace) {
+      return new Future.error(e, stacktrace);
+    }
+  }
+
+  Future<IdbFactory> deleteDatabase(String name, {void onBlocked(Event e)}) {
+    try {
+      var request = _deleteDatabase(name);
+
+      if (onBlocked != null) {
+        request.onBlocked.listen(onBlocked);
+      }
+      var completer = new Completer<IdbFactory>.sync();
+      request.onSuccess.listen((e) {
+        completer.complete(this);
+      });
+      request.onError.listen(completer.completeError);
+      return completer.future;
+    } catch (e, stacktrace) {
+      return new Future.error(e, stacktrace);
+    }
+  }
+
+  /**
+   * Checks to see if getDatabaseNames is supported by the current platform.
+   * TODO(terry): Should be able to always return false?
+   */
+  bool get supportsDatabaseNames {
+    return supported &&
+        JS('bool', '!!(#.getDatabaseNames || #.webkitGetDatabaseNames)', this,
+            this);
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory IdbFactory._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int cmp(Object first, Object second) native;
+
+  @JSName('deleteDatabase')
+  OpenDBRequest _deleteDatabase(String name) native;
+
+  @JSName('open')
+  @Returns('Request')
+  @Creates('Request')
+  @Creates('Database')
+  OpenDBRequest _open(String name, [int version]) native;
+}
+
+/**
+ * Ties a request to a completer, so the completer is completed when it succeeds
+ * and errors out when the request errors.
+ */
+Future<T> _completeRequest<T>(Request request) {
+  var completer = new Completer<T>.sync();
+  // TODO: make sure that completer.complete is synchronous as transactions
+  // may be committed if the result is not processed immediately.
+  request.onSuccess.listen((e) {
+    T result = request.result;
+    completer.complete(result);
+  });
+  request.onError.listen(completer.completeError);
+  return completer.future;
+}
+// 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.
+
+@Unstable()
+@Native("IDBIndex")
+class Index extends Interceptor {
+  Future<int> count([key_OR_range]) {
+    try {
+      var request = _count(key_OR_range);
+      return _completeRequest(request);
+    } catch (e, stacktrace) {
+      return new Future.error(e, stacktrace);
+    }
+  }
+
+  Future get(key) {
+    try {
+      var request = _get(key);
+
+      return _completeRequest(request);
+    } catch (e, stacktrace) {
+      return new Future.error(e, stacktrace);
+    }
+  }
+
+  Future getKey(key) {
+    try {
+      var request = _getKey(key);
+
+      return _completeRequest(request);
+    } catch (e, stacktrace) {
+      return new Future.error(e, stacktrace);
+    }
+  }
+
+  /**
+   * Creates a stream of cursors over the records in this object store.
+   *
+   * See also:
+   *
+   * * [ObjectStore.openCursor]
+   */
+  Stream<CursorWithValue> openCursor(
+      {key, KeyRange range, String direction, bool autoAdvance}) {
+    var key_OR_range = null;
+    if (key != null) {
+      if (range != null) {
+        throw new ArgumentError('Cannot specify both key and range.');
+      }
+      key_OR_range = key;
+    } else {
+      key_OR_range = range;
+    }
+    var request;
+    if (direction == null) {
+      // FIXME: Passing in "next" should be unnecessary.
+      request = _openCursor(key_OR_range, "next");
+    } else {
+      request = _openCursor(key_OR_range, direction);
+    }
+    return ObjectStore._cursorStreamFromResult(request, autoAdvance);
+  }
+
+  /**
+   * Creates a stream of cursors over the records in this object store.
+   *
+   * See also:
+   *
+   * * [ObjectStore.openCursor]
+   */
+  Stream<Cursor> openKeyCursor(
+      {key, KeyRange range, String direction, bool autoAdvance}) {
+    var key_OR_range = null;
+    if (key != null) {
+      if (range != null) {
+        throw new ArgumentError('Cannot specify both key and range.');
+      }
+      key_OR_range = key;
+    } else {
+      key_OR_range = range;
+    }
+    var request;
+    if (direction == null) {
+      // FIXME: Passing in "next" should be unnecessary.
+      request = _openKeyCursor(key_OR_range, "next");
+    } else {
+      request = _openKeyCursor(key_OR_range, direction);
+    }
+    return ObjectStore._cursorStreamFromResult(request, autoAdvance);
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory Index._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @annotation_Creates_SerializedScriptValue
+  final Object keyPath;
+
+  final bool multiEntry;
+
+  String name;
+
+  final ObjectStore objectStore;
+
+  final bool unique;
+
+  @JSName('count')
+  Request _count(Object key) native;
+
+  @JSName('get')
+  @Returns('Request')
+  @Creates('Request')
+  @annotation_Creates_SerializedScriptValue
+  Request _get(Object key) native;
+
+  Request getAll(Object query, [int count]) native;
+
+  Request getAllKeys(Object query, [int count]) native;
+
+  @JSName('getKey')
+  @Returns('Request')
+  @Creates('Request')
+  @annotation_Creates_SerializedScriptValue
+  @Creates('ObjectStore')
+  Request _getKey(Object key) native;
+
+  @JSName('openCursor')
+  @Returns('Request')
+  @Creates('Request')
+  @Creates('Cursor')
+  Request _openCursor(Object range, [String direction]) native;
+
+  @JSName('openKeyCursor')
+  @Returns('Request')
+  @Creates('Request')
+  @Creates('Cursor')
+  Request _openKeyCursor(Object range, [String direction]) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("IDBKeyRange")
+class KeyRange extends Interceptor {
+  factory KeyRange.only(/*Key*/ value) =>
+      _KeyRangeFactoryProvider.createKeyRange_only(value);
+
+  factory KeyRange.lowerBound(/*Key*/ bound, [bool open = false]) =>
+      _KeyRangeFactoryProvider.createKeyRange_lowerBound(bound, open);
+
+  factory KeyRange.upperBound(/*Key*/ bound, [bool open = false]) =>
+      _KeyRangeFactoryProvider.createKeyRange_upperBound(bound, open);
+
+  factory KeyRange.bound(/*Key*/ lower, /*Key*/ upper,
+          [bool lowerOpen = false, bool upperOpen = false]) =>
+      _KeyRangeFactoryProvider.createKeyRange_bound(
+          lower, upper, lowerOpen, upperOpen);
+
+  // To suppress missing implicit constructor warnings.
+  factory KeyRange._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @annotation_Creates_SerializedScriptValue
+  final Object lower;
+
+  final bool lowerOpen;
+
+  @annotation_Creates_SerializedScriptValue
+  final Object upper;
+
+  final bool upperOpen;
+
+  @JSName('bound')
+  static KeyRange bound_(Object lower, Object upper,
+      [bool lowerOpen, bool upperOpen]) native;
+
+  bool includes(Object key) native;
+
+  @JSName('lowerBound')
+  static KeyRange lowerBound_(Object bound, [bool open]) native;
+
+  @JSName('only')
+  static KeyRange only_(Object value) native;
+
+  @JSName('upperBound')
+  static KeyRange upperBound_(Object bound, [bool open]) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("IDBObjectStore")
+class ObjectStore extends Interceptor {
+  Future add(value, [key]) {
+    try {
+      var request;
+      if (key != null) {
+        request = _add(value, key);
+      } else {
+        request = _add(value);
+      }
+      return _completeRequest(request);
+    } catch (e, stacktrace) {
+      return new Future.error(e, stacktrace);
+    }
+  }
+
+  Future clear() {
+    try {
+      return _completeRequest(_clear());
+    } catch (e, stacktrace) {
+      return new Future.error(e, stacktrace);
+    }
+  }
+
+  Future delete(key_OR_keyRange) {
+    try {
+      return _completeRequest(_delete(key_OR_keyRange));
+    } catch (e, stacktrace) {
+      return new Future.error(e, stacktrace);
+    }
+  }
+
+  Future<int> count([key_OR_range]) {
+    try {
+      var request = _count(key_OR_range);
+      return _completeRequest(request);
+    } catch (e, stacktrace) {
+      return new Future.error(e, stacktrace);
+    }
+  }
+
+  Future put(value, [key]) {
+    try {
+      var request;
+      if (key != null) {
+        request = _put(value, key);
+      } else {
+        request = _put(value);
+      }
+      return _completeRequest(request);
+    } catch (e, stacktrace) {
+      return new Future.error(e, stacktrace);
+    }
+  }
+
+  Future getObject(key) {
+    try {
+      var request = _get(key);
+
+      return _completeRequest(request);
+    } catch (e, stacktrace) {
+      return new Future.error(e, stacktrace);
+    }
+  }
+
+  /**
+   * Creates a stream of cursors over the records in this object store.
+   *
+   * **The stream must be manually advanced by calling [Cursor.next] after
+   * each item or by specifying autoAdvance to be true.**
+   *
+   *     var cursors = objectStore.openCursor().listen(
+   *       (cursor) {
+   *         // ...some processing with the cursor
+   *         cursor.next(); // advance onto the next cursor.
+   *       },
+   *       onDone: () {
+   *         // called when there are no more cursors.
+   *         print('all done!');
+   *       });
+   *
+   * Asynchronous operations which are not related to the current transaction
+   * will cause the transaction to automatically be committed-- all processing
+   * must be done synchronously unless they are additional async requests to
+   * the current transaction.
+   */
+  Stream<CursorWithValue> openCursor(
+      {key, KeyRange range, String direction, bool autoAdvance}) {
+    var key_OR_range = null;
+    if (key != null) {
+      if (range != null) {
+        throw new ArgumentError('Cannot specify both key and range.');
+      }
+      key_OR_range = key;
+    } else {
+      key_OR_range = range;
+    }
+
+    // TODO: try/catch this and return a stream with an immediate error.
+    var request;
+    if (direction == null) {
+      request = _openCursor(key_OR_range);
+    } else {
+      request = _openCursor(key_OR_range, direction);
+    }
+    return _cursorStreamFromResult(request, autoAdvance);
+  }
+
+  Index createIndex(String name, keyPath, {bool unique, bool multiEntry}) {
+    var options = {};
+    if (unique != null) {
+      options['unique'] = unique;
+    }
+    if (multiEntry != null) {
+      options['multiEntry'] = multiEntry;
+    }
+
+    return _createIndex(name, keyPath, options);
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory ObjectStore._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool autoIncrement;
+
+  @Returns('DomStringList|Null')
+  @Creates('DomStringList')
+  final List<String> indexNames;
+
+  @annotation_Creates_SerializedScriptValue
+  final Object keyPath;
+
+  String name;
+
+  final Transaction transaction;
+
+  @Returns('Request')
+  @Creates('Request')
+  @_annotation_Creates_IDBKey
+  Request _add(/*any*/ value, [/*any*/ key]) {
+    if (key != null) {
+      var value_1 = convertDartToNative_SerializedScriptValue(value);
+      var key_2 = convertDartToNative_SerializedScriptValue(key);
+      return _add_1(value_1, key_2);
+    }
+    var value_1 = convertDartToNative_SerializedScriptValue(value);
+    return _add_2(value_1);
+  }
+
+  @JSName('add')
+  @Returns('Request')
+  @Creates('Request')
+  @_annotation_Creates_IDBKey
+  Request _add_1(value, key) native;
+  @JSName('add')
+  @Returns('Request')
+  @Creates('Request')
+  @_annotation_Creates_IDBKey
+  Request _add_2(value) native;
+
+  @JSName('clear')
+  Request _clear() native;
+
+  @JSName('count')
+  Request _count(Object key) native;
+
+  Index _createIndex(String name, Object keyPath, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return _createIndex_1(name, keyPath, options_1);
+    }
+    return _createIndex_2(name, keyPath);
+  }
+
+  @JSName('createIndex')
+  Index _createIndex_1(name, keyPath, options) native;
+  @JSName('createIndex')
+  Index _createIndex_2(name, keyPath) native;
+
+  @JSName('delete')
+  Request _delete(Object key) native;
+
+  void deleteIndex(String name) native;
+
+  @JSName('get')
+  @Returns('Request')
+  @Creates('Request')
+  @annotation_Creates_SerializedScriptValue
+  Request _get(Object key) native;
+
+  Request getAll(Object query, [int count]) native;
+
+  Request getAllKeys(Object query, [int count]) native;
+
+  Request getKey(Object key) native;
+
+  Index index(String name) native;
+
+  @JSName('openCursor')
+  @Returns('Request')
+  @Creates('Request')
+  @Creates('Cursor')
+  Request _openCursor(Object range, [String direction]) native;
+
+  Request openKeyCursor(Object range, [String direction]) native;
+
+  @Returns('Request')
+  @Creates('Request')
+  @_annotation_Creates_IDBKey
+  Request _put(/*any*/ value, [/*any*/ key]) {
+    if (key != null) {
+      var value_1 = convertDartToNative_SerializedScriptValue(value);
+      var key_2 = convertDartToNative_SerializedScriptValue(key);
+      return _put_1(value_1, key_2);
+    }
+    var value_1 = convertDartToNative_SerializedScriptValue(value);
+    return _put_2(value_1);
+  }
+
+  @JSName('put')
+  @Returns('Request')
+  @Creates('Request')
+  @_annotation_Creates_IDBKey
+  Request _put_1(value, key) native;
+  @JSName('put')
+  @Returns('Request')
+  @Creates('Request')
+  @_annotation_Creates_IDBKey
+  Request _put_2(value) native;
+
+  /**
+   * Helper for iterating over cursors in a request.
+   */
+  static Stream<T> _cursorStreamFromResult<T extends Cursor>(
+      Request request, bool autoAdvance) {
+    // TODO: need to guarantee that the controller provides the values
+    // immediately as waiting until the next tick will cause the transaction to
+    // close.
+    var controller = new StreamController<T>(sync: true);
+
+    //TODO: Report stacktrace once issue 4061 is resolved.
+    request.onError.listen(controller.addError);
+
+    request.onSuccess.listen((e) {
+      T cursor = request.result as dynamic;
+      if (cursor == null) {
+        controller.close();
+      } else {
+        controller.add(cursor);
+        if (autoAdvance == true && controller.hasListener) {
+          cursor.next();
+        }
+      }
+    });
+    return controller.stream;
+  }
+}
+// Copyright (c) 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.
+
+@Native("IDBObservation")
+class Observation extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Observation._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final Object key;
+
+  final String type;
+
+  final Object value;
+}
+// Copyright (c) 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.
+
+@Native("IDBObserver")
+class Observer extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Observer._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory Observer(ObserverCallback callback) {
+    var callback_1 = convertDartClosureToJS(callback, 1);
+    return Observer._create_1(callback_1);
+  }
+  static Observer _create_1(callback) =>
+      JS('Observer', 'new IDBObserver(#)', callback);
+
+  void observe(Database db, Transaction tx, Map options) {
+    var options_1 = convertDartToNative_Dictionary(options);
+    _observe_1(db, tx, options_1);
+    return;
+  }
+
+  @JSName('observe')
+  void _observe_1(Database db, Transaction tx, options) native;
+
+  void unobserve(Database db) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("IDBObserverChanges")
+class ObserverChanges extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ObserverChanges._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final Database database;
+
+  final Object records;
+
+  final Transaction transaction;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("IDBOpenDBRequest,IDBVersionChangeRequest")
+class OpenDBRequest extends Request {
+  // To suppress missing implicit constructor warnings.
+  factory OpenDBRequest._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `blocked` events to event
+   * handlers that are not necessarily instances of [OpenDBRequest].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> blockedEvent =
+      const EventStreamProvider<Event>('blocked');
+
+  /**
+   * Static factory designed to expose `upgradeneeded` events to event
+   * handlers that are not necessarily instances of [OpenDBRequest].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<VersionChangeEvent> upgradeNeededEvent =
+      const EventStreamProvider<VersionChangeEvent>('upgradeneeded');
+
+  /// Stream of `blocked` events handled by this [OpenDBRequest].
+  Stream<Event> get onBlocked => blockedEvent.forTarget(this);
+
+  /// Stream of `upgradeneeded` events handled by this [OpenDBRequest].
+  Stream<VersionChangeEvent> get onUpgradeNeeded =>
+      upgradeNeededEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("IDBRequest")
+class Request extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory Request._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `error` events to event
+   * handlers that are not necessarily instances of [Request].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  /**
+   * Static factory designed to expose `success` events to event
+   * handlers that are not necessarily instances of [Request].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> successEvent =
+      const EventStreamProvider<Event>('success');
+
+  final DomException error;
+
+  final String readyState;
+
+  dynamic get result => _convertNativeToDart_IDBAny(this._get_result);
+  @JSName('result')
+  @Creates('Null')
+  final dynamic _get_result;
+
+  @Creates('Null')
+  final Object source;
+
+  final Transaction transaction;
+
+  /// Stream of `error` events handled by this [Request].
+  Stream<Event> get onError => errorEvent.forTarget(this);
+
+  /// Stream of `success` events handled by this [Request].
+  Stream<Event> get onSuccess => successEvent.forTarget(this);
+}
+// 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.
+
+@Unstable()
+@Native("IDBTransaction")
+class Transaction extends EventTarget {
+  /**
+   * Provides a Future which will be completed once the transaction has
+   * completed.
+   *
+   * The future will error if an error occurrs on the transaction or if the
+   * transaction is aborted.
+   */
+  Future<Database> get completed {
+    var completer = new Completer<Database>();
+
+    this.onComplete.first.then((_) {
+      completer.complete(db);
+    });
+
+    this.onError.first.then((e) {
+      completer.completeError(e);
+    });
+
+    this.onAbort.first.then((e) {
+      // Avoid completing twice if an error occurs.
+      if (!completer.isCompleted) {
+        completer.completeError(e);
+      }
+    });
+
+    return completer.future;
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory Transaction._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `abort` events to event
+   * handlers that are not necessarily instances of [Transaction].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> abortEvent =
+      const EventStreamProvider<Event>('abort');
+
+  /**
+   * Static factory designed to expose `complete` events to event
+   * handlers that are not necessarily instances of [Transaction].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> completeEvent =
+      const EventStreamProvider<Event>('complete');
+
+  /**
+   * Static factory designed to expose `error` events to event
+   * handlers that are not necessarily instances of [Transaction].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  final Database db;
+
+  final DomException error;
+
+  final String mode;
+
+  @Returns('DomStringList|Null')
+  @Creates('DomStringList')
+  final List<String> objectStoreNames;
+
+  void abort() native;
+
+  ObjectStore objectStore(String name) native;
+
+  /// Stream of `abort` events handled by this [Transaction].
+  Stream<Event> get onAbort => abortEvent.forTarget(this);
+
+  /// Stream of `complete` events handled by this [Transaction].
+  Stream<Event> get onComplete => completeEvent.forTarget(this);
+
+  /// Stream of `error` events handled by this [Transaction].
+  Stream<Event> get onError => errorEvent.forTarget(this);
+}
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("IDBVersionChangeEvent")
+class VersionChangeEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory VersionChangeEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory VersionChangeEvent(String type, [Map eventInitDict]) {
+    if (eventInitDict != null) {
+      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+      return VersionChangeEvent._create_1(type, eventInitDict_1);
+    }
+    return VersionChangeEvent._create_2(type);
+  }
+  static VersionChangeEvent _create_1(type, eventInitDict) => JS(
+      'VersionChangeEvent',
+      'new IDBVersionChangeEvent(#,#)',
+      type,
+      eventInitDict);
+  static VersionChangeEvent _create_2(type) =>
+      JS('VersionChangeEvent', 'new IDBVersionChangeEvent(#)', type);
+
+  final String dataLoss;
+
+  final String dataLossMessage;
+
+  @Creates('int|String|Null')
+  @Returns('int|String|Null')
+  final int newVersion;
+
+  @Creates('int|String|Null')
+  @Returns('int|String|Null')
+  final int oldVersion;
+
+  @JSName('target')
+  final OpenDBRequest target;
+}
diff --git a/sdk_nnbd/lib/internal/async_cast.dart b/sdk_nnbd/lib/internal/async_cast.dart
new file mode 100644
index 0000000..e041ff3
--- /dev/null
+++ b/sdk_nnbd/lib/internal/async_cast.dart
@@ -0,0 +1,121 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart._internal;
+
+// Casting wrappers for asynchronous classes.
+
+class CastStream<S, T> extends Stream<T> {
+  final Stream<S> _source;
+  CastStream(this._source);
+  bool get isBroadcast => _source.isBroadcast;
+
+  StreamSubscription<T> listen(void onData(T data),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    return new CastStreamSubscription<S, T>(
+        _source.listen(null, onDone: onDone, cancelOnError: cancelOnError))
+      ..onData(onData)
+      ..onError(onError);
+  }
+
+  Stream<R> cast<R>() => new CastStream<S, R>(_source);
+}
+
+class CastStreamSubscription<S, T> implements StreamSubscription<T> {
+  final StreamSubscription<S> _source;
+
+  /// Zone where listen was called.
+  final Zone _zone = Zone.current;
+
+  /// User's data handler. May be null.
+  void Function(T) _handleData;
+
+  /// Copy of _source's handleError so we can report errors in onData.
+  /// May be null.
+  Function _handleError;
+
+  CastStreamSubscription(this._source) {
+    _source.onData(_onData);
+  }
+
+  Future cancel() => _source.cancel();
+
+  void onData(void handleData(T data)) {
+    _handleData = handleData == null
+        ? null
+        : _zone.registerUnaryCallback<dynamic, T>(handleData);
+  }
+
+  void onError(Function handleError) {
+    _source.onError(handleError);
+    if (handleError == null) {
+      _handleError = null;
+    } else if (handleError is Function(Null, Null)) {
+      _handleError = _zone
+          .registerBinaryCallback<dynamic, Object, StackTrace>(handleError);
+    } else {
+      _handleError = _zone.registerUnaryCallback<dynamic, Object>(handleError);
+    }
+  }
+
+  void onDone(void handleDone()) {
+    _source.onDone(handleDone);
+  }
+
+  void _onData(S data) {
+    if (_handleData == null) return;
+    T targetData;
+    try {
+      targetData = data as T;
+    } catch (error, stack) {
+      if (_handleError == null) {
+        _zone.handleUncaughtError(error, stack);
+      } else if (_handleError is Function(Null, Null)) {
+        _zone.runBinaryGuarded(_handleError, error, stack);
+      } else {
+        _zone.runUnaryGuarded(_handleError, error);
+      }
+      return;
+    }
+    _zone.runUnaryGuarded(_handleData, targetData);
+  }
+
+  void pause([Future resumeSignal]) {
+    _source.pause(resumeSignal);
+  }
+
+  void resume() {
+    _source.resume();
+  }
+
+  bool get isPaused => _source.isPaused;
+
+  Future<E> asFuture<E>([E futureValue]) => _source.asFuture<E>(futureValue);
+}
+
+class CastStreamTransformer<SS, ST, TS, TT>
+    extends StreamTransformerBase<TS, TT> {
+  final StreamTransformer<SS, ST> _source;
+  CastStreamTransformer(this._source);
+
+  StreamTransformer<RS, RT> cast<RS, RT>() =>
+      new CastStreamTransformer<SS, ST, RS, RT>(_source);
+  Stream<TT> bind(Stream<TS> stream) =>
+      _source.bind(stream.cast<SS>()).cast<TT>();
+}
+
+class CastConverter<SS, ST, TS, TT> extends Converter<TS, TT> {
+  final Converter<SS, ST> _source;
+  CastConverter(this._source);
+
+  TT convert(TS input) => _source.convert(input as SS) as TT;
+
+  // cast is inherited from Converter.
+
+  Stream<TT> bind(Stream<TS> stream) =>
+      _source.bind(stream.cast<SS>()).cast<TT>();
+
+  Converter<RS, RT> cast<RS, RT>() =>
+      new CastConverter<SS, ST, RS, RT>(_source);
+}
diff --git a/sdk_nnbd/lib/internal/cast.dart b/sdk_nnbd/lib/internal/cast.dart
new file mode 100644
index 0000000..b3620f5
--- /dev/null
+++ b/sdk_nnbd/lib/internal/cast.dart
@@ -0,0 +1,361 @@
+// Copyright (c) 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 dart._internal;
+
+// Casting wrappers for collection classes.
+
+abstract class _CastIterableBase<S, T> extends Iterable<T> {
+  Iterable<S> get _source;
+
+  Iterator<T> get iterator => new CastIterator<S, T>(_source.iterator);
+
+  // The following members use the default implementation on the
+  // throwing iterator. These are all operations that have no more efficient
+  // implementation than visiting every element in order,
+  // or that has no more efficient way to get the correct type (toList, toSet).
+  //
+  // * map
+  // * where
+  // * expand
+  // * forEach
+  // * reduce
+  // * fold
+  // * every
+  // * any
+  // * join
+  // * toList
+  // * toSet
+  // * skipWhile
+  // * takeWhile
+  // * firstWhere
+  // * singleWhere
+
+  int get length => _source.length;
+  bool get isEmpty => _source.isEmpty;
+  bool get isNotEmpty => _source.isNotEmpty;
+
+  Iterable<T> skip(int count) => new CastIterable<S, T>(_source.skip(count));
+  Iterable<T> take(int count) => new CastIterable<S, T>(_source.take(count));
+
+  T elementAt(int index) => _source.elementAt(index) as T;
+  T get first => _source.first as T;
+  T get last => _source.last as T;
+  T get single => _source.single as T;
+
+  bool contains(Object other) => _source.contains(other);
+
+  // Might be implemented by testing backwards from the end,
+  // so use the _source's implementation.
+  T lastWhere(bool test(T element), {T orElse()}) =>
+      _source.lastWhere((S element) => test(element as T),
+          orElse: (orElse == null) ? null : () => orElse() as S) as T;
+
+  String toString() => _source.toString();
+}
+
+class CastIterator<S, T> implements Iterator<T> {
+  Iterator<S> _source;
+  CastIterator(this._source);
+  bool moveNext() => _source.moveNext();
+  T get current => _source.current as T;
+}
+
+class CastIterable<S, T> extends _CastIterableBase<S, T> {
+  final Iterable<S> _source;
+
+  CastIterable._(this._source);
+
+  factory CastIterable(Iterable<S> source) {
+    if (source is EfficientLengthIterable<S>) {
+      return new _EfficientLengthCastIterable<S, T>(source);
+    }
+    return new CastIterable<S, T>._(source);
+  }
+
+  Iterable<R> cast<R>() => new CastIterable<S, R>(_source);
+}
+
+class _EfficientLengthCastIterable<S, T> extends CastIterable<S, T>
+    implements EfficientLengthIterable<T> {
+  _EfficientLengthCastIterable(EfficientLengthIterable<S> source)
+      : super._(source);
+}
+
+abstract class _CastListBase<S, T> extends _CastIterableBase<S, T>
+    with ListMixin<T> {
+  List<S> get _source;
+
+  // Using the default implementation from ListMixin:
+  // * reversed
+  // * shuffle
+  // * indexOf
+  // * lastIndexOf
+  // * clear
+  // * sublist
+  // * asMap
+
+  T operator [](int index) => _source[index] as T;
+
+  void operator []=(int index, T value) {
+    _source[index] = value as S;
+  }
+
+  void set length(int length) {
+    _source.length = length;
+  }
+
+  void add(T value) {
+    _source.add(value as S);
+  }
+
+  void addAll(Iterable<T> values) {
+    _source.addAll(new CastIterable<T, S>(values));
+  }
+
+  void sort([int compare(T v1, T v2)]) {
+    _source.sort(
+        compare == null ? null : (S v1, S v2) => compare(v1 as T, v2 as T));
+  }
+
+  void shuffle([Random random]) {
+    _source.shuffle(random);
+  }
+
+  void insert(int index, T element) {
+    _source.insert(index, element as S);
+  }
+
+  void insertAll(int index, Iterable<T> elements) {
+    _source.insertAll(index, new CastIterable<T, S>(elements));
+  }
+
+  void setAll(int index, Iterable<T> elements) {
+    _source.setAll(index, new CastIterable<T, S>(elements));
+  }
+
+  bool remove(Object value) => _source.remove(value);
+
+  T removeAt(int index) => _source.removeAt(index) as T;
+
+  T removeLast() => _source.removeLast() as T;
+
+  void removeWhere(bool test(T element)) {
+    _source.removeWhere((S element) => test(element as T));
+  }
+
+  void retainWhere(bool test(T element)) {
+    _source.retainWhere((S element) => test(element as T));
+  }
+
+  Iterable<T> getRange(int start, int end) =>
+      new CastIterable<S, T>(_source.getRange(start, end));
+
+  void setRange(int start, int end, Iterable<T> iterable, [int skipCount = 0]) {
+    _source.setRange(start, end, new CastIterable<T, S>(iterable), skipCount);
+  }
+
+  void removeRange(int start, int end) {
+    _source.removeRange(start, end);
+  }
+
+  void fillRange(int start, int end, [T fillValue]) {
+    _source.fillRange(start, end, fillValue as S);
+  }
+
+  void replaceRange(int start, int end, Iterable<T> replacement) {
+    _source.replaceRange(start, end, new CastIterable<T, S>(replacement));
+  }
+}
+
+class CastList<S, T> extends _CastListBase<S, T> {
+  final List<S> _source;
+  CastList(this._source);
+
+  List<R> cast<R>() => new CastList<S, R>(_source);
+}
+
+class CastSet<S, T> extends _CastIterableBase<S, T> implements Set<T> {
+  final Set<S> _source;
+
+  /// Creates a new empty set of the same *kind* as [_source],
+  /// but with `<R>` as type argument.
+  /// Used by [toSet] and [union].
+  final Set<R> Function<R>() _emptySet;
+
+  CastSet(this._source, this._emptySet);
+
+  static Set<R> _defaultEmptySet<R>() => new Set<R>();
+
+  Set<R> cast<R>() => new CastSet<S, R>(_source, _emptySet);
+  bool add(T value) => _source.add(value as S);
+
+  void addAll(Iterable<T> elements) {
+    _source.addAll(new CastIterable<T, S>(elements));
+  }
+
+  bool remove(Object object) => _source.remove(object);
+
+  void removeAll(Iterable<Object> objects) {
+    _source.removeAll(objects);
+  }
+
+  void retainAll(Iterable<Object> objects) {
+    _source.retainAll(objects);
+  }
+
+  void removeWhere(bool test(T element)) {
+    _source.removeWhere((S element) => test(element as T));
+  }
+
+  void retainWhere(bool test(T element)) {
+    _source.retainWhere((S element) => test(element as T));
+  }
+
+  bool containsAll(Iterable<Object> objects) => _source.containsAll(objects);
+
+  Set<T> intersection(Set<Object> other) {
+    if (_emptySet != null) return _conditionalAdd(other, true);
+    return new CastSet<S, T>(_source.intersection(other), null);
+  }
+
+  Set<T> difference(Set<Object> other) {
+    if (_emptySet != null) return _conditionalAdd(other, false);
+    return new CastSet<S, T>(_source.difference(other), null);
+  }
+
+  Set<T> _conditionalAdd(Set<Object> other, bool otherContains) {
+    Set<T> result = (_emptySet == null) ? new Set<T>() : _emptySet<T>();
+    for (var element in _source) {
+      T castElement = element as T;
+      if (otherContains == other.contains(castElement)) result.add(castElement);
+    }
+    return result;
+  }
+
+  Set<T> union(Set<T> other) => _clone()..addAll(other);
+
+  void clear() {
+    _source.clear();
+  }
+
+  Set<T> _clone() {
+    Set<T> result = (_emptySet == null) ? new Set<T>() : _emptySet<T>();
+    result.addAll(this);
+    return result;
+  }
+
+  Set<T> toSet() => _clone();
+
+  T lookup(Object key) => _source.lookup(key) as T;
+}
+
+class CastMap<SK, SV, K, V> extends MapBase<K, V> {
+  final Map<SK, SV> _source;
+
+  CastMap(this._source);
+
+  Map<RK, RV> cast<RK, RV>() => new CastMap<SK, SV, RK, RV>(_source);
+
+  bool containsValue(Object value) => _source.containsValue(value);
+
+  bool containsKey(Object key) => _source.containsKey(key);
+
+  V operator [](Object key) => _source[key] as V;
+
+  void operator []=(K key, V value) {
+    _source[key as SK] = value as SV;
+  }
+
+  V putIfAbsent(K key, V ifAbsent()) => _source.putIfAbsent(
+      key as SK, (ifAbsent == null) ? null : () => ifAbsent() as SV) as V;
+
+  void addAll(Map<K, V> other) {
+    _source.addAll(new CastMap<K, V, SK, SV>(other));
+  }
+
+  V remove(Object key) => _source.remove(key) as V;
+
+  void clear() {
+    _source.clear();
+  }
+
+  void forEach(void f(K key, V value)) {
+    _source.forEach((SK key, SV value) {
+      f(key as K, value as V);
+    });
+  }
+
+  Iterable<K> get keys => new CastIterable<SK, K>(_source.keys);
+
+  Iterable<V> get values => new CastIterable<SV, V>(_source.values);
+
+  int get length => _source.length;
+
+  bool get isEmpty => _source.isEmpty;
+
+  bool get isNotEmpty => _source.isNotEmpty;
+
+  V update(K key, V update(V value), {V ifAbsent()}) {
+    return _source.update(key as SK, (SV value) => update(value as V) as SV,
+        ifAbsent: (ifAbsent == null) ? null : () => ifAbsent() as SV) as V;
+  }
+
+  void updateAll(V update(K key, V value)) {
+    _source.updateAll((SK key, SV value) => update(key as K, value as V) as SV);
+  }
+
+  Iterable<MapEntry<K, V>> get entries {
+    return _source.entries.map<MapEntry<K, V>>(
+        (MapEntry<SK, SV> e) => new MapEntry<K, V>(e.key as K, e.value as V));
+  }
+
+  void addEntries(Iterable<MapEntry<K, V>> entries) {
+    for (var entry in entries) {
+      _source[entry.key as SK] = entry.value as SV;
+    }
+  }
+
+  void removeWhere(bool test(K key, V value)) {
+    _source.removeWhere((SK key, SV value) => test(key as K, value as V));
+  }
+}
+
+class CastQueue<S, T> extends _CastIterableBase<S, T> implements Queue<T> {
+  final Queue<S> _source;
+  CastQueue(this._source);
+  Queue<R> cast<R>() => new CastQueue<S, R>(_source);
+
+  T removeFirst() => _source.removeFirst() as T;
+  T removeLast() => _source.removeLast() as T;
+
+  void add(T value) {
+    _source.add(value as S);
+  }
+
+  void addFirst(T value) {
+    _source.addFirst(value as S);
+  }
+
+  void addLast(T value) {
+    _source.addLast(value as S);
+  }
+
+  bool remove(Object other) => _source.remove(other);
+  void addAll(Iterable<T> elements) {
+    _source.addAll(new CastIterable<T, S>(elements));
+  }
+
+  void removeWhere(bool test(T element)) {
+    _source.removeWhere((S element) => test(element as T));
+  }
+
+  void retainWhere(bool test(T element)) {
+    _source.retainWhere((S element) => test(element as T));
+  }
+
+  void clear() {
+    _source.clear();
+  }
+}
diff --git a/sdk_nnbd/lib/internal/internal.dart b/sdk_nnbd/lib/internal/internal.dart
new file mode 100644
index 0000000..11ee996
--- /dev/null
+++ b/sdk_nnbd/lib/internal/internal.dart
@@ -0,0 +1,382 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart._internal;
+
+import 'dart:collection';
+
+import 'dart:async'
+    show
+        Future,
+        Stream,
+        StreamSubscription,
+        StreamTransformer,
+        StreamTransformerBase,
+        Zone;
+import 'dart:convert' show Converter;
+import 'dart:core' hide Symbol;
+import 'dart:core' as core;
+import 'dart:math' show Random;
+
+part 'async_cast.dart';
+part 'cast.dart';
+part 'iterable.dart';
+part 'list.dart';
+part 'print.dart';
+part 'sort.dart';
+part 'symbol.dart';
+part 'linked_list.dart';
+
+// Powers of 10 up to 10^22 are representable as doubles.
+// Powers of 10 above that are only approximate due to lack of precission.
+// Used by double-parsing.
+const POWERS_OF_TEN = const [
+  1.0, // 0
+  10.0,
+  100.0,
+  1000.0,
+  10000.0,
+  100000.0, // 5
+  1000000.0,
+  10000000.0,
+  100000000.0,
+  1000000000.0,
+  10000000000.0, // 10
+  100000000000.0,
+  1000000000000.0,
+  10000000000000.0,
+  100000000000000.0,
+  1000000000000000.0, // 15
+  10000000000000000.0,
+  100000000000000000.0,
+  1000000000000000000.0,
+  10000000000000000000.0,
+  100000000000000000000.0, // 20
+  1000000000000000000000.0,
+  10000000000000000000000.0,
+];
+
+/**
+ * An [Iterable] of the UTF-16 code units of a [String] in index order.
+ */
+class CodeUnits extends UnmodifiableListBase<int> {
+  /** The string that this is the code units of. */
+  final String _string;
+
+  CodeUnits(this._string);
+
+  int get length => _string.length;
+  int operator [](int i) => _string.codeUnitAt(i);
+
+  static String stringOf(CodeUnits u) => u._string;
+}
+
+/// Marks a function or library as having an external implementation ("native"
+/// in the Dart VM).
+///
+/// On a function, this provides a backend-specific String that can be used to
+/// identify the function's implementation.
+///
+/// On a library, it provides a Uri that can be used to locate the native
+/// library's implementation.
+class ExternalName {
+  final String name;
+  const ExternalName(this.name);
+}
+
+// Shared hex-parsing utilities.
+
+/// Parses a single hex-digit as code unit.
+///
+/// Returns a negative value if the character is not a valid hex-digit.
+int hexDigitValue(int char) {
+  assert(char >= 0 && char <= 0xFFFF);
+  const int digit0 = 0x30;
+  const int a = 0x61;
+  const int f = 0x66;
+  int digit = char ^ digit0;
+  if (digit <= 9) return digit;
+  int letter = (char | 0x20);
+  if (a <= letter && letter <= f) return letter - (a - 10);
+  return -1;
+}
+
+/// Parses two hex digits in a string.
+///
+/// Returns a negative value if either digit isn't valid.
+int parseHexByte(String source, int index) {
+  assert(index + 2 <= source.length);
+  int digit1 = hexDigitValue(source.codeUnitAt(index));
+  int digit2 = hexDigitValue(source.codeUnitAt(index + 1));
+  return digit1 * 16 + digit2 - (digit2 & 256);
+}
+
+/// Given an [instance] of some generic type [T], and [extract], a first-class
+/// generic function that takes the same number of type parameters as [T],
+/// invokes the function with the same type arguments that were passed to T
+/// when [instance] was constructed.
+///
+/// Example:
+///
+/// ```dart
+/// class Two<A, B> {}
+///
+/// print(extractTypeArguments<List>(<int>[], <T>() => new Set<T>()));
+/// // Prints: Instance of 'Set<int>'.
+///
+/// print(extractTypeArguments<Map>(<String, bool>{},
+///     <T, S>() => new Two<T, S>));
+/// // Prints: Instance of 'Two<String, bool>'.
+/// ```
+///
+/// The type argument T is important to choose which specific type parameter
+/// list in [instance]'s type hierarchy is being extracted. Consider:
+///
+/// ```dart
+/// class A<T> {}
+/// class B<T> {}
+///
+/// class C implements A<int>, B<String> {}
+///
+/// main() {
+///   var c = new C();
+///   print(extractTypeArguments<A>(c, <T>() => <T>[]));
+///   // Prints: Instance of 'List<int>'.
+///
+///   print(extractTypeArguments<B>(c, <T>() => <T>[]));
+///   // Prints: Instance of 'List<String>'.
+/// }
+/// ```
+///
+/// A caller must not:
+///
+/// *   Pass `null` for [instance].
+/// *   Use a non-class type (i.e. a function type) for [T].
+/// *   Use a non-generic type for [T].
+/// *   Pass an instance of a generic type and a function that don't both take
+///     the same number of type arguments:
+///
+///     ```dart
+///     extractTypeArguments<List>(<int>[], <T, S>() => null);
+///     ```
+///
+/// See this issue for more context:
+/// https://github.com/dart-lang/sdk/issues/31371
+external Object extractTypeArguments<T>(T instance, Function extract);
+
+/// Annotation class marking the version where SDK API was added.
+///
+/// A `Since` annotation can be applied to a library declaration,
+/// any public declaration in a library, or in a class, or to
+/// an optional parameter.
+///
+/// It signifies that the export, member or parameter was *added* in
+/// that version.
+///
+/// When applied to a library declaration, it also a applies to
+/// all members declared or exported by that library.
+/// If applied to a class, it also applies to all members and constructors
+/// of that class.
+/// If applied to a class method, or parameter of such,
+/// any method implementing that interface method is also annotated.
+/// I multiple `Since` annotations apply to the same declaration or
+/// parameter, the latest version takes precendence.
+///
+/// Any use of a marked API may trigger a warning if the using code
+/// does not require an SDK version guaranteeing that the API is available,
+/// unless the API feature is also provided by something else.
+/// It is only a problem if an annotated feature is used, and the annotated
+/// API is the *only* thing providing the functionality.
+/// For example, using `Future` exported by `dart:core` is not a problem
+/// if the same library also imports `dart:async`, and using an optional
+/// parameter on an interface is not a problem if the same type also
+/// implements another interface providing the same parameter.
+///
+/// The version must be a semantic version (like `1.4.2` or `0.9.4-rec.4`),
+/// or the first two numbers of a semantic version (like `1.0` or `2.2`),
+/// representing a stable release, and equivalent to the semantic version
+/// you get by appending a `.0`.
+@Since("2.2")
+class Since {
+  final String version;
+  const Since(this.version);
+}
+
+/**
+ * HTTP status codes.  Exported in dart:io and dart:html.
+ */
+abstract class HttpStatus {
+  static const int continue_ = 100;
+  static const int switchingProtocols = 101;
+  @Since("2.1")
+  static const int processing = 102;
+  static const int ok = 200;
+  static const int created = 201;
+  static const int accepted = 202;
+  static const int nonAuthoritativeInformation = 203;
+  static const int noContent = 204;
+  static const int resetContent = 205;
+  static const int partialContent = 206;
+  @Since("2.1")
+  static const int multiStatus = 207;
+  @Since("2.1")
+  static const int alreadyReported = 208;
+  @Since("2.1")
+  static const int imUsed = 226;
+  static const int multipleChoices = 300;
+  static const int movedPermanently = 301;
+  static const int found = 302;
+  static const int movedTemporarily = 302; // Common alias for found.
+  static const int seeOther = 303;
+  static const int notModified = 304;
+  static const int useProxy = 305;
+  static const int temporaryRedirect = 307;
+  @Since("2.1")
+  static const int permanentRedirect = 308;
+  static const int badRequest = 400;
+  static const int unauthorized = 401;
+  static const int paymentRequired = 402;
+  static const int forbidden = 403;
+  static const int notFound = 404;
+  static const int methodNotAllowed = 405;
+  static const int notAcceptable = 406;
+  static const int proxyAuthenticationRequired = 407;
+  static const int requestTimeout = 408;
+  static const int conflict = 409;
+  static const int gone = 410;
+  static const int lengthRequired = 411;
+  static const int preconditionFailed = 412;
+  static const int requestEntityTooLarge = 413;
+  static const int requestUriTooLong = 414;
+  static const int unsupportedMediaType = 415;
+  static const int requestedRangeNotSatisfiable = 416;
+  static const int expectationFailed = 417;
+  @Since("2.1")
+  static const int misdirectedRequest = 421;
+  @Since("2.1")
+  static const int unprocessableEntity = 422;
+  @Since("2.1")
+  static const int locked = 423;
+  @Since("2.1")
+  static const int failedDependency = 424;
+  static const int upgradeRequired = 426;
+  @Since("2.1")
+  static const int preconditionRequired = 428;
+  @Since("2.1")
+  static const int tooManyRequests = 429;
+  @Since("2.1")
+  static const int requestHeaderFieldsTooLarge = 431;
+  @Since("2.1")
+  static const int connectionClosedWithoutResponse = 444;
+  @Since("2.1")
+  static const int unavailableForLegalReasons = 451;
+  @Since("2.1")
+  static const int clientClosedRequest = 499;
+  static const int internalServerError = 500;
+  static const int notImplemented = 501;
+  static const int badGateway = 502;
+  static const int serviceUnavailable = 503;
+  static const int gatewayTimeout = 504;
+  static const int httpVersionNotSupported = 505;
+  @Since("2.1")
+  static const int variantAlsoNegotiates = 506;
+  @Since("2.1")
+  static const int insufficientStorage = 507;
+  @Since("2.1")
+  static const int loopDetected = 508;
+  @Since("2.1")
+  static const int notExtended = 510;
+  @Since("2.1")
+  static const int networkAuthenticationRequired = 511;
+  // Client generated status code.
+  static const int networkConnectTimeoutError = 599;
+
+  @Deprecated("Use continue_ instead")
+  static const int CONTINUE = continue_;
+  @Deprecated("Use switchingProtocols instead")
+  static const int SWITCHING_PROTOCOLS = switchingProtocols;
+  @Deprecated("Use ok instead")
+  static const int OK = ok;
+  @Deprecated("Use created instead")
+  static const int CREATED = created;
+  @Deprecated("Use accepted instead")
+  static const int ACCEPTED = accepted;
+  @Deprecated("Use nonAuthoritativeInformation instead")
+  static const int NON_AUTHORITATIVE_INFORMATION = nonAuthoritativeInformation;
+  @Deprecated("Use noContent instead")
+  static const int NO_CONTENT = noContent;
+  @Deprecated("Use resetContent instead")
+  static const int RESET_CONTENT = resetContent;
+  @Deprecated("Use partialContent instead")
+  static const int PARTIAL_CONTENT = partialContent;
+  @Deprecated("Use multipleChoices instead")
+  static const int MULTIPLE_CHOICES = multipleChoices;
+  @Deprecated("Use movedPermanently instead")
+  static const int MOVED_PERMANENTLY = movedPermanently;
+  @Deprecated("Use found instead")
+  static const int FOUND = found;
+  @Deprecated("Use movedTemporarily instead")
+  static const int MOVED_TEMPORARILY = movedTemporarily;
+  @Deprecated("Use seeOther instead")
+  static const int SEE_OTHER = seeOther;
+  @Deprecated("Use notModified instead")
+  static const int NOT_MODIFIED = notModified;
+  @Deprecated("Use useProxy instead")
+  static const int USE_PROXY = useProxy;
+  @Deprecated("Use temporaryRedirect instead")
+  static const int TEMPORARY_REDIRECT = temporaryRedirect;
+  @Deprecated("Use badRequest instead")
+  static const int BAD_REQUEST = badRequest;
+  @Deprecated("Use unauthorized instead")
+  static const int UNAUTHORIZED = unauthorized;
+  @Deprecated("Use paymentRequired instead")
+  static const int PAYMENT_REQUIRED = paymentRequired;
+  @Deprecated("Use forbidden instead")
+  static const int FORBIDDEN = forbidden;
+  @Deprecated("Use notFound instead")
+  static const int NOT_FOUND = notFound;
+  @Deprecated("Use methodNotAllowed instead")
+  static const int METHOD_NOT_ALLOWED = methodNotAllowed;
+  @Deprecated("Use notAcceptable instead")
+  static const int NOT_ACCEPTABLE = notAcceptable;
+  @Deprecated("Use proxyAuthenticationRequired instead")
+  static const int PROXY_AUTHENTICATION_REQUIRED = proxyAuthenticationRequired;
+  @Deprecated("Use requestTimeout instead")
+  static const int REQUEST_TIMEOUT = requestTimeout;
+  @Deprecated("Use conflict instead")
+  static const int CONFLICT = conflict;
+  @Deprecated("Use gone instead")
+  static const int GONE = gone;
+  @Deprecated("Use lengthRequired instead")
+  static const int LENGTH_REQUIRED = lengthRequired;
+  @Deprecated("Use preconditionFailed instead")
+  static const int PRECONDITION_FAILED = preconditionFailed;
+  @Deprecated("Use requestEntityTooLarge instead")
+  static const int REQUEST_ENTITY_TOO_LARGE = requestEntityTooLarge;
+  @Deprecated("Use requestUriTooLong instead")
+  static const int REQUEST_URI_TOO_LONG = requestUriTooLong;
+  @Deprecated("Use unsupportedMediaType instead")
+  static const int UNSUPPORTED_MEDIA_TYPE = unsupportedMediaType;
+  @Deprecated("Use requestedRangeNotSatisfiable instead")
+  static const int REQUESTED_RANGE_NOT_SATISFIABLE =
+      requestedRangeNotSatisfiable;
+  @Deprecated("Use expectationFailed instead")
+  static const int EXPECTATION_FAILED = expectationFailed;
+  @Deprecated("Use upgradeRequired instead")
+  static const int UPGRADE_REQUIRED = upgradeRequired;
+  @Deprecated("Use internalServerError instead")
+  static const int INTERNAL_SERVER_ERROR = internalServerError;
+  @Deprecated("Use notImplemented instead")
+  static const int NOT_IMPLEMENTED = notImplemented;
+  @Deprecated("Use badGateway instead")
+  static const int BAD_GATEWAY = badGateway;
+  @Deprecated("Use serviceUnavailable instead")
+  static const int SERVICE_UNAVAILABLE = serviceUnavailable;
+  @Deprecated("Use gatewayTimeout instead")
+  static const int GATEWAY_TIMEOUT = gatewayTimeout;
+  @Deprecated("Use httpVersionNotSupported instead")
+  static const int HTTP_VERSION_NOT_SUPPORTED = httpVersionNotSupported;
+  @Deprecated("Use networkConnectTimeoutError instead")
+  static const int NETWORK_CONNECT_TIMEOUT_ERROR = networkConnectTimeoutError;
+}
diff --git a/sdk_nnbd/lib/internal/internal_sources.gni b/sdk_nnbd/lib/internal/internal_sources.gni
new file mode 100644
index 0000000..7c8af46
--- /dev/null
+++ b/sdk_nnbd/lib/internal/internal_sources.gni
@@ -0,0 +1,18 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for 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 file contains all sources for the dart:_internal library.
+internal_sdk_sources = [
+  "internal.dart",
+
+  # The above file needs to be first as it lists the parts below.
+  "async_cast.dart",
+  "cast.dart",
+  "iterable.dart",
+  "list.dart",
+  "linked_list.dart",
+  "print.dart",
+  "sort.dart",
+  "symbol.dart",
+]
diff --git a/sdk_nnbd/lib/internal/iterable.dart b/sdk_nnbd/lib/internal/iterable.dart
new file mode 100644
index 0000000..b3e8e4e
--- /dev/null
+++ b/sdk_nnbd/lib/internal/iterable.dart
@@ -0,0 +1,897 @@
+// 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.
+
+part of dart._internal;
+
+/**
+ * Marker interface for [Iterable] subclasses that have an efficient
+ * [length] implementation.
+ */
+abstract class EfficientLengthIterable<T> extends Iterable<T> {
+  const EfficientLengthIterable();
+  /**
+   * Returns the number of elements in the iterable.
+   *
+   * This is an efficient operation that doesn't require iterating through
+   * the elements.
+   */
+  int get length;
+}
+
+/**
+ * An [Iterable] for classes that have efficient [length] and [elementAt].
+ *
+ * All other methods are implemented in terms of [length] and [elementAt],
+ * including [iterator].
+ */
+abstract class ListIterable<E> extends EfficientLengthIterable<E> {
+  int get length;
+  E elementAt(int i);
+
+  const ListIterable();
+
+  Iterator<E> get iterator => new ListIterator<E>(this);
+
+  void forEach(void action(E element)) {
+    int length = this.length;
+    for (int i = 0; i < length; i++) {
+      action(elementAt(i));
+      if (length != this.length) {
+        throw new ConcurrentModificationError(this);
+      }
+    }
+  }
+
+  bool get isEmpty => length == 0;
+
+  E get first {
+    if (length == 0) throw IterableElementError.noElement();
+    return elementAt(0);
+  }
+
+  E get last {
+    if (length == 0) throw IterableElementError.noElement();
+    return elementAt(length - 1);
+  }
+
+  E get single {
+    if (length == 0) throw IterableElementError.noElement();
+    if (length > 1) throw IterableElementError.tooMany();
+    return elementAt(0);
+  }
+
+  bool contains(Object element) {
+    int length = this.length;
+    for (int i = 0; i < length; i++) {
+      if (elementAt(i) == element) return true;
+      if (length != this.length) {
+        throw new ConcurrentModificationError(this);
+      }
+    }
+    return false;
+  }
+
+  bool every(bool test(E element)) {
+    int length = this.length;
+    for (int i = 0; i < length; i++) {
+      if (!test(elementAt(i))) return false;
+      if (length != this.length) {
+        throw new ConcurrentModificationError(this);
+      }
+    }
+    return true;
+  }
+
+  bool any(bool test(E element)) {
+    int length = this.length;
+    for (int i = 0; i < length; i++) {
+      if (test(elementAt(i))) return true;
+      if (length != this.length) {
+        throw new ConcurrentModificationError(this);
+      }
+    }
+    return false;
+  }
+
+  E firstWhere(bool test(E element), {E orElse()}) {
+    int length = this.length;
+    for (int i = 0; i < length; i++) {
+      E element = elementAt(i);
+      if (test(element)) return element;
+      if (length != this.length) {
+        throw new ConcurrentModificationError(this);
+      }
+    }
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E lastWhere(bool test(E element), {E orElse()}) {
+    int length = this.length;
+    for (int i = length - 1; i >= 0; i--) {
+      E element = elementAt(i);
+      if (test(element)) return element;
+      if (length != this.length) {
+        throw new ConcurrentModificationError(this);
+      }
+    }
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E singleWhere(bool test(E element), {E orElse()}) {
+    int length = this.length;
+    E match = null;
+    bool matchFound = false;
+    for (int i = 0; i < length; i++) {
+      E element = elementAt(i);
+      if (test(element)) {
+        if (matchFound) {
+          throw IterableElementError.tooMany();
+        }
+        matchFound = true;
+        match = element;
+      }
+      if (length != this.length) {
+        throw new ConcurrentModificationError(this);
+      }
+    }
+    if (matchFound) return match;
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  String join([String separator = ""]) {
+    int length = this.length;
+    if (!separator.isEmpty) {
+      if (length == 0) return "";
+      String first = "${elementAt(0)}";
+      if (length != this.length) {
+        throw new ConcurrentModificationError(this);
+      }
+      StringBuffer buffer = new StringBuffer(first);
+      for (int i = 1; i < length; i++) {
+        buffer.write(separator);
+        buffer.write(elementAt(i));
+        if (length != this.length) {
+          throw new ConcurrentModificationError(this);
+        }
+      }
+      return buffer.toString();
+    } else {
+      StringBuffer buffer = new StringBuffer();
+      for (int i = 0; i < length; i++) {
+        buffer.write(elementAt(i));
+        if (length != this.length) {
+          throw new ConcurrentModificationError(this);
+        }
+      }
+      return buffer.toString();
+    }
+  }
+
+  Iterable<E> where(bool test(E element)) => super.where(test);
+
+  Iterable<T> map<T>(T f(E element)) => new MappedListIterable<E, T>(this, f);
+
+  E reduce(E combine(E value, E element)) {
+    int length = this.length;
+    if (length == 0) throw IterableElementError.noElement();
+    E value = elementAt(0);
+    for (int i = 1; i < length; i++) {
+      value = combine(value, elementAt(i));
+      if (length != this.length) {
+        throw new ConcurrentModificationError(this);
+      }
+    }
+    return value;
+  }
+
+  T fold<T>(T initialValue, T combine(T previousValue, E element)) {
+    var value = initialValue;
+    int length = this.length;
+    for (int i = 0; i < length; i++) {
+      value = combine(value, elementAt(i));
+      if (length != this.length) {
+        throw new ConcurrentModificationError(this);
+      }
+    }
+    return value;
+  }
+
+  Iterable<E> skip(int count) => new SubListIterable<E>(this, count, null);
+
+  Iterable<E> skipWhile(bool test(E element)) => super.skipWhile(test);
+
+  Iterable<E> take(int count) => new SubListIterable<E>(this, 0, count);
+
+  Iterable<E> takeWhile(bool test(E element)) => super.takeWhile(test);
+
+  List<E> toList({bool growable: true}) {
+    List<E> result;
+    if (growable) {
+      result = <E>[]..length = length;
+    } else {
+      result = new List<E>(length);
+    }
+    for (int i = 0; i < length; i++) {
+      result[i] = elementAt(i);
+    }
+    return result;
+  }
+
+  Set<E> toSet() {
+    Set<E> result = new Set<E>();
+    for (int i = 0; i < length; i++) {
+      result.add(elementAt(i));
+    }
+    return result;
+  }
+}
+
+class SubListIterable<E> extends ListIterable<E> {
+  final Iterable<E> _iterable; // Has efficient length and elementAt.
+  final int _start;
+  /** If null, represents the length of the iterable. */
+  final int _endOrLength;
+
+  SubListIterable(this._iterable, this._start, this._endOrLength) {
+    RangeError.checkNotNegative(_start, "start");
+    if (_endOrLength != null) {
+      RangeError.checkNotNegative(_endOrLength, "end");
+      if (_start > _endOrLength) {
+        throw new RangeError.range(_start, 0, _endOrLength, "start");
+      }
+    }
+  }
+
+  int get _endIndex {
+    int length = _iterable.length;
+    if (_endOrLength == null || _endOrLength > length) return length;
+    return _endOrLength;
+  }
+
+  int get _startIndex {
+    int length = _iterable.length;
+    if (_start > length) return length;
+    return _start;
+  }
+
+  int get length {
+    int length = _iterable.length;
+    if (_start >= length) return 0;
+    if (_endOrLength == null || _endOrLength >= length) {
+      return length - _start;
+    }
+    return _endOrLength - _start;
+  }
+
+  E elementAt(int index) {
+    int realIndex = _startIndex + index;
+    if (index < 0 || realIndex >= _endIndex) {
+      throw new RangeError.index(index, this, "index");
+    }
+    return _iterable.elementAt(realIndex);
+  }
+
+  Iterable<E> skip(int count) {
+    RangeError.checkNotNegative(count, "count");
+    int newStart = _start + count;
+    if (_endOrLength != null && newStart >= _endOrLength) {
+      return new EmptyIterable<E>();
+    }
+    return new SubListIterable<E>(_iterable, newStart, _endOrLength);
+  }
+
+  Iterable<E> take(int count) {
+    RangeError.checkNotNegative(count, "count");
+    if (_endOrLength == null) {
+      return new SubListIterable<E>(_iterable, _start, _start + count);
+    } else {
+      int newEnd = _start + count;
+      if (_endOrLength < newEnd) return this;
+      return new SubListIterable<E>(_iterable, _start, newEnd);
+    }
+  }
+
+  List<E> toList({bool growable: true}) {
+    int start = _start;
+    int end = _iterable.length;
+    if (_endOrLength != null && _endOrLength < end) end = _endOrLength;
+    int length = end - start;
+    if (length < 0) length = 0;
+    List<E> result =
+        growable ? (new List<E>()..length = length) : new List<E>(length);
+    for (int i = 0; i < length; i++) {
+      result[i] = _iterable.elementAt(start + i);
+      if (_iterable.length < end) throw new ConcurrentModificationError(this);
+    }
+    return result;
+  }
+}
+
+/**
+ * An [Iterator] that iterates a list-like [Iterable].
+ *
+ * All iterations is done in terms of [Iterable.length] and
+ * [Iterable.elementAt]. These operations are fast for list-like
+ * iterables.
+ */
+class ListIterator<E> implements Iterator<E> {
+  final Iterable<E> _iterable;
+  final int _length;
+  int _index;
+  E _current;
+
+  ListIterator(Iterable<E> iterable)
+      : _iterable = iterable,
+        _length = iterable.length,
+        _index = 0;
+
+  E get current => _current;
+
+  @pragma("vm:prefer-inline")
+  bool moveNext() {
+    int length = _iterable.length;
+    if (_length != length) {
+      throw new ConcurrentModificationError(_iterable);
+    }
+    if (_index >= length) {
+      _current = null;
+      return false;
+    }
+    _current = _iterable.elementAt(_index);
+    _index++;
+    return true;
+  }
+}
+
+typedef T _Transformation<S, T>(S value);
+
+class MappedIterable<S, T> extends Iterable<T> {
+  final Iterable<S> _iterable;
+  final _Transformation<S, T> _f;
+
+  factory MappedIterable(Iterable<S> iterable, T function(S value)) {
+    if (iterable is EfficientLengthIterable) {
+      return new EfficientLengthMappedIterable<S, T>(iterable, function);
+    }
+    return new MappedIterable<S, T>._(iterable, function);
+  }
+
+  MappedIterable._(this._iterable, this._f);
+
+  Iterator<T> get iterator => new MappedIterator<S, T>(_iterable.iterator, _f);
+
+  // Length related functions are independent of the mapping.
+  int get length => _iterable.length;
+  bool get isEmpty => _iterable.isEmpty;
+
+  // Index based lookup can be done before transforming.
+  T get first => _f(_iterable.first);
+  T get last => _f(_iterable.last);
+  T get single => _f(_iterable.single);
+  T elementAt(int index) => _f(_iterable.elementAt(index));
+}
+
+class EfficientLengthMappedIterable<S, T> extends MappedIterable<S, T>
+    implements EfficientLengthIterable<T> {
+  EfficientLengthMappedIterable(Iterable<S> iterable, T function(S value))
+      : super._(iterable, function);
+}
+
+class MappedIterator<S, T> extends Iterator<T> {
+  T _current;
+  final Iterator<S> _iterator;
+  final _Transformation<S, T> _f;
+
+  MappedIterator(this._iterator, this._f);
+
+  bool moveNext() {
+    if (_iterator.moveNext()) {
+      _current = _f(_iterator.current);
+      return true;
+    }
+    _current = null;
+    return false;
+  }
+
+  T get current => _current;
+}
+
+/**
+ * Specialized alternative to [MappedIterable] for mapped [List]s.
+ *
+ * Expects efficient `length` and `elementAt` on the source iterable.
+ */
+class MappedListIterable<S, T> extends ListIterable<T> {
+  final Iterable<S> _source;
+  final _Transformation<S, T> _f;
+
+  MappedListIterable(this._source, this._f);
+
+  int get length => _source.length;
+  T elementAt(int index) => _f(_source.elementAt(index));
+}
+
+typedef bool _ElementPredicate<E>(E element);
+
+class WhereIterable<E> extends Iterable<E> {
+  final Iterable<E> _iterable;
+  final _ElementPredicate<E> _f;
+
+  WhereIterable(this._iterable, this._f);
+
+  Iterator<E> get iterator => new WhereIterator<E>(_iterable.iterator, _f);
+
+  // Specialization of [Iterable.map] to non-EfficientLengthIterable.
+  Iterable<T> map<T>(T f(E element)) => new MappedIterable<E, T>._(this, f);
+}
+
+class WhereIterator<E> extends Iterator<E> {
+  final Iterator<E> _iterator;
+  final _ElementPredicate<E> _f;
+
+  WhereIterator(this._iterator, this._f);
+
+  bool moveNext() {
+    while (_iterator.moveNext()) {
+      if (_f(_iterator.current)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  E get current => _iterator.current;
+}
+
+typedef Iterable<T> _ExpandFunction<S, T>(S sourceElement);
+
+class ExpandIterable<S, T> extends Iterable<T> {
+  final Iterable<S> _iterable;
+  final _ExpandFunction<S, T> _f;
+
+  ExpandIterable(this._iterable, this._f);
+
+  Iterator<T> get iterator => new ExpandIterator<S, T>(_iterable.iterator, _f);
+}
+
+class ExpandIterator<S, T> implements Iterator<T> {
+  final Iterator<S> _iterator;
+  final _ExpandFunction<S, T> _f;
+  // Initialize _currentExpansion to an empty iterable. A null value
+  // marks the end of iteration, and we don't want to call _f before
+  // the first moveNext call.
+  Iterator<T> _currentExpansion = const EmptyIterator();
+  T _current;
+
+  ExpandIterator(this._iterator, this._f);
+
+  T get current => _current;
+
+  bool moveNext() {
+    if (_currentExpansion == null) return false;
+    while (!_currentExpansion.moveNext()) {
+      _current = null;
+      if (_iterator.moveNext()) {
+        // If _f throws, this ends iteration. Otherwise _currentExpansion and
+        // _current will be set again below.
+        _currentExpansion = null;
+        _currentExpansion = _f(_iterator.current).iterator;
+      } else {
+        return false;
+      }
+    }
+    _current = _currentExpansion.current;
+    return true;
+  }
+}
+
+class TakeIterable<E> extends Iterable<E> {
+  final Iterable<E> _iterable;
+  final int _takeCount;
+
+  factory TakeIterable(Iterable<E> iterable, int takeCount) {
+    ArgumentError.checkNotNull(takeCount, "takeCount");
+    RangeError.checkNotNegative(takeCount, "takeCount");
+    if (iterable is EfficientLengthIterable) {
+      return new EfficientLengthTakeIterable<E>(iterable, takeCount);
+    }
+    return new TakeIterable<E>._(iterable, takeCount);
+  }
+
+  TakeIterable._(this._iterable, this._takeCount);
+
+  Iterator<E> get iterator {
+    return new TakeIterator<E>(_iterable.iterator, _takeCount);
+  }
+}
+
+class EfficientLengthTakeIterable<E> extends TakeIterable<E>
+    implements EfficientLengthIterable<E> {
+  EfficientLengthTakeIterable(Iterable<E> iterable, int takeCount)
+      : super._(iterable, takeCount);
+
+  int get length {
+    int iterableLength = _iterable.length;
+    if (iterableLength > _takeCount) return _takeCount;
+    return iterableLength;
+  }
+}
+
+class TakeIterator<E> extends Iterator<E> {
+  final Iterator<E> _iterator;
+  int _remaining;
+
+  TakeIterator(this._iterator, this._remaining) {
+    assert(_remaining >= 0);
+  }
+
+  bool moveNext() {
+    _remaining--;
+    if (_remaining >= 0) {
+      return _iterator.moveNext();
+    }
+    _remaining = -1;
+    return false;
+  }
+
+  E get current {
+    if (_remaining < 0) return null;
+    return _iterator.current;
+  }
+}
+
+class TakeWhileIterable<E> extends Iterable<E> {
+  final Iterable<E> _iterable;
+  final _ElementPredicate<E> _f;
+
+  TakeWhileIterable(this._iterable, this._f);
+
+  Iterator<E> get iterator {
+    return new TakeWhileIterator<E>(_iterable.iterator, _f);
+  }
+}
+
+class TakeWhileIterator<E> extends Iterator<E> {
+  final Iterator<E> _iterator;
+  final _ElementPredicate<E> _f;
+  bool _isFinished = false;
+
+  TakeWhileIterator(this._iterator, this._f);
+
+  bool moveNext() {
+    if (_isFinished) return false;
+    if (!_iterator.moveNext() || !_f(_iterator.current)) {
+      _isFinished = true;
+      return false;
+    }
+    return true;
+  }
+
+  E get current {
+    if (_isFinished) return null;
+    return _iterator.current;
+  }
+}
+
+class SkipIterable<E> extends Iterable<E> {
+  final Iterable<E> _iterable;
+  final int _skipCount;
+
+  factory SkipIterable(Iterable<E> iterable, int count) {
+    if (iterable is EfficientLengthIterable) {
+      return new EfficientLengthSkipIterable<E>(iterable, count);
+    }
+    return new SkipIterable<E>._(iterable, _checkCount(count));
+  }
+
+  SkipIterable._(this._iterable, this._skipCount);
+
+  Iterable<E> skip(int count) {
+    return new SkipIterable<E>._(_iterable, _skipCount + _checkCount(count));
+  }
+
+  Iterator<E> get iterator {
+    return new SkipIterator<E>(_iterable.iterator, _skipCount);
+  }
+}
+
+class EfficientLengthSkipIterable<E> extends SkipIterable<E>
+    implements EfficientLengthIterable<E> {
+  factory EfficientLengthSkipIterable(Iterable<E> iterable, int count) {
+    return new EfficientLengthSkipIterable<E>._(iterable, _checkCount(count));
+  }
+
+  EfficientLengthSkipIterable._(Iterable<E> iterable, int count)
+      : super._(iterable, count);
+
+  int get length {
+    int length = _iterable.length - _skipCount;
+    if (length >= 0) return length;
+    return 0;
+  }
+
+  Iterable<E> skip(int count) {
+    return new EfficientLengthSkipIterable<E>._(
+        _iterable, _skipCount + _checkCount(count));
+  }
+}
+
+int _checkCount(int count) {
+  ArgumentError.checkNotNull(count, "count");
+  RangeError.checkNotNegative(count, "count");
+  return count;
+}
+
+class SkipIterator<E> extends Iterator<E> {
+  final Iterator<E> _iterator;
+  int _skipCount;
+
+  SkipIterator(this._iterator, this._skipCount) {
+    assert(_skipCount >= 0);
+  }
+
+  bool moveNext() {
+    for (int i = 0; i < _skipCount; i++) _iterator.moveNext();
+    _skipCount = 0;
+    return _iterator.moveNext();
+  }
+
+  E get current => _iterator.current;
+}
+
+class SkipWhileIterable<E> extends Iterable<E> {
+  final Iterable<E> _iterable;
+  final _ElementPredicate<E> _f;
+
+  SkipWhileIterable(this._iterable, this._f);
+
+  Iterator<E> get iterator {
+    return new SkipWhileIterator<E>(_iterable.iterator, _f);
+  }
+}
+
+class SkipWhileIterator<E> extends Iterator<E> {
+  final Iterator<E> _iterator;
+  final _ElementPredicate<E> _f;
+  bool _hasSkipped = false;
+
+  SkipWhileIterator(this._iterator, this._f);
+
+  bool moveNext() {
+    if (!_hasSkipped) {
+      _hasSkipped = true;
+      while (_iterator.moveNext()) {
+        if (!_f(_iterator.current)) return true;
+      }
+    }
+    return _iterator.moveNext();
+  }
+
+  E get current => _iterator.current;
+}
+
+/**
+ * The always empty [Iterable].
+ */
+class EmptyIterable<E> extends EfficientLengthIterable<E> {
+  const EmptyIterable();
+
+  Iterator<E> get iterator => const EmptyIterator();
+
+  void forEach(void action(E element)) {}
+
+  bool get isEmpty => true;
+
+  int get length => 0;
+
+  E get first {
+    throw IterableElementError.noElement();
+  }
+
+  E get last {
+    throw IterableElementError.noElement();
+  }
+
+  E get single {
+    throw IterableElementError.noElement();
+  }
+
+  E elementAt(int index) {
+    throw new RangeError.range(index, 0, 0, "index");
+  }
+
+  bool contains(Object element) => false;
+
+  bool every(bool test(E element)) => true;
+
+  bool any(bool test(E element)) => false;
+
+  E firstWhere(bool test(E element), {E orElse()}) {
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E lastWhere(bool test(E element), {E orElse()}) {
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  E singleWhere(bool test(E element), {E orElse()}) {
+    if (orElse != null) return orElse();
+    throw IterableElementError.noElement();
+  }
+
+  String join([String separator = ""]) => "";
+
+  Iterable<E> where(bool test(E element)) => this;
+
+  Iterable<T> map<T>(T f(E element)) => new EmptyIterable<T>();
+
+  E reduce(E combine(E value, E element)) {
+    throw IterableElementError.noElement();
+  }
+
+  T fold<T>(T initialValue, T combine(T previousValue, E element)) {
+    return initialValue;
+  }
+
+  Iterable<E> skip(int count) {
+    RangeError.checkNotNegative(count, "count");
+    return this;
+  }
+
+  Iterable<E> skipWhile(bool test(E element)) => this;
+
+  Iterable<E> take(int count) {
+    RangeError.checkNotNegative(count, "count");
+    return this;
+  }
+
+  Iterable<E> takeWhile(bool test(E element)) => this;
+
+  List<E> toList({bool growable: true}) => growable ? <E>[] : new List<E>(0);
+
+  Set<E> toSet() => new Set<E>();
+}
+
+/** The always empty iterator. */
+class EmptyIterator<E> implements Iterator<E> {
+  const EmptyIterator();
+  bool moveNext() => false;
+  E get current => null;
+}
+
+class FollowedByIterable<E> extends Iterable<E> {
+  final Iterable<E> _first;
+  final Iterable<E> _second;
+  FollowedByIterable(this._first, this._second);
+
+  factory FollowedByIterable.firstEfficient(
+      EfficientLengthIterable<E> first, Iterable<E> second) {
+    if (second is EfficientLengthIterable<E>) {
+      return new EfficientLengthFollowedByIterable<E>(first, second);
+    }
+    return new FollowedByIterable<E>(first, second);
+  }
+
+  Iterator<E> get iterator => new FollowedByIterator(_first, _second);
+
+  int get length => _first.length + _second.length;
+  bool get isEmpty => _first.isEmpty && _second.isEmpty;
+  bool get isNotEmpty => _first.isNotEmpty || _second.isNotEmpty;
+
+  // May be more efficient if either iterable is a Set.
+  bool contains(Object value) =>
+      _first.contains(value) || _second.contains(value);
+
+  E get first {
+    var iterator = _first.iterator;
+    if (iterator.moveNext()) return iterator.current;
+    return _second.first;
+  }
+
+  E get last {
+    var iterator = _second.iterator;
+    if (iterator.moveNext()) {
+      E last = iterator.current;
+      while (iterator.moveNext()) last = iterator.current;
+      return last;
+    }
+    return _first.last;
+  }
+
+  // If linear sequences of `followedBy` becomes an issue, we can flatten
+  // into a list of iterables instead of a tree or spine.
+}
+
+class EfficientLengthFollowedByIterable<E> extends FollowedByIterable<E>
+    implements EfficientLengthIterable<E> {
+  EfficientLengthFollowedByIterable(
+      EfficientLengthIterable<E> first, EfficientLengthIterable<E> second)
+      : super(first, second);
+
+  Iterable<E> skip(int count) {
+    int firstLength = _first.length;
+    if (count >= firstLength) return _second.skip(count - firstLength);
+    return new EfficientLengthFollowedByIterable<E>(
+        _first.skip(count), _second);
+  }
+
+  Iterable<E> take(int count) {
+    int firstLength = _first.length;
+    if (count <= firstLength) return _first.take(count);
+    return new EfficientLengthFollowedByIterable<E>(
+        _first, _second.take(count - firstLength));
+  }
+
+  E elementAt(int index) {
+    int firstLength = _first.length;
+    if (index < firstLength) return _first.elementAt(index);
+    return _second.elementAt(index - firstLength);
+  }
+
+  E get first {
+    if (_first.isNotEmpty) return _first.first;
+    return _second.first;
+  }
+
+  E get last {
+    if (_second.isNotEmpty) return _second.last;
+    return _first.last;
+  }
+}
+
+class FollowedByIterator<E> implements Iterator<E> {
+  Iterator<E> _currentIterator;
+  Iterable<E> _nextIterable;
+
+  FollowedByIterator(Iterable<E> first, this._nextIterable)
+      : _currentIterator = first.iterator;
+
+  bool moveNext() {
+    if (_currentIterator.moveNext()) return true;
+    if (_nextIterable != null) {
+      _currentIterator = _nextIterable.iterator;
+      _nextIterable = null;
+      return _currentIterator.moveNext();
+    }
+    return false;
+  }
+
+  E get current => _currentIterator.current;
+}
+
+class WhereTypeIterable<T> extends Iterable<T> {
+  final Iterable<Object> _source;
+  WhereTypeIterable(this._source);
+  Iterator<T> get iterator => new WhereTypeIterator<T>(_source.iterator);
+}
+
+class WhereTypeIterator<T> implements Iterator<T> {
+  final Iterator<Object> _source;
+  WhereTypeIterator(this._source);
+  bool moveNext() {
+    while (_source.moveNext()) {
+      if (_source.current is T) return true;
+    }
+    return false;
+  }
+
+  T get current => _source.current;
+}
+
+/**
+ * Creates errors throw by [Iterable] when the element count is wrong.
+ */
+abstract class IterableElementError {
+  /** Error thrown thrown by, e.g., [Iterable.first] when there is no result. */
+  static StateError noElement() => new StateError("No element");
+  /** Error thrown by, e.g., [Iterable.single] if there are too many results. */
+  static StateError tooMany() => new StateError("Too many elements");
+  /** Error thrown by, e.g., [List.setRange] if there are too few elements. */
+  static StateError tooFew() => new StateError("Too few elements");
+}
diff --git a/sdk_nnbd/lib/internal/linked_list.dart b/sdk_nnbd/lib/internal/linked_list.dart
new file mode 100644
index 0000000..31a6c01
--- /dev/null
+++ b/sdk_nnbd/lib/internal/linked_list.dart
@@ -0,0 +1,126 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart._internal;
+
+/// A rudimentary linked list.
+class LinkedList<T extends LinkedListEntry<T>> extends IterableBase<T> {
+  T first;
+  T last;
+  int length = 0;
+
+  bool get isEmpty => length == 0;
+
+  /**
+   * Adds [newLast] to the end of this linked list.
+   */
+  void add(T newLast) {
+    assert(newLast._next == null && newLast._previous == null);
+    if (last != null) {
+      assert(last._next == null);
+      last._next = newLast;
+    } else {
+      first = newLast;
+    }
+    newLast._previous = last;
+    last = newLast;
+    last._list = this;
+    length++;
+  }
+
+  /**
+   * Adds [newFirst] to the beginning of this linked list.
+   */
+  void addFirst(T newFirst) {
+    if (first != null) {
+      assert(first._previous == null);
+      first._previous = newFirst;
+    } else {
+      last = newFirst;
+    }
+    newFirst._next = first;
+    first = newFirst;
+    first._list = this;
+    length++;
+  }
+
+  /**
+   * Removes the given [node] from this list.
+   *
+   * If the entry is not in this linked list nothing happens.
+   *
+   * Also see [LinkedListEntry.unlink].
+   */
+  void remove(T node) {
+    if (node._list != this) return;
+    length--;
+    if (node._previous == null) {
+      assert(identical(node, first));
+      first = node._next;
+    } else {
+      node._previous._next = node._next;
+    }
+    if (node._next == null) {
+      assert(identical(node, last));
+      last = node._previous;
+    } else {
+      node._next._previous = node._previous;
+    }
+    node._next = node._previous = null;
+    node._list = null;
+  }
+
+  Iterator<T> get iterator => new _LinkedListIterator<T>(this);
+}
+
+class LinkedListEntry<T extends LinkedListEntry<T>> {
+  T _next;
+  T _previous;
+  LinkedList<T> _list;
+
+  /**
+   * Unlinks the element from its linked list.
+   *
+   * If the entry is not in a linked list, does nothing. Otherwise, this
+   * is equivalent to calling [LinkedList.remove] on the list this entry
+   * is currently in.
+   */
+  void unlink() {
+    if (_list == null) return;
+    _list.remove(this);
+  }
+}
+
+class _LinkedListIterator<T extends LinkedListEntry<T>> implements Iterator<T> {
+  /// The current element of the iterator.
+  // This field is writeable, but should only read by users of this class.
+  T current;
+
+  /// The list the iterator iterates over.
+  ///
+  /// Set to [null] if the provided list was empty (indicating that there were
+  /// no entries to iterate over).
+  ///
+  /// Set to [null] as soon as [moveNext] was invoked (indicating that the
+  /// iterator has to work with [current] from now on.
+  LinkedList<T> _list;
+
+  _LinkedListIterator(this._list) {
+    if (_list.length == 0) _list = null;
+  }
+
+  bool moveNext() {
+    // current is null if the iterator hasn't started iterating, or if the
+    // iteration is finished. In the first case, the [_list] field is not null.
+    if (current == null) {
+      if (_list == null) return false;
+      assert(_list.length > 0);
+      current = _list.first;
+      _list = null;
+      return true;
+    }
+    current = current._next;
+    return current != null;
+  }
+}
diff --git a/sdk_nnbd/lib/internal/list.dart b/sdk_nnbd/lib/internal/list.dart
new file mode 100644
index 0000000..e0ddd70
--- /dev/null
+++ b/sdk_nnbd/lib/internal/list.dart
@@ -0,0 +1,341 @@
+// 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 dart._internal;
+
+/**
+ * Mixin that throws on the length changing operations of [List].
+ *
+ * Intended to mix-in on top of [ListMixin] for fixed-length lists.
+ */
+abstract class FixedLengthListMixin<E> {
+  /** This operation is not supported by a fixed length list. */
+  set length(int newLength) {
+    throw new UnsupportedError(
+        "Cannot change the length of a fixed-length list");
+  }
+
+  /** This operation is not supported by a fixed length list. */
+  void add(E value) {
+    throw new UnsupportedError("Cannot add to a fixed-length list");
+  }
+
+  /** This operation is not supported by a fixed length list. */
+  void insert(int index, E value) {
+    throw new UnsupportedError("Cannot add to a fixed-length list");
+  }
+
+  /** This operation is not supported by a fixed length list. */
+  void insertAll(int at, Iterable<E> iterable) {
+    throw new UnsupportedError("Cannot add to a fixed-length list");
+  }
+
+  /** This operation is not supported by a fixed length list. */
+  void addAll(Iterable<E> iterable) {
+    throw new UnsupportedError("Cannot add to a fixed-length list");
+  }
+
+  /** This operation is not supported by a fixed length list. */
+  bool remove(Object element) {
+    throw new UnsupportedError("Cannot remove from a fixed-length list");
+  }
+
+  /** This operation is not supported by a fixed length list. */
+  void removeWhere(bool test(E element)) {
+    throw new UnsupportedError("Cannot remove from a fixed-length list");
+  }
+
+  /** This operation is not supported by a fixed length list. */
+  void retainWhere(bool test(E element)) {
+    throw new UnsupportedError("Cannot remove from a fixed-length list");
+  }
+
+  /** This operation is not supported by a fixed length list. */
+  void clear() {
+    throw new UnsupportedError("Cannot clear a fixed-length list");
+  }
+
+  /** This operation is not supported by a fixed length list. */
+  E removeAt(int index) {
+    throw new UnsupportedError("Cannot remove from a fixed-length list");
+  }
+
+  /** This operation is not supported by a fixed length list. */
+  E removeLast() {
+    throw new UnsupportedError("Cannot remove from a fixed-length list");
+  }
+
+  /** This operation is not supported by a fixed length list. */
+  void removeRange(int start, int end) {
+    throw new UnsupportedError("Cannot remove from a fixed-length list");
+  }
+
+  /** This operation is not supported by a fixed length list. */
+  void replaceRange(int start, int end, Iterable<E> iterable) {
+    throw new UnsupportedError("Cannot remove from a fixed-length list");
+  }
+}
+
+/**
+ * Mixin for an unmodifiable [List] class.
+ *
+ * This overrides all mutating methods with methods that throw.
+ * This mixin is intended to be mixed in on top of [ListMixin] on
+ * unmodifiable lists.
+ */
+abstract class UnmodifiableListMixin<E> implements List<E> {
+  /** This operation is not supported by an unmodifiable list. */
+  void operator []=(int index, E value) {
+    throw new UnsupportedError("Cannot modify an unmodifiable list");
+  }
+
+  /** This operation is not supported by an unmodifiable list. */
+  set length(int newLength) {
+    throw new UnsupportedError(
+        "Cannot change the length of an unmodifiable list");
+  }
+
+  set first(E element) {
+    throw new UnsupportedError("Cannot modify an unmodifiable list");
+  }
+
+  set last(E element) {
+    throw new UnsupportedError("Cannot modify an unmodifiable list");
+  }
+
+  /** This operation is not supported by an unmodifiable list. */
+  void setAll(int at, Iterable<E> iterable) {
+    throw new UnsupportedError("Cannot modify an unmodifiable list");
+  }
+
+  /** This operation is not supported by an unmodifiable list. */
+  void add(E value) {
+    throw new UnsupportedError("Cannot add to an unmodifiable list");
+  }
+
+  /** This operation is not supported by an unmodifiable list. */
+  void insert(int index, E element) {
+    throw new UnsupportedError("Cannot add to an unmodifiable list");
+  }
+
+  /** This operation is not supported by an unmodifiable list. */
+  void insertAll(int at, Iterable<E> iterable) {
+    throw new UnsupportedError("Cannot add to an unmodifiable list");
+  }
+
+  /** This operation is not supported by an unmodifiable list. */
+  void addAll(Iterable<E> iterable) {
+    throw new UnsupportedError("Cannot add to an unmodifiable list");
+  }
+
+  /** This operation is not supported by an unmodifiable list. */
+  bool remove(Object element) {
+    throw new UnsupportedError("Cannot remove from an unmodifiable list");
+  }
+
+  /** This operation is not supported by an unmodifiable list. */
+  void removeWhere(bool test(E element)) {
+    throw new UnsupportedError("Cannot remove from an unmodifiable list");
+  }
+
+  /** This operation is not supported by an unmodifiable list. */
+  void retainWhere(bool test(E element)) {
+    throw new UnsupportedError("Cannot remove from an unmodifiable list");
+  }
+
+  /** This operation is not supported by an unmodifiable list. */
+  void sort([Comparator<E> compare]) {
+    throw new UnsupportedError("Cannot modify an unmodifiable list");
+  }
+
+  /** This operation is not supported by an unmodifiable list. */
+  void shuffle([Random random]) {
+    throw new UnsupportedError("Cannot modify an unmodifiable list");
+  }
+
+  /** This operation is not supported by an unmodifiable list. */
+  void clear() {
+    throw new UnsupportedError("Cannot clear an unmodifiable list");
+  }
+
+  /** This operation is not supported by an unmodifiable list. */
+  E removeAt(int index) {
+    throw new UnsupportedError("Cannot remove from an unmodifiable list");
+  }
+
+  /** This operation is not supported by an unmodifiable list. */
+  E removeLast() {
+    throw new UnsupportedError("Cannot remove from an unmodifiable list");
+  }
+
+  /** This operation is not supported by an unmodifiable list. */
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+    throw new UnsupportedError("Cannot modify an unmodifiable list");
+  }
+
+  /** This operation is not supported by an unmodifiable list. */
+  void removeRange(int start, int end) {
+    throw new UnsupportedError("Cannot remove from an unmodifiable list");
+  }
+
+  /** This operation is not supported by an unmodifiable list. */
+  void replaceRange(int start, int end, Iterable<E> iterable) {
+    throw new UnsupportedError("Cannot remove from an unmodifiable list");
+  }
+
+  /** This operation is not supported by an unmodifiable list. */
+  void fillRange(int start, int end, [E fillValue]) {
+    throw new UnsupportedError("Cannot modify an unmodifiable list");
+  }
+}
+
+/**
+ * Abstract implementation of a fixed-length list.
+ *
+ * All operations are defined in terms of `length`, `operator[]` and
+ * `operator[]=`, which need to be implemented.
+ */
+abstract class FixedLengthListBase<E> = ListBase<E>
+    with FixedLengthListMixin<E>;
+
+/**
+ * Abstract implementation of an unmodifiable list.
+ *
+ * All operations are defined in terms of `length` and `operator[]`,
+ * which need to be implemented.
+ */
+abstract class UnmodifiableListBase<E> = ListBase<E>
+    with UnmodifiableListMixin<E>;
+
+class _ListIndicesIterable extends ListIterable<int> {
+  List _backedList;
+
+  _ListIndicesIterable(this._backedList);
+
+  int get length => _backedList.length;
+  int elementAt(int index) {
+    RangeError.checkValidIndex(index, this);
+    return index;
+  }
+}
+
+class ListMapView<E> extends UnmodifiableMapBase<int, E> {
+  List<E> _values;
+
+  ListMapView(this._values);
+
+  E operator [](Object key) => containsKey(key) ? _values[key] : null;
+  int get length => _values.length;
+
+  Iterable<E> get values => new SubListIterable<E>(_values, 0, null);
+  Iterable<int> get keys => new _ListIndicesIterable(_values);
+
+  bool get isEmpty => _values.isEmpty;
+  bool get isNotEmpty => _values.isNotEmpty;
+  bool containsValue(Object value) => _values.contains(value);
+  bool containsKey(Object key) => key is int && key >= 0 && key < length;
+
+  void forEach(void f(int key, E value)) {
+    int length = _values.length;
+    for (int i = 0; i < length; i++) {
+      f(i, _values[i]);
+      if (length != _values.length) {
+        throw new ConcurrentModificationError(_values);
+      }
+    }
+  }
+}
+
+class ReversedListIterable<E> extends ListIterable<E> {
+  Iterable<E> _source;
+  ReversedListIterable(this._source);
+
+  int get length => _source.length;
+
+  E elementAt(int index) => _source.elementAt(_source.length - 1 - index);
+}
+
+/**
+ * Creates errors thrown by unmodifiable lists when they are attempted modified.
+ *
+ * This class creates [UnsupportedError]s with specialized messages.
+ */
+abstract class UnmodifiableListError {
+  /** Error thrown when trying to add elements to an unmodifiable list. */
+  static UnsupportedError add() =>
+      new UnsupportedError("Cannot add to unmodifiable List");
+
+  /** Error thrown when trying to add elements to an unmodifiable list. */
+  static UnsupportedError change() =>
+      new UnsupportedError("Cannot change the content of an unmodifiable List");
+
+  /** Error thrown when trying to change the length of an unmodifiable list. */
+  static UnsupportedError length() =>
+      new UnsupportedError("Cannot change length of unmodifiable List");
+
+  /** Error thrown when trying to remove elements from an unmodifiable list. */
+  static UnsupportedError remove() =>
+      new UnsupportedError("Cannot remove from unmodifiable List");
+}
+
+/**
+ * Creates errors thrown by non-growable lists when they are attempted modified.
+ *
+ * This class creates [UnsupportedError]s with specialized messages.
+ */
+abstract class NonGrowableListError {
+  /** Error thrown when trying to add elements to an non-growable list. */
+  static UnsupportedError add() =>
+      new UnsupportedError("Cannot add to non-growable List");
+
+  /** Error thrown when trying to change the length of an non-growable list. */
+  static UnsupportedError length() =>
+      new UnsupportedError("Cannot change length of non-growable List");
+
+  /** Error thrown when trying to remove elements from an non-growable list. */
+  static UnsupportedError remove() =>
+      new UnsupportedError("Cannot remove from non-growable List");
+}
+
+/**
+ * Converts a growable list to a fixed length list with the same elements.
+ *
+ * For internal use only.
+ * Only works on growable lists as created by `[]` or `new List()`.
+ * May throw on any other list.
+ *
+ * The operation is efficient. It doesn't copy the elements, but converts
+ * the existing list directly to a fixed length list.
+ * That means that it is a destructive conversion.
+ * The original list should not be used afterwards.
+ *
+ * The returned list may be the same list as the original,
+ * or it may be a different list (according to [identical]).
+ * The original list may have changed type to be a fixed list,
+ * or become empty or been otherwise modified.
+ * It will still be a valid object, so references to it will not, e.g., crash
+ * the runtime if accessed, but no promises are made wrt. its contents.
+ *
+ * This unspecified behavior is the reason the function is not exposed to
+ * users. We allow the underlying implementation to make the most efficient
+ * conversion, at the cost of leaving the original list in an unspecified
+ * state.
+ */
+external List<T> makeListFixedLength<T>(List<T> growableList);
+
+/**
+ * Converts a fixed-length list to an unmodifiable list.
+ *
+ * For internal use only.
+ * Only works for core fixed-length lists as created by `new List(length)`,
+ * or as returned by [makeListFixedLength].
+ *
+ * The operation is efficient. It doesn't copy the elements, but converts
+ * the existing list directly to a fixed length list.
+ * That means that it is a destructive conversion.
+ * The original list should not be used afterwards.
+ *
+ * The unmodifiable list type is similar to the one used by const lists.
+ */
+external List<T> makeFixedListUnmodifiable<T>(List<T> fixedLengthList);
diff --git a/sdk_nnbd/lib/internal/patch.dart b/sdk_nnbd/lib/internal/patch.dart
new file mode 100644
index 0000000..3fc9733
--- /dev/null
+++ b/sdk_nnbd/lib/internal/patch.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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 "dart:_internal";
+
+class _Patch {
+  const _Patch();
+}
+
+const _Patch patch = const _Patch();
diff --git a/sdk_nnbd/lib/internal/print.dart b/sdk_nnbd/lib/internal/print.dart
new file mode 100644
index 0000000..417003b
--- /dev/null
+++ b/sdk_nnbd/lib/internal/print.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.
+
+part of dart._internal;
+
+/**
+ * This function is set by the first allocation of a Zone.
+ *
+ * Once the function is set the core `print` function calls this closure instead
+ * of [printToConsole].
+ *
+ * This decouples the core library from the async library.
+ */
+void Function(String) printToZone = null;
+
+external void printToConsole(String line);
diff --git a/sdk_nnbd/lib/internal/sort.dart b/sdk_nnbd/lib/internal/sort.dart
new file mode 100644
index 0000000..d6cca2e
--- /dev/null
+++ b/sdk_nnbd/lib/internal/sort.dart
@@ -0,0 +1,385 @@
+// 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.
+
+part of dart._internal;
+
+/**
+ * Dual-Pivot Quicksort algorithm.
+ *
+ * This class implements the dual-pivot quicksort algorithm as presented in
+ * Vladimir Yaroslavskiy's paper.
+ *
+ * Some improvements have been copied from Android's implementation.
+ */
+class Sort {
+  // When a list has less then [:_INSERTION_SORT_THRESHOLD:] elements it will
+  // be sorted by an insertion sort.
+  static const int _INSERTION_SORT_THRESHOLD = 32;
+
+  /**
+   * Sorts all elements of the given list [:a:] according to the given
+   * [:compare:] function.
+   *
+   * The [:compare:] function takes two arguments [:x:] and [:y:] and returns
+   *  -1 if [:x < y:],
+   *   0 if [:x == y:], and
+   *   1 if [:x > y:].
+   *
+   * The function's behavior must be consistent. It must not return different
+   * results for the same values.
+   */
+  static void sort<E>(List<E> a, int compare(E a, E b)) {
+    _doSort(a, 0, a.length - 1, compare);
+  }
+
+  /**
+   * Sorts all elements in the range [:from:] (inclusive) to [:to:] (exclusive)
+   * of the given list [:a:].
+   *
+   * If the given range is invalid an "OutOfRange" error is raised.
+   * TODO(floitsch): do we want an error?
+   *
+   * See [:sort:] for requirements of the [:compare:] function.
+   */
+  static void sortRange<E>(List<E> a, int from, int to, int compare(E a, E b)) {
+    if ((from < 0) || (to > a.length) || (to < from)) {
+      throw "OutOfRange";
+    }
+    _doSort(a, from, to - 1, compare);
+  }
+
+  /**
+   * Sorts the list in the interval [:left:] to [:right:] (both inclusive).
+   */
+  static void _doSort<E>(
+      List<E> a, int left, int right, int compare(E a, E b)) {
+    if ((right - left) <= _INSERTION_SORT_THRESHOLD) {
+      _insertionSort(a, left, right, compare);
+    } else {
+      _dualPivotQuicksort(a, left, right, compare);
+    }
+  }
+
+  static void _insertionSort<E>(
+      List<E> a, int left, int right, int compare(E a, E b)) {
+    for (int i = left + 1; i <= right; i++) {
+      var el = a[i];
+      int j = i;
+      while ((j > left) && (compare(a[j - 1], el) > 0)) {
+        a[j] = a[j - 1];
+        j--;
+      }
+      a[j] = el;
+    }
+  }
+
+  static void _dualPivotQuicksort<E>(
+      List<E> a, int left, int right, int compare(E a, E b)) {
+    assert(right - left > _INSERTION_SORT_THRESHOLD);
+
+    // Compute the two pivots by looking at 5 elements.
+    int sixth = (right - left + 1) ~/ 6;
+    int index1 = left + sixth;
+    int index5 = right - sixth;
+    int index3 = (left + right) ~/ 2; // The midpoint.
+    int index2 = index3 - sixth;
+    int index4 = index3 + sixth;
+
+    var el1 = a[index1];
+    var el2 = a[index2];
+    var el3 = a[index3];
+    var el4 = a[index4];
+    var el5 = a[index5];
+
+    // Sort the selected 5 elements using a sorting network.
+    if (compare(el1, el2) > 0) {
+      var t = el1;
+      el1 = el2;
+      el2 = t;
+    }
+    if (compare(el4, el5) > 0) {
+      var t = el4;
+      el4 = el5;
+      el5 = t;
+    }
+    if (compare(el1, el3) > 0) {
+      var t = el1;
+      el1 = el3;
+      el3 = t;
+    }
+    if (compare(el2, el3) > 0) {
+      var t = el2;
+      el2 = el3;
+      el3 = t;
+    }
+    if (compare(el1, el4) > 0) {
+      var t = el1;
+      el1 = el4;
+      el4 = t;
+    }
+    if (compare(el3, el4) > 0) {
+      var t = el3;
+      el3 = el4;
+      el4 = t;
+    }
+    if (compare(el2, el5) > 0) {
+      var t = el2;
+      el2 = el5;
+      el5 = t;
+    }
+    if (compare(el2, el3) > 0) {
+      var t = el2;
+      el2 = el3;
+      el3 = t;
+    }
+    if (compare(el4, el5) > 0) {
+      var t = el4;
+      el4 = el5;
+      el5 = t;
+    }
+
+    var pivot1 = el2;
+    var pivot2 = el4;
+
+    // el2 and el4 have been saved in the pivot variables. They will be written
+    // back, once the partitioning is finished.
+    a[index1] = el1;
+    a[index3] = el3;
+    a[index5] = el5;
+
+    a[index2] = a[left];
+    a[index4] = a[right];
+
+    int less = left + 1; // First element in the middle partition.
+    int great = right - 1; // Last element in the middle partition.
+
+    bool pivots_are_equal = (compare(pivot1, pivot2) == 0);
+    if (pivots_are_equal) {
+      var pivot = pivot1;
+      // Degenerated case where the partitioning becomes a Dutch national flag
+      // problem.
+      //
+      // [ |  < pivot  | == pivot | unpartitioned | > pivot  | ]
+      //  ^             ^          ^             ^            ^
+      // left         less         k           great         right
+      //
+      // a[left] and a[right] are undefined and are filled after the
+      // partitioning.
+      //
+      // Invariants:
+      //   1) for x in ]left, less[ : x < pivot.
+      //   2) for x in [less, k[ : x == pivot.
+      //   3) for x in ]great, right[ : x > pivot.
+      for (int k = less; k <= great; k++) {
+        var ak = a[k];
+        int comp = compare(ak, pivot);
+        if (comp == 0) continue;
+        if (comp < 0) {
+          if (k != less) {
+            a[k] = a[less];
+            a[less] = ak;
+          }
+          less++;
+        } else {
+          // comp > 0.
+          //
+          // Find the first element <= pivot in the range [k - 1, great] and
+          // put [:ak:] there. We know that such an element must exist:
+          // When k == less, then el3 (which is equal to pivot) lies in the
+          // interval. Otherwise a[k - 1] == pivot and the search stops at k-1.
+          // Note that in the latter case invariant 2 will be violated for a
+          // short amount of time. The invariant will be restored when the
+          // pivots are put into their final positions.
+          while (true) {
+            comp = compare(a[great], pivot);
+            if (comp > 0) {
+              great--;
+              // This is the only location in the while-loop where a new
+              // iteration is started.
+              continue;
+            } else if (comp < 0) {
+              // Triple exchange.
+              a[k] = a[less];
+              a[less++] = a[great];
+              a[great--] = ak;
+              break;
+            } else {
+              // comp == 0;
+              a[k] = a[great];
+              a[great--] = ak;
+              // Note: if great < k then we will exit the outer loop and fix
+              // invariant 2 (which we just violated).
+              break;
+            }
+          }
+        }
+      }
+    } else {
+      // We partition the list into three parts:
+      //  1. < pivot1
+      //  2. >= pivot1 && <= pivot2
+      //  3. > pivot2
+      //
+      // During the loop we have:
+      // [ | < pivot1 | >= pivot1 && <= pivot2 | unpartitioned  | > pivot2  | ]
+      //  ^            ^                        ^              ^             ^
+      // left         less                     k              great        right
+      //
+      // a[left] and a[right] are undefined and are filled after the
+      // partitioning.
+      //
+      // Invariants:
+      //   1. for x in ]left, less[ : x < pivot1
+      //   2. for x in [less, k[ : pivot1 <= x && x <= pivot2
+      //   3. for x in ]great, right[ : x > pivot2
+      for (int k = less; k <= great; k++) {
+        var ak = a[k];
+        int comp_pivot1 = compare(ak, pivot1);
+        if (comp_pivot1 < 0) {
+          if (k != less) {
+            a[k] = a[less];
+            a[less] = ak;
+          }
+          less++;
+        } else {
+          int comp_pivot2 = compare(ak, pivot2);
+          if (comp_pivot2 > 0) {
+            while (true) {
+              int comp = compare(a[great], pivot2);
+              if (comp > 0) {
+                great--;
+                if (great < k) break;
+                // This is the only location inside the loop where a new
+                // iteration is started.
+                continue;
+              } else {
+                // a[great] <= pivot2.
+                comp = compare(a[great], pivot1);
+                if (comp < 0) {
+                  // Triple exchange.
+                  a[k] = a[less];
+                  a[less++] = a[great];
+                  a[great--] = ak;
+                } else {
+                  // a[great] >= pivot1.
+                  a[k] = a[great];
+                  a[great--] = ak;
+                }
+                break;
+              }
+            }
+          }
+        }
+      }
+    }
+
+    // Move pivots into their final positions.
+    // We shrunk the list from both sides (a[left] and a[right] have
+    // meaningless values in them) and now we move elements from the first
+    // and third partition into these locations so that we can store the
+    // pivots.
+    a[left] = a[less - 1];
+    a[less - 1] = pivot1;
+    a[right] = a[great + 1];
+    a[great + 1] = pivot2;
+
+    // The list is now partitioned into three partitions:
+    // [ < pivot1   | >= pivot1 && <= pivot2   |  > pivot2   ]
+    //  ^            ^                        ^             ^
+    // left         less                     great        right
+
+    // Recursive descent. (Don't include the pivot values.)
+    _doSort(a, left, less - 2, compare);
+    _doSort(a, great + 2, right, compare);
+
+    if (pivots_are_equal) {
+      // All elements in the second partition are equal to the pivot. No
+      // need to sort them.
+      return;
+    }
+
+    // In theory it should be enough to call _doSort recursively on the second
+    // partition.
+    // The Android source however removes the pivot elements from the recursive
+    // call if the second partition is too large (more than 2/3 of the list).
+    if (less < index1 && great > index5) {
+      while (compare(a[less], pivot1) == 0) {
+        less++;
+      }
+      while (compare(a[great], pivot2) == 0) {
+        great--;
+      }
+
+      // Copy paste of the previous 3-way partitioning with adaptions.
+      //
+      // We partition the list into three parts:
+      //  1. == pivot1
+      //  2. > pivot1 && < pivot2
+      //  3. == pivot2
+      //
+      // During the loop we have:
+      // [ == pivot1 | > pivot1 && < pivot2 | unpartitioned  | == pivot2 ]
+      //              ^                      ^              ^
+      //            less                     k              great
+      //
+      // Invariants:
+      //   1. for x in [ *, less[ : x == pivot1
+      //   2. for x in [less, k[ : pivot1 < x && x < pivot2
+      //   3. for x in ]great, * ] : x == pivot2
+      for (int k = less; k <= great; k++) {
+        var ak = a[k];
+        int comp_pivot1 = compare(ak, pivot1);
+        if (comp_pivot1 == 0) {
+          if (k != less) {
+            a[k] = a[less];
+            a[less] = ak;
+          }
+          less++;
+        } else {
+          int comp_pivot2 = compare(ak, pivot2);
+          if (comp_pivot2 == 0) {
+            while (true) {
+              int comp = compare(a[great], pivot2);
+              if (comp == 0) {
+                great--;
+                if (great < k) break;
+                // This is the only location inside the loop where a new
+                // iteration is started.
+                continue;
+              } else {
+                // a[great] < pivot2.
+                comp = compare(a[great], pivot1);
+                if (comp < 0) {
+                  // Triple exchange.
+                  a[k] = a[less];
+                  a[less++] = a[great];
+                  a[great--] = ak;
+                } else {
+                  // a[great] == pivot1.
+                  a[k] = a[great];
+                  a[great--] = ak;
+                }
+                break;
+              }
+            }
+          }
+        }
+      }
+      // The second partition has now been cleared of pivot elements and looks
+      // as follows:
+      // [  *  |  > pivot1 && < pivot2  | * ]
+      //        ^                      ^
+      //       less                  great
+      // Sort the second partition using recursive descent.
+      _doSort(a, less, great, compare);
+    } else {
+      // The second partition looks as follows:
+      // [  *  |  >= pivot1 && <= pivot2  | * ]
+      //        ^                        ^
+      //       less                    great
+      // Simply sort it by recursive descent.
+      _doSort(a, less, great, compare);
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/internal/symbol.dart b/sdk_nnbd/lib/internal/symbol.dart
new file mode 100644
index 0000000..54d235c
--- /dev/null
+++ b/sdk_nnbd/lib/internal/symbol.dart
@@ -0,0 +1,142 @@
+// 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 dart._internal;
+
+/**
+ * Implementation of [core.Symbol].  This class uses the same name as
+ * a core class so a user can't tell the difference.
+ *
+ * The purpose of this class is to hide [_name] from user code, but
+ * make it accessible to Dart platform code via the static method
+ * [getName].
+ */
+class Symbol implements core.Symbol {
+  final String _name;
+
+  /**
+   * Source of RegExp matching Dart reserved words.
+   *
+   * Reserved words are not allowed as identifiers.
+   */
+  static const String reservedWordRE =
+      r'(?:assert|break|c(?:a(?:se|tch)|lass|on(?:st|tinue))|d(?:efault|o)|'
+      r'e(?:lse|num|xtends)|f(?:alse|inal(?:ly)?|or)|i[fns]|n(?:ew|ull)|'
+      r'ret(?:hrow|urn)|s(?:uper|witch)|t(?:h(?:is|row)|r(?:ue|y))|'
+      r'v(?:ar|oid)|w(?:hile|ith))';
+  /**
+   * Source of RegExp matching any public identifier.
+   *
+   * A public identifier is a valid identifier (not a reserved word)
+   * that doesn't start with '_'.
+   */
+  static const String publicIdentifierRE =
+      r'(?!' '$reservedWordRE' r'\b(?!\$))[a-zA-Z$][\w$]*';
+  /**
+   * Source of RegExp matching any identifier.
+   *
+   * It matches identifiers but not reserved words. The identifiers
+   * may start with '_'.
+   */
+  static const String identifierRE =
+      r'(?!' '$reservedWordRE' r'\b(?!\$))[a-zA-Z$_][\w$]*';
+  /**
+   * Source of RegExp matching a declarable operator names.
+   *
+   * The operators that can be declared using `operator` declarations are
+   * also the only ones allowed as symbols. The name of the operators is
+   * the same as the operator itself except for unary minus, where the name
+   * is "unary-".
+   */
+  static const String operatorRE =
+      r'(?:[\-+*/%&|^]|\[\]=?|==|~/?|<[<=]?|>[>=]?|unary-)';
+
+  // Grammar if symbols:
+  //    symbol ::= qualifiedName | <empty>
+  //    qualifiedName ::= publicIdentifier '.' qualifiedName | name
+  //    name ::= publicIdentifier
+  //           | publicIdentifier '='
+  //           | operator
+  // where publicIdentifier is any valid identifier (not a reserved word)
+  // that isn't private (doesn't start with '_').
+  //
+  // Railroad diagram of the accepted grammar:
+  //
+  //    /----------------\
+  //    |                |
+  //    |          /-[.]-/     /-[=]-\
+  //    \         /           /       \
+  //  -------[id]------------------------->
+  //       \                     /
+  //        \------[operator]---/
+  //            \              /
+  //             \------------/
+  //
+
+  /**
+   * RegExp that validates a non-empty non-private symbol.
+   *
+   * The empty symbol is handled before this regexp is used, and is not
+   * accepted.
+   */
+  static final RegExp publicSymbolPattern = new RegExp(
+      '^(?:$operatorRE\$|$publicIdentifierRE(?:=?\$|[.](?!\$)))+?\$');
+
+  // The grammar of symbols that may be private is the same as for public
+  // symbols, except that "publicIdentifier" is replaced by "identifier",
+  // which matches any identifier.
+
+  /**
+   * RegExp that validates a non-empty symbol.
+   *
+   * Private symbols are accepted.
+   *
+   * The empty symbol is handled before this regexp is used, and is not
+   * accepted.
+   */
+  static final RegExp symbolPattern =
+      new RegExp('^(?:$operatorRE\$|$identifierRE(?:=?\$|[.](?!\$)))+?\$');
+
+  external const Symbol(String name);
+
+  /**
+   * Platform-private method used by the mirror system to create
+   * otherwise invalid names.
+   */
+  const Symbol.unvalidated(this._name);
+
+  // This is called by dart2js.
+  Symbol.validated(String name) : this._name = validatePublicSymbol(name);
+
+  bool operator ==(other) => other is Symbol && _name == other._name;
+
+  external int get hashCode;
+
+  external toString();
+
+  /// Platform-private accessor which cannot be called from user libraries.
+  static String getName(Symbol symbol) => symbol._name;
+
+  static String validatePublicSymbol(String name) {
+    if (name.isEmpty || publicSymbolPattern.hasMatch(name)) return name;
+    if (name.startsWith('_')) {
+      // There may be other private parts in a qualified name than the first
+      // one, but this is a common case that deserves a specific error
+      // message.
+      throw new ArgumentError('"$name" is a private identifier');
+    }
+    throw new ArgumentError('"$name" is not a valid (qualified) symbol name');
+  }
+
+  /**
+   * Checks whether name is a valid symbol name.
+   *
+   * This test allows both private and non-private symbols.
+   */
+  static bool isValidSymbol(String name) {
+    return (name.isEmpty || symbolPattern.hasMatch(name));
+  }
+
+  external static String computeUnmangledName(Symbol symbol);
+}
diff --git a/sdk_nnbd/lib/io/bytes_builder.dart b/sdk_nnbd/lib/io/bytes_builder.dart
new file mode 100644
index 0000000..9113d44
--- /dev/null
+++ b/sdk_nnbd/lib/io/bytes_builder.dart
@@ -0,0 +1,233 @@
+// 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 dart.io;
+
+/**
+ * Builds a list of bytes, allowing bytes and lists of bytes to be added at the
+ * end.
+ *
+ * Used to efficiently collect bytes and lists of bytes.
+ */
+abstract class BytesBuilder {
+  /**
+   * Construct a new empty [BytesBuilder].
+   *
+   * If [copy] is true, the data is always copied when added to the list. If
+   * it [copy] is false, the data is only copied if needed. That means that if
+   * the lists are changed after added to the [BytesBuilder], it may effect the
+   * output. Default is `true`.
+   */
+  factory BytesBuilder({bool copy: true}) {
+    if (copy) {
+      return new _CopyingBytesBuilder();
+    } else {
+      return new _BytesBuilder();
+    }
+  }
+
+  /**
+   * Appends [bytes] to the current contents of the builder.
+   *
+   * Each value of [bytes] will be bit-representation truncated to the range
+   * 0 .. 255.
+   */
+  void add(List<int> bytes);
+
+  /**
+   * Append [byte] to the current contents of the builder.
+   *
+   * The [byte] will be bit-representation truncated to the range 0 .. 255.
+   */
+  void addByte(int byte);
+
+  /**
+   * Returns the contents of `this` and clears `this`.
+   *
+   * The list returned is a view of the internal buffer, limited to the
+   * [length].
+   */
+  Uint8List takeBytes();
+
+  /**
+   * Returns a copy of the current contents of the builder.
+   *
+   * Leaves the contents of the builder intact.
+   */
+  Uint8List toBytes();
+
+  /**
+   * The number of bytes in the builder.
+   */
+  int get length;
+
+  /**
+   * Returns `true` if the buffer is empty.
+   */
+  bool get isEmpty;
+
+  /**
+   * Returns `true` if the buffer is not empty.
+   */
+  bool get isNotEmpty;
+
+  /**
+   * Clear the contents of the builder.
+   */
+  void clear();
+}
+
+class _CopyingBytesBuilder implements BytesBuilder {
+  // Start with 1024 bytes.
+  static const int _initSize = 1024;
+
+  // Safe for reuse because a fixed-length empty list is immutable.
+  static final _emptyList = new Uint8List(0);
+
+  int _length = 0;
+  Uint8List _buffer;
+
+  _CopyingBytesBuilder([int initialCapacity = 0])
+      : _buffer = (initialCapacity <= 0)
+            ? _emptyList
+            : new Uint8List(_pow2roundup(initialCapacity));
+
+  void add(List<int> bytes) {
+    int bytesLength = bytes.length;
+    if (bytesLength == 0) return;
+    int required = _length + bytesLength;
+    if (_buffer.length < required) {
+      _grow(required);
+    }
+    assert(_buffer.length >= required);
+    if (bytes is Uint8List) {
+      _buffer.setRange(_length, required, bytes);
+    } else {
+      for (int i = 0; i < bytesLength; i++) {
+        _buffer[_length + i] = bytes[i];
+      }
+    }
+    _length = required;
+  }
+
+  void addByte(int byte) {
+    if (_buffer.length == _length) {
+      // The grow algorithm always at least doubles.
+      // If we added one to _length it would quadruple unnecessarily.
+      _grow(_length);
+    }
+    assert(_buffer.length > _length);
+    _buffer[_length] = byte;
+    _length++;
+  }
+
+  void _grow(int required) {
+    // We will create a list in the range of 2-4 times larger than
+    // required.
+    int newSize = required * 2;
+    if (newSize < _initSize) {
+      newSize = _initSize;
+    } else {
+      newSize = _pow2roundup(newSize);
+    }
+    var newBuffer = new Uint8List(newSize);
+    newBuffer.setRange(0, _buffer.length, _buffer);
+    _buffer = newBuffer;
+  }
+
+  Uint8List takeBytes() {
+    if (_length == 0) return _emptyList;
+    var buffer = new Uint8List.view(_buffer.buffer, 0, _length);
+    clear();
+    return buffer;
+  }
+
+  Uint8List toBytes() {
+    if (_length == 0) return _emptyList;
+    return new Uint8List.fromList(
+        new Uint8List.view(_buffer.buffer, 0, _length));
+  }
+
+  int get length => _length;
+
+  bool get isEmpty => _length == 0;
+
+  bool get isNotEmpty => _length != 0;
+
+  void clear() {
+    _length = 0;
+    _buffer = _emptyList;
+  }
+
+  static int _pow2roundup(int x) {
+    assert(x > 0);
+    --x;
+    x |= x >> 1;
+    x |= x >> 2;
+    x |= x >> 4;
+    x |= x >> 8;
+    x |= x >> 16;
+    return x + 1;
+  }
+}
+
+class _BytesBuilder implements BytesBuilder {
+  int _length = 0;
+  final List<Uint8List> _chunks = [];
+
+  void add(List<int> bytes) {
+    Uint8List typedBytes;
+    if (bytes is Uint8List) {
+      typedBytes = bytes;
+    } else {
+      typedBytes = new Uint8List.fromList(bytes);
+    }
+    _chunks.add(typedBytes);
+    _length += typedBytes.length;
+  }
+
+  void addByte(int byte) {
+    _chunks.add(new Uint8List(1)..[0] = byte);
+    _length++;
+  }
+
+  Uint8List takeBytes() {
+    if (_length == 0) return _CopyingBytesBuilder._emptyList;
+    if (_chunks.length == 1) {
+      var buffer = _chunks[0];
+      clear();
+      return buffer;
+    }
+    var buffer = new Uint8List(_length);
+    int offset = 0;
+    for (var chunk in _chunks) {
+      buffer.setRange(offset, offset + chunk.length, chunk);
+      offset += chunk.length;
+    }
+    clear();
+    return buffer;
+  }
+
+  Uint8List toBytes() {
+    if (_length == 0) return _CopyingBytesBuilder._emptyList;
+    var buffer = new Uint8List(_length);
+    int offset = 0;
+    for (var chunk in _chunks) {
+      buffer.setRange(offset, offset + chunk.length, chunk);
+      offset += chunk.length;
+    }
+    return buffer;
+  }
+
+  int get length => _length;
+
+  bool get isEmpty => _length == 0;
+
+  bool get isNotEmpty => _length != 0;
+
+  void clear() {
+    _length = 0;
+    _chunks.clear();
+  }
+}
diff --git a/sdk_nnbd/lib/io/common.dart b/sdk_nnbd/lib/io/common.dart
new file mode 100644
index 0000000..77b7587
--- /dev/null
+++ b/sdk_nnbd/lib/io/common.dart
@@ -0,0 +1,117 @@
+// Copyright (c) 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 dart.io;
+
+// Constants used when working with native ports.
+// These must match the constants in runtime/bin/dartutils.h class CObject.
+const int _successResponse = 0;
+const int _illegalArgumentResponse = 1;
+const int _osErrorResponse = 2;
+const int _fileClosedResponse = 3;
+
+const int _errorResponseErrorType = 0;
+const int _osErrorResponseErrorCode = 1;
+const int _osErrorResponseMessage = 2;
+
+// Functions used to receive exceptions from native ports.
+bool _isErrorResponse(response) =>
+    response is List && response[0] != _successResponse;
+
+/**
+ * Returns an Exception or an Error
+ */
+_exceptionFromResponse(response, String message, String path) {
+  assert(_isErrorResponse(response));
+  switch (response[_errorResponseErrorType]) {
+    case _illegalArgumentResponse:
+      return new ArgumentError("$message: $path");
+    case _osErrorResponse:
+      var err = new OSError(response[_osErrorResponseMessage],
+          response[_osErrorResponseErrorCode]);
+      return new FileSystemException(message, path, err);
+    case _fileClosedResponse:
+      return new FileSystemException("File closed", path);
+    default:
+      return new Exception("Unknown error");
+  }
+}
+
+/**
+ * Base class for all IO related exceptions.
+ */
+abstract class IOException implements Exception {
+  String toString() => "IOException";
+}
+
+/**
+  * An [OSError] object holds information about an error from the
+  * operating system.
+  */
+@pragma("vm:entry-point")
+class OSError {
+  /** Constant used to indicate that no OS error code is available. */
+  static const int noErrorCode = -1;
+
+  /// Error message supplied by the operating system. This may be `null` or
+  /// empty if no message is associated with the error.
+  final String message;
+
+  /// Error code supplied by the operating system.
+  ///
+  /// Will have the value [OSError.noErrorCode] if there is no error code
+  /// associated with the error.
+  final int errorCode;
+
+  /** Creates an OSError object from a message and an errorCode. */
+  @pragma("vm:entry-point")
+  const OSError([this.message = "", this.errorCode = noErrorCode]);
+
+  /** Converts an OSError object to a string representation. */
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write("OS Error");
+    if (message.isNotEmpty) {
+      sb..write(": ")..write(message);
+      if (errorCode != noErrorCode) {
+        sb..write(", errno = ")..write(errorCode.toString());
+      }
+    } else if (errorCode != noErrorCode) {
+      sb..write(": errno = ")..write(errorCode.toString());
+    }
+    return sb.toString();
+  }
+}
+
+// Object for holding a buffer and an offset.
+class _BufferAndStart {
+  List<int> buffer;
+  int start;
+  _BufferAndStart(this.buffer, this.start);
+}
+
+// Ensure that the input List can be serialized through a native port.
+// Only Int8List and Uint8List Lists are serialized directly.
+// All other lists are first copied into a Uint8List. This has the added
+// benefit that it is faster to access from the C code as well.
+_BufferAndStart _ensureFastAndSerializableByteData(
+    List<int> buffer, int start, int end) {
+  if (buffer is Uint8List || buffer is Int8List) {
+    return new _BufferAndStart(buffer, start);
+  }
+  int length = end - start;
+  var newBuffer = new Uint8List(length);
+  int j = start;
+  for (int i = 0; i < length; i++) {
+    int value = buffer[j];
+    if (value == null) throw ArgumentError("List element is null at index $j");
+    newBuffer[i] = value;
+    j++;
+  }
+  return new _BufferAndStart(newBuffer, 0);
+}
+
+class _IOCrypto {
+  external static Uint8List getRandomBytes(int count);
+}
diff --git a/sdk_nnbd/lib/io/data_transformer.dart b/sdk_nnbd/lib/io/data_transformer.dart
new file mode 100644
index 0000000..33c615d
--- /dev/null
+++ b/sdk_nnbd/lib/io/data_transformer.dart
@@ -0,0 +1,673 @@
+// 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 dart.io;
+
+/**
+ * Exposes ZLib options for input parameters.
+ *
+ * See http://www.zlib.net/manual.html for more documentation.
+ */
+abstract class ZLibOption {
+  /// Minimal value for [ZLibCodec.windowBits], [ZLibEncoder.windowBits]
+  /// and [ZLibDecoder.windowBits].
+  static const int minWindowBits = 8;
+  @Deprecated("Use minWindowBits instead")
+  static const int MIN_WINDOW_BITS = 8;
+
+  /// Maximal value for [ZLibCodec.windowBits], [ZLibEncoder.windowBits]
+  /// and [ZLibDecoder.windowBits].
+  static const int maxWindowBits = 15;
+  @Deprecated("Use maxWindowBits instead")
+  static const int MAX_WINDOW_BITS = 15;
+
+  /// Default value for [ZLibCodec.windowBits], [ZLibEncoder.windowBits]
+  /// and [ZLibDecoder.windowBits].
+  static const int defaultWindowBits = 15;
+  @Deprecated("Use defaultWindowBits instead")
+  static const int DEFAULT_WINDOW_BITS = 15;
+
+  /// Minimal value for [ZLibCodec.level] and [ZLibEncoder.level].
+  static const int minLevel = -1;
+  @Deprecated("Use minLevel instead")
+  static const int MIN_LEVEL = -1;
+
+  /// Maximal value for [ZLibCodec.level] and [ZLibEncoder.level]
+  static const int maxLevel = 9;
+  @Deprecated("Use maxLevel instead")
+  static const int MAX_LEVEL = 9;
+
+  /// Default value for [ZLibCodec.level] and [ZLibEncoder.level].
+  static const int defaultLevel = 6;
+  @Deprecated("Use defaultLevel instead")
+  static const int DEFAULT_LEVEL = 6;
+
+  /// Minimal value for [ZLibCodec.memLevel] and [ZLibEncoder.memLevel].
+  static const int minMemLevel = 1;
+  @Deprecated("Use minMemLevel instead")
+  static const int MIN_MEM_LEVEL = 1;
+
+  /// Maximal value for [ZLibCodec.memLevel] and [ZLibEncoder.memLevel].
+  static const int maxMemLevel = 9;
+  @Deprecated("Use maxMemLevel instead")
+  static const int MAX_MEM_LEVEL = 9;
+
+  /// Default value for [ZLibCodec.memLevel] and [ZLibEncoder.memLevel].
+  static const int defaultMemLevel = 8;
+  @Deprecated("Use defaultMemLevel instead")
+  static const int DEFAULT_MEM_LEVEL = 8;
+
+  /// Recommended strategy for data produced by a filter (or predictor)
+  static const int strategyFiltered = 1;
+  @Deprecated("Use strategyFiltered instead")
+  static const int STRATEGY_FILTERED = 1;
+
+  /// Use this strategy to force Huffman encoding only (no string match)
+  static const int strategyHuffmanOnly = 2;
+  @Deprecated("Use strategyHuffmanOnly instead")
+  static const int STRATEGY_HUFFMAN_ONLY = 2;
+
+  /// Use this strategy to limit match distances to one (run-length encoding)
+  static const int strategyRle = 3;
+  @Deprecated("Use strategyRle instead")
+  static const int STRATEGY_RLE = 3;
+
+  /// This strategy prevents the use of dynamic Huffman codes, allowing for a
+  /// simpler decoder
+  static const int strategyFixed = 4;
+  @Deprecated("Use strategyFixed instead")
+  static const int STRATEGY_FIXED = 4;
+
+  /// Recommended strategy for normal data
+  static const int strategyDefault = 0;
+  @Deprecated("Use strategyDefault instead")
+  static const int STRATEGY_DEFAULT = 0;
+}
+
+/**
+ * An instance of the default implementation of the [ZLibCodec].
+ */
+const ZLibCodec zlib = const ZLibCodec._default();
+@Deprecated("Use zlib instead")
+const ZLibCodec ZLIB = zlib;
+
+/**
+ * The [ZLibCodec] encodes raw bytes to ZLib compressed bytes and decodes ZLib
+ * compressed bytes to raw bytes.
+ */
+class ZLibCodec extends Codec<List<int>, List<int>> {
+  /**
+   * When true, `GZip` frames will be added to the compressed data.
+   */
+  final bool gzip;
+
+  /**
+   * The compression-[level] can be set in the range of `-1..9`, with `6` being
+   * the default compression level. Levels above `6` will have higher
+   * compression rates at the cost of more CPU and memory usage. Levels below
+   * `6` will use less CPU and memory at the cost of lower compression rates.
+   */
+  final int level;
+
+  /**
+   * Specifies how much memory should be allocated for the internal compression
+   * state. `1` uses minimum memory but is slow and reduces compression ratio;
+   * `9` uses maximum memory for optimal speed. The default value is `8`.
+   *
+   * The memory requirements for deflate are (in bytes):
+   *
+   *     (1 << (windowBits + 2)) +  (1 << (memLevel + 9))
+   * that is: 128K for windowBits = 15 + 128K for memLevel = 8 (default values)
+   */
+  final int memLevel;
+
+  /**
+   * Tunes the compression algorithm. Use the value strategyDefault for normal
+   * data, strategyFiltered for data produced by a filter (or predictor),
+   * strategyHuffmanOnly to force Huffman encoding only (no string match), or
+   * strategyRle to limit match distances to one (run-length encoding).
+   */
+  final int strategy;
+
+  /**
+   * Base two logarithm of the window size (the size of the history buffer). It
+   * should be in the range 8..15. Larger values result in better compression at
+   * the expense of memory usage. The default value is 15
+   */
+  final int windowBits;
+
+  /**
+   * When true, deflate generates raw data with no zlib header or trailer, and
+   * will not compute an adler32 check value
+   */
+  final bool raw;
+
+  /**
+   * Initial compression dictionary.
+   *
+   * It should consist of strings (byte sequences) that are likely to be
+   * encountered later in the data to be compressed, with the most commonly used
+   * strings preferably put towards the end of the dictionary. Using a
+   * dictionary is most useful when the data to be compressed is short and can
+   * be predicted with good accuracy; the data can then be compressed better
+   * than with the default empty dictionary.
+   */
+  final List<int> dictionary;
+
+  ZLibCodec(
+      {this.level: ZLibOption.defaultLevel,
+      this.windowBits: ZLibOption.defaultWindowBits,
+      this.memLevel: ZLibOption.defaultMemLevel,
+      this.strategy: ZLibOption.strategyDefault,
+      this.dictionary,
+      this.raw: false,
+      this.gzip: false}) {
+    _validateZLibeLevel(level);
+    _validateZLibMemLevel(memLevel);
+    _validateZLibStrategy(strategy);
+    _validateZLibWindowBits(windowBits);
+  }
+
+  const ZLibCodec._default()
+      : level = ZLibOption.defaultLevel,
+        windowBits = ZLibOption.defaultWindowBits,
+        memLevel = ZLibOption.defaultMemLevel,
+        strategy = ZLibOption.strategyDefault,
+        raw = false,
+        gzip = false,
+        dictionary = null;
+
+  /**
+   * Get a [ZLibEncoder] for encoding to `ZLib` compressed data.
+   */
+  ZLibEncoder get encoder => new ZLibEncoder(
+      gzip: false,
+      level: level,
+      windowBits: windowBits,
+      memLevel: memLevel,
+      strategy: strategy,
+      dictionary: dictionary,
+      raw: raw);
+
+  /**
+   * Get a [ZLibDecoder] for decoding `ZLib` compressed data.
+   */
+  ZLibDecoder get decoder =>
+      new ZLibDecoder(windowBits: windowBits, dictionary: dictionary, raw: raw);
+}
+
+/**
+ * An instance of the default implementation of the [GZipCodec].
+ */
+const GZipCodec gzip = const GZipCodec._default();
+@Deprecated("Use gzip instead")
+const GZipCodec GZIP = gzip;
+
+/**
+ * The [GZipCodec] encodes raw bytes to GZip compressed bytes and decodes GZip
+ * compressed bytes to raw bytes.
+ *
+ * The difference between [ZLibCodec] and [GZipCodec] is that the [GZipCodec]
+ * wraps the `ZLib` compressed bytes in `GZip` frames.
+ */
+class GZipCodec extends Codec<List<int>, List<int>> {
+  /**
+   * When true, `GZip` frames will be added to the compressed data.
+   */
+  final bool gzip;
+
+  /**
+   * The compression-[level] can be set in the range of `-1..9`, with `6` being
+   * the default compression level. Levels above `6` will have higher
+   * compression rates at the cost of more CPU and memory usage. Levels below
+   * `6` will use less CPU and memory at the cost of lower compression rates.
+   */
+  final int level;
+
+  /**
+   * Specifies how much memory should be allocated for the internal compression
+   * state. `1` uses minimum memory but is slow and reduces compression ratio;
+   * `9` uses maximum memory for optimal speed. The default value is `8`.
+   *
+   * The memory requirements for deflate are (in bytes):
+   *
+   *     (1 << (windowBits + 2)) +  (1 << (memLevel + 9))
+   * that is: 128K for windowBits = 15 + 128K for memLevel = 8 (default values)
+   */
+  final int memLevel;
+
+  /**
+   * Tunes the compression algorithm. Use the value
+   * [ZLibOption.strategyDefault] for normal data,
+   * [ZLibOption.strategyFiltered] for data produced by a filter
+   * (or predictor), [ZLibOption.strategyHuffmanOnly] to force Huffman
+   * encoding only (no string match), or [ZLibOption.strategyRle] to limit
+   * match distances to one (run-length encoding).
+   */
+  final int strategy;
+
+  /**
+   * Base two logarithm of the window size (the size of the history buffer). It
+   * should be in the range `8..15`. Larger values result in better compression
+   * at the expense of memory usage. The default value is `15`
+   */
+  final int windowBits;
+
+  /**
+   * Initial compression dictionary.
+   *
+   * It should consist of strings (byte sequences) that are likely to be
+   * encountered later in the data to be compressed, with the most commonly used
+   * strings preferably put towards the end of the dictionary. Using a
+   * dictionary is most useful when the data to be compressed is short and can
+   * be predicted with good accuracy; the data can then be compressed better
+   * than with the default empty dictionary.
+   */
+  final List<int> dictionary;
+
+  /**
+   * When true, deflate generates raw data with no zlib header or trailer, and
+   * will not compute an adler32 check value
+   */
+  final bool raw;
+
+  GZipCodec(
+      {this.level: ZLibOption.defaultLevel,
+      this.windowBits: ZLibOption.defaultWindowBits,
+      this.memLevel: ZLibOption.defaultMemLevel,
+      this.strategy: ZLibOption.strategyDefault,
+      this.dictionary,
+      this.raw: false,
+      this.gzip: true}) {
+    _validateZLibeLevel(level);
+    _validateZLibMemLevel(memLevel);
+    _validateZLibStrategy(strategy);
+    _validateZLibWindowBits(windowBits);
+  }
+
+  const GZipCodec._default()
+      : level = ZLibOption.defaultLevel,
+        windowBits = ZLibOption.defaultWindowBits,
+        memLevel = ZLibOption.defaultMemLevel,
+        strategy = ZLibOption.strategyDefault,
+        raw = false,
+        gzip = true,
+        dictionary = null;
+
+  /**
+   * Get a [ZLibEncoder] for encoding to `GZip` compressed data.
+   */
+  ZLibEncoder get encoder => new ZLibEncoder(
+      gzip: true,
+      level: level,
+      windowBits: windowBits,
+      memLevel: memLevel,
+      strategy: strategy,
+      dictionary: dictionary,
+      raw: raw);
+
+  /**
+   * Get a [ZLibDecoder] for decoding `GZip` compressed data.
+   */
+  ZLibDecoder get decoder =>
+      new ZLibDecoder(windowBits: windowBits, dictionary: dictionary, raw: raw);
+}
+
+/**
+ * The [ZLibEncoder] encoder is used by [ZLibCodec] and [GZipCodec] to compress
+ * data.
+ */
+class ZLibEncoder extends Converter<List<int>, List<int>> {
+  /**
+   * When true, `GZip` frames will be added to the compressed data.
+   */
+  final bool gzip;
+
+  /**
+   * The compression-[level] can be set in the range of `-1..9`, with `6` being
+   * the default compression level. Levels above `6` will have higher
+   * compression rates at the cost of more CPU and memory usage. Levels below
+   * `6` will use less CPU and memory at the cost of lower compression rates.
+   */
+  final int level;
+
+  /**
+   * Specifies how much memory should be allocated for the internal compression
+   * state. `1` uses minimum memory but is slow and reduces compression ratio;
+   * `9` uses maximum memory for optimal speed. The default value is `8`.
+   *
+   * The memory requirements for deflate are (in bytes):
+   *
+   *     (1 << (windowBits + 2)) +  (1 << (memLevel + 9))
+   * that is: 128K for windowBits = 15 + 128K for memLevel = 8 (default values)
+   */
+  final int memLevel;
+
+  /**
+   * Tunes the compression algorithm. Use the value
+   * [ZLibOption.strategyDefault] for normal data,
+   * [ZLibOption.strategyFiltered] for data produced by a filter
+   * (or predictor), [ZLibOption.strategyHuffmanOnly] to force Huffman
+   * encoding only (no string match), or [ZLibOption.strategyRle] to limit
+   * match distances to one (run-length encoding).
+   */
+  final int strategy;
+
+  /**
+   * Base two logarithm of the window size (the size of the history buffer). It
+   * should be in the range `8..15`. Larger values result in better compression
+   * at the expense of memory usage. The default value is `15`
+   */
+  final int windowBits;
+
+  /**
+   * Initial compression dictionary.
+   *
+   * It should consist of strings (byte sequences) that are likely to be
+   * encountered later in the data to be compressed, with the most commonly used
+   * strings preferably put towards the end of the dictionary. Using a
+   * dictionary is most useful when the data to be compressed is short and can
+   * be predicted with good accuracy; the data can then be compressed better
+   * than with the default empty dictionary.
+   */
+  final List<int> dictionary;
+
+  /**
+   * When true, deflate generates raw data with no zlib header or trailer, and
+   * will not compute an adler32 check value
+   */
+  final bool raw;
+
+  ZLibEncoder(
+      {this.gzip: false,
+      this.level: ZLibOption.defaultLevel,
+      this.windowBits: ZLibOption.defaultWindowBits,
+      this.memLevel: ZLibOption.defaultMemLevel,
+      this.strategy: ZLibOption.strategyDefault,
+      this.dictionary,
+      this.raw: false}) {
+    _validateZLibeLevel(level);
+    _validateZLibMemLevel(memLevel);
+    _validateZLibStrategy(strategy);
+    _validateZLibWindowBits(windowBits);
+  }
+
+  /**
+   * Convert a list of bytes using the options given to the ZLibEncoder
+   * constructor.
+   */
+  List<int> convert(List<int> bytes) {
+    _BufferSink sink = new _BufferSink();
+    startChunkedConversion(sink)
+      ..add(bytes)
+      ..close();
+    return sink.builder.takeBytes();
+  }
+
+  /**
+   * Start a chunked conversion using the options given to the [ZLibEncoder]
+   * constructor. While it accepts any [Sink] taking [List<int>]'s,
+   * the optimal sink to be passed as [sink] is a [ByteConversionSink].
+   */
+  ByteConversionSink startChunkedConversion(Sink<List<int>> sink) {
+    if (sink is! ByteConversionSink) {
+      sink = new ByteConversionSink.from(sink);
+    }
+    return new _ZLibEncoderSink._(
+        sink, gzip, level, windowBits, memLevel, strategy, dictionary, raw);
+  }
+}
+
+/**
+ * The [ZLibDecoder] is used by [ZLibCodec] and [GZipCodec] to decompress data.
+ */
+class ZLibDecoder extends Converter<List<int>, List<int>> {
+  /**
+   * Base two logarithm of the window size (the size of the history buffer). It
+   * should be in the range `8..15`. Larger values result in better compression
+   * at the expense of memory usage. The default value is `15`.
+   */
+  final int windowBits;
+
+  /**
+   * Initial compression dictionary.
+   *
+   * It should consist of strings (byte sequences) that are likely to be
+   * encountered later in the data to be compressed, with the most commonly used
+   * strings preferably put towards the end of the dictionary. Using a
+   * dictionary is most useful when the data to be compressed is short and can
+   * be predicted with good accuracy; the data can then be compressed better
+   * than with the default empty dictionary.
+   */
+  final List<int> dictionary;
+
+  /**
+   * When true, deflate generates raw data with no zlib header or trailer, and
+   * will not compute an adler32 check value
+   */
+  final bool raw;
+
+  ZLibDecoder(
+      {this.windowBits: ZLibOption.defaultWindowBits,
+      this.dictionary,
+      this.raw: false}) {
+    _validateZLibWindowBits(windowBits);
+  }
+
+  /**
+   * Convert a list of bytes using the options given to the [ZLibDecoder]
+   * constructor.
+   */
+  List<int> convert(List<int> bytes) {
+    _BufferSink sink = new _BufferSink();
+    startChunkedConversion(sink)
+      ..add(bytes)
+      ..close();
+    return sink.builder.takeBytes();
+  }
+
+  /**
+   * Start a chunked conversion. While it accepts any [Sink]
+   * taking [List<int>]'s, the optimal sink to be passed as [sink] is a
+   * [ByteConversionSink].
+   */
+  ByteConversionSink startChunkedConversion(Sink<List<int>> sink) {
+    if (sink is! ByteConversionSink) {
+      sink = new ByteConversionSink.from(sink);
+    }
+    return new _ZLibDecoderSink._(sink, windowBits, dictionary, raw);
+  }
+}
+
+/**
+ * The [RawZLibFilter] class provides a low-level interface to zlib.
+ */
+abstract class RawZLibFilter {
+  /**
+   * Returns a a [RawZLibFilter] whose [process] and [processed] methods
+   * compress data.
+   */
+  factory RawZLibFilter.deflateFilter({
+    bool gzip: false,
+    int level: ZLibOption.defaultLevel,
+    int windowBits: ZLibOption.defaultWindowBits,
+    int memLevel: ZLibOption.defaultMemLevel,
+    int strategy: ZLibOption.strategyDefault,
+    List<int> dictionary,
+    bool raw: false,
+  }) {
+    return _makeZLibDeflateFilter(
+        gzip, level, windowBits, memLevel, strategy, dictionary, raw);
+  }
+
+  /**
+   * Returns a a [RawZLibFilter] whose [process] and [processed] methods
+   * decompress data.
+   */
+  factory RawZLibFilter.inflateFilter({
+    int windowBits: ZLibOption.defaultWindowBits,
+    List<int> dictionary,
+    bool raw: false,
+  }) {
+    return _makeZLibInflateFilter(windowBits, dictionary, raw);
+  }
+
+  /**
+   * Call to process a chunk of data. A call to [process] should only be made
+   * when [processed] returns [:null:].
+   */
+  void process(List<int> data, int start, int end);
+
+  /**
+   * Get a chunk of processed data. When there are no more data available,
+   * [processed] will return [:null:]. Set [flush] to [:false:] for non-final
+   * calls to improve performance of some filters.
+   *
+   * The last call to [processed] should have [end] set to [:true:]. This will
+   * make sure an 'end' packet is written on the stream.
+   */
+  List<int> processed({bool flush: true, bool end: false});
+
+  external static RawZLibFilter _makeZLibDeflateFilter(
+      bool gzip,
+      int level,
+      int windowBits,
+      int memLevel,
+      int strategy,
+      List<int> dictionary,
+      bool raw);
+
+  external static RawZLibFilter _makeZLibInflateFilter(
+      int windowBits, List<int> dictionary, bool raw);
+}
+
+class _BufferSink extends ByteConversionSink {
+  final BytesBuilder builder = new BytesBuilder(copy: false);
+
+  void add(List<int> chunk) {
+    builder.add(chunk);
+  }
+
+  void addSlice(List<int> chunk, int start, int end, bool isLast) {
+    if (chunk is Uint8List) {
+      Uint8List list = chunk;
+      builder.add(new Uint8List.view(list.buffer, start, end - start));
+    } else {
+      builder.add(chunk.sublist(start, end));
+    }
+  }
+
+  void close() {}
+}
+
+class _ZLibEncoderSink extends _FilterSink {
+  _ZLibEncoderSink._(
+      ByteConversionSink sink,
+      bool gzip,
+      int level,
+      int windowBits,
+      int memLevel,
+      int strategy,
+      List<int> dictionary,
+      bool raw)
+      : super(
+            sink,
+            RawZLibFilter._makeZLibDeflateFilter(
+                gzip, level, windowBits, memLevel, strategy, dictionary, raw));
+}
+
+class _ZLibDecoderSink extends _FilterSink {
+  _ZLibDecoderSink._(
+      ByteConversionSink sink, int windowBits, List<int> dictionary, bool raw)
+      : super(sink,
+            RawZLibFilter._makeZLibInflateFilter(windowBits, dictionary, raw));
+}
+
+class _FilterSink extends ByteConversionSink {
+  final RawZLibFilter _filter;
+  final ByteConversionSink _sink;
+  bool _closed = false;
+  bool _empty = true;
+
+  _FilterSink(this._sink, this._filter);
+
+  void add(List<int> data) {
+    addSlice(data, 0, data.length, false);
+  }
+
+  void addSlice(List<int> data, int start, int end, bool isLast) {
+    if (_closed) return;
+    if (end == null) throw new ArgumentError.notNull("end");
+    RangeError.checkValidRange(start, end, data.length);
+    try {
+      _empty = false;
+      _BufferAndStart bufferAndStart =
+          _ensureFastAndSerializableByteData(data, start, end);
+      _filter.process(bufferAndStart.buffer, bufferAndStart.start,
+          end - (start - bufferAndStart.start));
+      List<int> out;
+      while ((out = _filter.processed(flush: false)) != null) {
+        _sink.add(out);
+      }
+    } catch (e) {
+      _closed = true;
+      rethrow;
+    }
+
+    if (isLast) close();
+  }
+
+  void close() {
+    if (_closed) return;
+    // Be sure to send process an empty chunk of data. Without this, the empty
+    // message would not have a GZip frame (if compressed with GZip).
+    if (_empty) _filter.process(const [], 0, 0);
+    try {
+      List<int> out;
+      while ((out = _filter.processed(end: true)) != null) {
+        _sink.add(out);
+      }
+    } catch (e) {
+      // TODO(kevmoo): not sure why this isn't a try/finally
+      _closed = true;
+      throw e;
+    }
+    _closed = true;
+    _sink.close();
+  }
+}
+
+void _validateZLibWindowBits(int windowBits) {
+  if (ZLibOption.minWindowBits > windowBits ||
+      ZLibOption.maxWindowBits < windowBits) {
+    throw new RangeError.range(
+        windowBits, ZLibOption.minWindowBits, ZLibOption.maxWindowBits);
+  }
+}
+
+void _validateZLibeLevel(int level) {
+  if (ZLibOption.minLevel > level || ZLibOption.maxLevel < level) {
+    throw new RangeError.range(level, ZLibOption.minLevel, ZLibOption.maxLevel);
+  }
+}
+
+void _validateZLibMemLevel(int memLevel) {
+  if (ZLibOption.minMemLevel > memLevel || ZLibOption.maxMemLevel < memLevel) {
+    throw new RangeError.range(
+        memLevel, ZLibOption.minMemLevel, ZLibOption.maxMemLevel);
+  }
+}
+
+void _validateZLibStrategy(int strategy) {
+  const strategies = const <int>[
+    ZLibOption.strategyFiltered,
+    ZLibOption.strategyHuffmanOnly,
+    ZLibOption.strategyRle,
+    ZLibOption.strategyFixed,
+    ZLibOption.strategyDefault
+  ];
+  if (strategies.indexOf(strategy) == -1) {
+    throw new ArgumentError("Unsupported 'strategy'");
+  }
+}
diff --git a/sdk_nnbd/lib/io/directory.dart b/sdk_nnbd/lib/io/directory.dart
new file mode 100644
index 0000000..2f141cb
--- /dev/null
+++ b/sdk_nnbd/lib/io/directory.dart
@@ -0,0 +1,344 @@
+// Copyright (c) 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 dart.io;
+
+/**
+ * A reference to a directory (or _folder_) on the file system.
+ *
+ * A Directory instance is an object holding a [path] on which operations can
+ * be performed. The path to the directory can be [absolute] or relative.
+ * You can get the parent directory using the getter [parent],
+ * a property inherited from [FileSystemEntity].
+ *
+ * In addition to being used as an instance to access the file system,
+ * Directory has a number of static properties, such as [systemTemp],
+ * which gets the system's temporary directory, and the getter and setter
+ * [current], which you can use to access or change the current directory.
+ *
+ * Create a new Directory object with a pathname to access the specified
+ * directory on the file system from your program.
+ *
+ *     var myDir = new Directory('myDir');
+ *
+ * Most methods in this class occur in synchronous and asynchronous pairs,
+ * for example, [create] and [createSync].
+ * Unless you have a specific reason for using the synchronous version
+ * of a method, prefer the asynchronous version to avoid blocking your program.
+ *
+ * ## Create a directory
+ *
+ * The following code sample creates a directory using the [create] method.
+ * By setting the `recursive` parameter to true, you can create the
+ * named directory and all its necessary parent directories,
+ * if they do not already exist.
+ *
+ *     import 'dart:io';
+ *
+ *     void main() {
+ *       // Creates dir/ and dir/subdir/.
+ *       new Directory('dir/subdir').create(recursive: true)
+ *         // The created directory is returned as a Future.
+ *         .then((Directory directory) {
+ *           print(directory.path);
+ *       });
+ *     }
+ *
+ * ## List a directory
+ *
+ * Use the [list] or [listSync] methods to get the files and directories
+ * contained by a directory.
+ * Set `recursive` to true to recursively list all subdirectories.
+ * Set `followLinks` to true to follow symbolic links.
+ * The list method returns a [Stream] that provides FileSystemEntity
+ * objects. Use the listen callback function to process each object
+ * as it become available.
+ *
+ *     import 'dart:io';
+ *
+ *     void main() {
+ *       // Get the system temp directory.
+ *       var systemTempDir = Directory.systemTemp;
+ *
+ *       // List directory contents, recursing into sub-directories,
+ *       // but not following symbolic links.
+ *       systemTempDir.list(recursive: true, followLinks: false)
+ *         .listen((FileSystemEntity entity) {
+ *           print(entity.path);
+ *         });
+ *     }
+ *
+ * ## The use of Futures
+ *
+ * I/O operations can block a program for some period of time while it waits for
+ * the operation to complete. To avoid this, all
+ * methods involving I/O have an asynchronous variant which returns a [Future].
+ * This future completes when the I/O operation finishes. While the I/O
+ * operation is in progress, the Dart program is not blocked,
+ * and can perform other operations.
+ *
+ * For example,
+ * the [exists] method, which determines whether the directory exists,
+ * returns a boolean value using a Future.
+ * Use `then` to register a callback function, which is called when
+ * the value is ready.
+ *
+ *     import 'dart:io';
+ *
+ *     main() {
+ *       final myDir = new Directory('dir');
+ *       myDir.exists().then((isThere) {
+ *         isThere ? print('exists') : print('non-existent');
+ *       });
+ *     }
+ *
+ *
+ * In addition to exists, the [stat], [rename], and
+ * other methods, return Futures.
+ *
+ * ## Other resources
+ *
+ * * [Dart by Example](https://www.dartlang.org/dart-by-example/#files-directories-and-symlinks)
+ *   provides additional task-oriented code samples that show how to use
+ *   various API from the Directory class and the related [File] class.
+ *
+ * * [I/O for Command-Line
+ *   Apps](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartio---io-for-command-line-apps)
+ *   a section from _A Tour of the Dart Libraries_ covers files and directories.
+ *
+ * * [Write Command-Line Apps](https://www.dartlang.org/docs/tutorials/cmdline/),
+ *   a tutorial about writing command-line apps, includes information about
+ *   files and directories.
+ */
+@pragma("vm:entry-point")
+abstract class Directory implements FileSystemEntity {
+  /**
+   * Gets the path of this directory.
+   */
+  String get path;
+
+  /**
+   * Creates a [Directory] object.
+   *
+   * If [path] is a relative path, it will be interpreted relative to the
+   * current working directory (see [Directory.current]), when used.
+   *
+   * If [path] is an absolute path, it will be immune to changes to the
+   * current working directory.
+   */
+  @pragma("vm:entry-point")
+  factory Directory(String path) {
+    final IOOverrides overrides = IOOverrides.current;
+    if (overrides == null) {
+      return new _Directory(path);
+    }
+    return overrides.createDirectory(path);
+  }
+
+  @pragma("vm:entry-point")
+  factory Directory.fromRawPath(Uint8List path) {
+    // TODO(bkonyi): Handle overrides.
+    return new _Directory.fromRawPath(path);
+  }
+
+  /**
+   * Create a Directory object from a URI.
+   *
+   * If [uri] cannot reference a directory this throws [UnsupportedError].
+   */
+  factory Directory.fromUri(Uri uri) => new Directory(uri.toFilePath());
+
+  /**
+   * Creates a directory object pointing to the current working
+   * directory.
+   */
+  static Directory get current {
+    final IOOverrides overrides = IOOverrides.current;
+    if (overrides == null) {
+      return _Directory.current;
+    }
+    return overrides.getCurrentDirectory();
+  }
+
+  /**
+   * Returns a [Uri] representing the directory's location.
+   *
+   * The returned URI's scheme is always "file" if the entity's [path] is
+   * absolute, otherwise the scheme will be empty.
+   * The returned URI's path always ends in a slash ('/').
+   */
+  Uri get uri;
+
+  /**
+   * Sets the current working directory of the Dart process including
+   * all running isolates. The new value set can be either a [Directory]
+   * or a [String].
+   *
+   * The new value is passed to the OS's system call unchanged, so a
+   * relative path passed as the new working directory will be
+   * resolved by the OS.
+   *
+   * Note that setting the current working directory is a synchronous
+   * operation and that it changes the working directory of *all*
+   * isolates.
+   *
+   * Use this with care - especially when working with asynchronous
+   * operations and multiple isolates. Changing the working directory,
+   * while asynchronous operations are pending or when other isolates
+   * are working with the file system, can lead to unexpected results.
+   */
+  static void set current(path) {
+    final IOOverrides overrides = IOOverrides.current;
+    if (overrides == null) {
+      _Directory.current = path;
+      return;
+    }
+    overrides.setCurrentDirectory(path);
+  }
+
+  /**
+   * Creates the directory with this name.
+   *
+   * If [recursive] is false, only the last directory in the path is
+   * created. If [recursive] is true, all non-existing path components
+   * are created. If the directory already exists nothing is done.
+   *
+   * Returns a [:Future<Directory>:] that completes with this
+   * directory once it has been created. If the directory cannot be
+   * created the future completes with an exception.
+   */
+  Future<Directory> create({bool recursive: false});
+
+  /**
+   * Synchronously creates the directory with this name.
+   *
+   * If [recursive] is false, only the last directory in the path is
+   * created. If [recursive] is true, all non-existing path components
+   * are created. If the directory already exists nothing is done.
+   *
+   * If the directory cannot be created an exception is thrown.
+   */
+  void createSync({bool recursive: false});
+
+  /**
+   * Gets the system temp directory.
+   *
+   * Gets the directory provided by the operating system for creating
+   * temporary files and directories in.
+   * The location of the system temp directory is platform-dependent,
+   * and may be set by an environment variable.
+   */
+  static Directory get systemTemp {
+    final IOOverrides overrides = IOOverrides.current;
+    if (overrides == null) {
+      return _Directory.systemTemp;
+    }
+    return overrides.getSystemTempDirectory();
+  }
+
+  /**
+   * Creates a temporary directory in this directory. Additional random
+   * characters are appended to [prefix] to produce a unique directory
+   * name. If [prefix] is missing or null, the empty string is used
+   * for [prefix].
+   *
+   * Returns a [:Future<Directory>:] that completes with the newly
+   * created temporary directory.
+   */
+  Future<Directory> createTemp([String prefix]);
+
+  /**
+   * Synchronously creates a temporary directory in this directory.
+   * Additional random characters are appended to [prefix] to produce
+   * a unique directory name. If [prefix] is missing or null, the empty
+   * string is used for [prefix].
+   *
+   * Returns the newly created temporary directory.
+   */
+  Directory createTempSync([String prefix]);
+
+  Future<String> resolveSymbolicLinks();
+
+  String resolveSymbolicLinksSync();
+
+  /**
+   * Renames this directory. Returns a [:Future<Directory>:] that completes
+   * with a [Directory] instance for the renamed directory.
+   *
+   * If newPath identifies an existing directory, that directory is
+   * replaced. If newPath identifies an existing file, the operation
+   * fails and the future completes with an exception.
+   */
+  Future<Directory> rename(String newPath);
+
+  /**
+   * Synchronously renames this directory. Returns a [Directory]
+   * instance for the renamed directory.
+   *
+   * If newPath identifies an existing directory, that directory is
+   * replaced. If newPath identifies an existing file the operation
+   * fails and an exception is thrown.
+   */
+  Directory renameSync(String newPath);
+
+  /**
+   * Returns a [Directory] instance whose path is the absolute path to [this].
+   *
+   * The absolute path is computed by prefixing
+   * a relative path with the current working directory, and returning
+   * an absolute path unchanged.
+   */
+  Directory get absolute;
+
+  /**
+   * Lists the sub-directories and files of this [Directory].
+   * Optionally recurses into sub-directories.
+   *
+   * If [followLinks] is false, then any symbolic links found
+   * are reported as [Link] objects, rather than as directories or files,
+   * and are not recursed into.
+   *
+   * If [followLinks] is true, then working links are reported as
+   * directories or files, depending on
+   * their type, and links to directories are recursed into.
+   * Broken links are reported as [Link] objects.
+   * If a symbolic link makes a loop in the file system, then a recursive
+   * listing will not follow a link twice in the
+   * same recursive descent, but will report it as a [Link]
+   * the second time it is seen.
+   *
+   * The result is a stream of [FileSystemEntity] objects
+   * for the directories, files, and links.
+   */
+  Stream<FileSystemEntity> list(
+      {bool recursive: false, bool followLinks: true});
+
+  /**
+   * Lists the sub-directories and files of this [Directory].
+   * Optionally recurses into sub-directories.
+   *
+   * If [followLinks] is false, then any symbolic links found
+   * are reported as [Link] objects, rather than as directories or files,
+   * and are not recursed into.
+   *
+   * If [followLinks] is true, then working links are reported as
+   * directories or files, depending on
+   * their type, and links to directories are recursed into.
+   * Broken links are reported as [Link] objects.
+   * If a link makes a loop in the file system, then a recursive
+   * listing will not follow a link twice in the
+   * same recursive descent, but will report it as a [Link]
+   * the second time it is seen.
+   *
+   * Returns a [List] containing [FileSystemEntity] objects for the
+   * directories, files, and links.
+   */
+  List<FileSystemEntity> listSync(
+      {bool recursive: false, bool followLinks: true});
+
+  /**
+   * Returns a human readable string for this Directory instance.
+   */
+  String toString();
+}
diff --git a/sdk_nnbd/lib/io/directory_impl.dart b/sdk_nnbd/lib/io/directory_impl.dart
new file mode 100644
index 0000000..faed892
--- /dev/null
+++ b/sdk_nnbd/lib/io/directory_impl.dart
@@ -0,0 +1,447 @@
+// Copyright (c) 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 dart.io;
+
+class _Directory extends FileSystemEntity implements Directory {
+  String _path;
+  Uint8List _rawPath;
+
+  _Directory(String path) {
+    ArgumentError.checkNotNull(path, 'path');
+    _path = path;
+    _rawPath = FileSystemEntity._toUtf8Array(_path);
+  }
+
+  _Directory.fromRawPath(Uint8List rawPath) {
+    if (rawPath == null) {
+      throw new ArgumentError('rawPath cannot be null');
+    }
+    _rawPath = FileSystemEntity._toNullTerminatedUtf8Array(rawPath);
+    _path = FileSystemEntity._toStringFromUtf8Array(rawPath);
+  }
+
+  String get path => _path;
+
+  external static _current(_Namespace namespace);
+  external static _setCurrent(_Namespace namespace, Uint8List rawPath);
+  external static _createTemp(_Namespace namespace, Uint8List rawPath);
+  external static String _systemTemp(_Namespace namespace);
+  external static _exists(_Namespace namespace, Uint8List rawPath);
+  external static _create(_Namespace namespace, Uint8List rawPath);
+  external static _deleteNative(
+      _Namespace namespace, Uint8List rawPath, bool recursive);
+  external static _rename(
+      _Namespace namespace, Uint8List rawPath, String newPath);
+  external static void _fillWithDirectoryListing(
+      _Namespace namespace,
+      List<FileSystemEntity> list,
+      Uint8List rawPath,
+      bool recursive,
+      bool followLinks);
+
+  static Directory get current {
+    var result = _current(_Namespace._namespace);
+    if (result is OSError) {
+      throw new FileSystemException(
+          "Getting current working directory failed", "", result);
+    }
+    return new _Directory(result);
+  }
+
+  static void set current(path) {
+    Uint8List _rawPath;
+    if (path is _Directory) {
+      // For our internal Directory implementation, go ahead and use the raw
+      // path.
+      _rawPath = path._rawPath;
+    } else if (path is Directory) {
+      // FIXME(bkonyi): package:file passes in instances of classes which do
+      // not have _path defined, so we will fallback to using the existing
+      // path String for now.
+      _rawPath = FileSystemEntity._toUtf8Array(path.path);
+    } else if (path is String) {
+      _rawPath = FileSystemEntity._toUtf8Array(path);
+    } else {
+      throw new ArgumentError('${Error.safeToString(path)} is not a String or'
+          ' Directory');
+    }
+    if (!_EmbedderConfig._mayChdir) {
+      throw new UnsupportedError(
+          "This embedder disallows setting Directory.current");
+    }
+    var result = _setCurrent(_Namespace._namespace, _rawPath);
+    if (result is ArgumentError) throw result;
+    if (result is OSError) {
+      throw new FileSystemException(
+          "Setting current working directory failed", path, result);
+    }
+  }
+
+  Uri get uri {
+    return new Uri.directory(path);
+  }
+
+  Future<bool> exists() {
+    return _File._dispatchWithNamespace(
+        _IOService.directoryExists, [null, _rawPath]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionOrErrorFromResponse(response, "Exists failed");
+      }
+      return response == 1;
+    });
+  }
+
+  bool existsSync() {
+    var result = _exists(_Namespace._namespace, _rawPath);
+    if (result is OSError) {
+      throw new FileSystemException("Exists failed", path, result);
+    }
+    return (result == 1);
+  }
+
+  Directory get absolute => new Directory(_absolutePath);
+
+  Future<Directory> create({bool recursive: false}) {
+    if (recursive) {
+      return exists().then((exists) {
+        if (exists) return this;
+        if (path != parent.path) {
+          return parent.create(recursive: true).then((_) {
+            return create();
+          });
+        } else {
+          return create();
+        }
+      });
+    } else {
+      return _File._dispatchWithNamespace(
+          _IOService.directoryCreate, [null, _rawPath]).then((response) {
+        if (_isErrorResponse(response)) {
+          throw _exceptionOrErrorFromResponse(response, "Creation failed");
+        }
+        return this;
+      });
+    }
+  }
+
+  void createSync({bool recursive: false}) {
+    if (recursive) {
+      if (existsSync()) return;
+      if (path != parent.path) {
+        parent.createSync(recursive: true);
+      }
+    }
+    var result = _create(_Namespace._namespace, _rawPath);
+    if (result is OSError) {
+      throw new FileSystemException("Creation failed", path, result);
+    }
+  }
+
+  static Directory get systemTemp =>
+      new Directory(_systemTemp(_Namespace._namespace));
+
+  Future<Directory> createTemp([String prefix]) {
+    prefix ??= '';
+    if (path == '') {
+      throw new ArgumentError("Directory.createTemp called with an empty path. "
+          "To use the system temp directory, use Directory.systemTemp");
+    }
+    String fullPrefix;
+    // FIXME(bkonyi): here we're using `path` directly, which might cause
+    // issues if it is not UTF-8 encoded.
+    if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) {
+      fullPrefix = "$path$prefix";
+    } else {
+      fullPrefix = "$path${Platform.pathSeparator}$prefix";
+    }
+    return _File._dispatchWithNamespace(_IOService.directoryCreateTemp,
+        [null, FileSystemEntity._toUtf8Array(fullPrefix)]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionOrErrorFromResponse(
+            response, "Creation of temporary directory failed");
+      }
+      return new Directory(response);
+    });
+  }
+
+  Directory createTempSync([String prefix]) {
+    prefix ??= '';
+    if (path == '') {
+      throw new ArgumentError("Directory.createTemp called with an empty path. "
+          "To use the system temp directory, use Directory.systemTemp");
+    }
+    String fullPrefix;
+    // FIXME(bkonyi): here we're using `path` directly, which might cause
+    // issues if it is not UTF-8 encoded.
+    if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) {
+      fullPrefix = "$path$prefix";
+    } else {
+      fullPrefix = "$path${Platform.pathSeparator}$prefix";
+    }
+    var result = _createTemp(
+        _Namespace._namespace, FileSystemEntity._toUtf8Array(fullPrefix));
+    if (result is OSError) {
+      throw new FileSystemException(
+          "Creation of temporary directory failed", fullPrefix, result);
+    }
+    return new Directory(result);
+  }
+
+  Future<Directory> _delete({bool recursive: false}) {
+    return _File._dispatchWithNamespace(
+            _IOService.directoryDelete, [null, _rawPath, recursive])
+        .then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionOrErrorFromResponse(response, "Deletion failed");
+      }
+      return this;
+    });
+  }
+
+  void _deleteSync({bool recursive: false}) {
+    var result = _deleteNative(_Namespace._namespace, _rawPath, recursive);
+    if (result is OSError) {
+      throw new FileSystemException("Deletion failed", path, result);
+    }
+  }
+
+  Future<Directory> rename(String newPath) {
+    return _File._dispatchWithNamespace(
+        _IOService.directoryRename, [null, _rawPath, newPath]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionOrErrorFromResponse(response, "Rename failed");
+      }
+      return new Directory(newPath);
+    });
+  }
+
+  Directory renameSync(String newPath) {
+    if (newPath is! String) {
+      throw new ArgumentError();
+    }
+    var result = _rename(_Namespace._namespace, _rawPath, newPath);
+    if (result is OSError) {
+      throw new FileSystemException("Rename failed", path, result);
+    }
+    return new Directory(newPath);
+  }
+
+  Stream<FileSystemEntity> list(
+      {bool recursive: false, bool followLinks: true}) {
+    return new _AsyncDirectoryLister(
+            // FIXME(bkonyi): here we're using `path` directly, which might cause issues
+            // if it is not UTF-8 encoded.
+            FileSystemEntity._toUtf8Array(
+                FileSystemEntity._ensureTrailingPathSeparators(path)),
+            recursive,
+            followLinks)
+        .stream;
+  }
+
+  List<FileSystemEntity> listSync(
+      {bool recursive: false, bool followLinks: true}) {
+    if (recursive is! bool || followLinks is! bool) {
+      throw new ArgumentError();
+    }
+    var result = <FileSystemEntity>[];
+    _fillWithDirectoryListing(
+        _Namespace._namespace,
+        result,
+        // FIXME(bkonyi): here we're using `path` directly, which might cause issues
+        // if it is not UTF-8 encoded.
+        FileSystemEntity._toUtf8Array(
+            FileSystemEntity._ensureTrailingPathSeparators(path)),
+        recursive,
+        followLinks);
+    return result;
+  }
+
+  String toString() => "Directory: '$path'";
+
+  bool _isErrorResponse(response) =>
+      response is List && response[0] != _successResponse;
+
+  _exceptionOrErrorFromResponse(response, String message) {
+    assert(_isErrorResponse(response));
+    switch (response[_errorResponseErrorType]) {
+      case _illegalArgumentResponse:
+        return new ArgumentError();
+      case _osErrorResponse:
+        var err = new OSError(response[_osErrorResponseMessage],
+            response[_osErrorResponseErrorCode]);
+        return new FileSystemException(message, path, err);
+      default:
+        return new Exception("Unknown error");
+    }
+  }
+}
+
+abstract class _AsyncDirectoryListerOps {
+  external factory _AsyncDirectoryListerOps(int pointer);
+
+  int getPointer();
+}
+
+class _AsyncDirectoryLister {
+  static const int listFile = 0;
+  static const int listDirectory = 1;
+  static const int listLink = 2;
+  static const int listError = 3;
+  static const int listDone = 4;
+
+  static const int responseType = 0;
+  static const int responsePath = 1;
+  static const int responseComplete = 1;
+  static const int responseError = 2;
+
+  final Uint8List rawPath;
+  final bool recursive;
+  final bool followLinks;
+
+  StreamController<FileSystemEntity> controller;
+  bool canceled = false;
+  bool nextRunning = false;
+  bool closed = false;
+  _AsyncDirectoryListerOps _ops;
+  Completer closeCompleter = new Completer();
+
+  _AsyncDirectoryLister(this.rawPath, this.recursive, this.followLinks) {
+    controller = new StreamController<FileSystemEntity>(
+        onListen: onListen, onResume: onResume, onCancel: onCancel, sync: true);
+  }
+
+  // WARNING:
+  // Calling this function will increase the reference count on the native
+  // object that implements the async directory lister operations. It should
+  // only be called to pass the pointer to the IO Service, which will decrement
+  // the reference count when it is finished with it.
+  int _pointer() {
+    return (_ops == null) ? null : _ops.getPointer();
+  }
+
+  Stream<FileSystemEntity> get stream => controller.stream;
+
+  void onListen() {
+    _File._dispatchWithNamespace(_IOService.directoryListStart,
+        [null, rawPath, recursive, followLinks]).then((response) {
+      if (response is int) {
+        _ops = new _AsyncDirectoryListerOps(response);
+        next();
+      } else if (response is Error) {
+        controller.addError(response, response.stackTrace);
+        close();
+      } else {
+        error(response);
+        close();
+      }
+    });
+  }
+
+  void onResume() {
+    if (!nextRunning) {
+      next();
+    }
+  }
+
+  Future onCancel() {
+    canceled = true;
+    // If we are active, but not requesting, close.
+    if (!nextRunning) {
+      close();
+    }
+
+    return closeCompleter.future;
+  }
+
+  void next() {
+    if (canceled) {
+      close();
+      return;
+    }
+    if (controller.isPaused || nextRunning) {
+      return;
+    }
+    var pointer = _pointer();
+    if (pointer == null) {
+      return;
+    }
+    nextRunning = true;
+    _IOService._dispatch(_IOService.directoryListNext, [pointer])
+        .then((result) {
+      nextRunning = false;
+      if (result is List) {
+        next();
+        assert(result.length % 2 == 0);
+        for (int i = 0; i < result.length; i++) {
+          assert(i % 2 == 0);
+          switch (result[i++]) {
+            case listFile:
+              controller.add(new File.fromRawPath(result[i]));
+              break;
+            case listDirectory:
+              controller.add(new Directory.fromRawPath(result[i]));
+              break;
+            case listLink:
+              controller.add(new Link.fromRawPath(result[i]));
+              break;
+            case listError:
+              error(result[i]);
+              break;
+            case listDone:
+              canceled = true;
+              return;
+          }
+        }
+      } else {
+        controller.addError(new FileSystemException("Internal error"));
+      }
+    });
+  }
+
+  void _cleanup() {
+    controller.close();
+    closeCompleter.complete();
+    _ops = null;
+  }
+
+  void close() {
+    if (closed) {
+      return;
+    }
+    if (nextRunning) {
+      return;
+    }
+    closed = true;
+
+    var pointer = _pointer();
+    if (pointer == null) {
+      _cleanup();
+    } else {
+      _IOService._dispatch(_IOService.directoryListStop, [pointer])
+          .whenComplete(_cleanup);
+    }
+  }
+
+  void error(message) {
+    var errorType = message[responseError][_errorResponseErrorType];
+    if (errorType == _illegalArgumentResponse) {
+      controller.addError(new ArgumentError());
+    } else if (errorType == _osErrorResponse) {
+      var responseErrorInfo = message[responseError];
+      var err = new OSError(responseErrorInfo[_osErrorResponseMessage],
+          responseErrorInfo[_osErrorResponseErrorCode]);
+      var errorPath = message[responsePath];
+      if (errorPath == null) {
+        errorPath = utf8.decode(rawPath, allowMalformed: true);
+      } else if (errorPath is Uint8List) {
+        errorPath = utf8.decode(message[responsePath], allowMalformed: true);
+      }
+      controller.addError(
+          new FileSystemException("Directory listing failed", errorPath, err));
+    } else {
+      controller.addError(new FileSystemException("Internal error"));
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/io/embedder_config.dart b/sdk_nnbd/lib/io/embedder_config.dart
new file mode 100644
index 0000000..cbc94f7
--- /dev/null
+++ b/sdk_nnbd/lib/io/embedder_config.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.io;
+
+/// Embedder-specific, fine-grained dart:io configuration.
+///
+/// This class contains per-Isolate flags that an embedder can set to put
+/// fine-grained limitations on what process-visible operations Isolates are
+/// permitted to use (e.g. exit()). By default, the whole dart:io API is
+/// enabled. When a disallowed operation is attempted, an `UnsupportedError` is
+/// thrown.
+@pragma('vm:entry-point')
+abstract class _EmbedderConfig {
+  /// The Isolate may set Directory.current.
+  static bool _mayChdir = true;
+
+  /// The Isolate may call exit().
+  @pragma("vm:entry-point")
+  static bool _mayExit = true;
+
+  // The Isolate may set Stdin.echoMode.
+  @pragma('vm:entry-point')
+  static bool _maySetEchoMode = true;
+
+  // The Isolate may set Stdin.lineMode.
+  @pragma('vm:entry-point')
+  static bool _maySetLineMode = true;
+
+  /// The Isolate may call sleep().
+  @pragma('vm:entry-point')
+  static bool _maySleep = true;
+
+  // TODO(zra): Consider adding:
+  // - an option to disallow modifying SecurityContext.defaultContext
+  // - an option to disallow closing stdout and stderr.
+}
diff --git a/sdk_nnbd/lib/io/eventhandler.dart b/sdk_nnbd/lib/io/eventhandler.dart
new file mode 100644
index 0000000..36f54e6
--- /dev/null
+++ b/sdk_nnbd/lib/io/eventhandler.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 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 dart.io;
+
+class _EventHandler {
+  external static void _sendData(Object sender, SendPort sendPort, int data);
+}
diff --git a/sdk_nnbd/lib/io/file.dart b/sdk_nnbd/lib/io/file.dart
new file mode 100644
index 0000000..861ce47
--- /dev/null
+++ b/sdk_nnbd/lib/io/file.dart
@@ -0,0 +1,1010 @@
+// 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 dart.io;
+
+/**
+ * The modes in which a File can be opened.
+ */
+class FileMode {
+  /// The mode for opening a file only for reading.
+  static const read = const FileMode._internal(0);
+  @Deprecated("Use read instead")
+  static const READ = read;
+
+  /// Mode for opening a file for reading and writing. The file is
+  /// overwritten if it already exists. The file is created if it does not
+  /// already exist.
+  static const write = const FileMode._internal(1);
+  @Deprecated("Use write instead")
+  static const WRITE = write;
+
+  /// Mode for opening a file for reading and writing to the
+  /// end of it. The file is created if it does not already exist.
+  static const append = const FileMode._internal(2);
+  @Deprecated("Use append instead")
+  static const APPEND = append;
+
+  /// Mode for opening a file for writing *only*. The file is
+  /// overwritten if it already exists. The file is created if it does not
+  /// already exist.
+  static const writeOnly = const FileMode._internal(3);
+  @Deprecated("Use writeOnly instead")
+  static const WRITE_ONLY = writeOnly;
+
+  /// Mode for opening a file for writing *only* to the
+  /// end of it. The file is created if it does not already exist.
+  static const writeOnlyAppend = const FileMode._internal(4);
+  @Deprecated("Use writeOnlyAppend instead")
+  static const WRITE_ONLY_APPEND = writeOnlyAppend;
+
+  final int _mode;
+
+  const FileMode._internal(this._mode);
+}
+
+/// The mode for opening a file only for reading.
+@Deprecated("Use FileMode.read instead")
+const READ = FileMode.read;
+
+/// The mode for opening a file for reading and writing. The file is
+/// overwritten if it already exists. The file is created if it does not
+/// already exist.
+@Deprecated("Use FileMode.write instead")
+const WRITE = FileMode.write;
+
+/// The mode for opening a file for reading and writing to the
+/// end of it. The file is created if it does not already exist.
+@Deprecated("Use FileMode.append instead")
+const APPEND = FileMode.append;
+
+/// Mode for opening a file for writing *only*. The file is
+/// overwritten if it already exists. The file is created if it does not
+/// already exist.
+@Deprecated("Use FileMode.writeOnly instead")
+const WRITE_ONLY = FileMode.writeOnly;
+
+/// Mode for opening a file for writing *only* to the
+/// end of it. The file is created if it does not already exist.
+@Deprecated("Use FileMode.writeOnlyAppend instead")
+const WRITE_ONLY_APPEND = FileMode.writeOnlyAppend;
+
+/// Type of lock when requesting a lock on a file.
+class FileLock {
+  /// Shared file lock.
+  static const shared = const FileLock._internal(1);
+  @Deprecated("Use shared instead")
+  static const SHARED = shared;
+
+  /// Exclusive file lock.
+  static const exclusive = const FileLock._internal(2);
+  @Deprecated("Use exclusive instead")
+  static const EXCLUSIVE = exclusive;
+
+  /// Blocking shared file lock.
+  static const blockingShared = const FileLock._internal(3);
+  @Deprecated("Use blockingShared instead")
+  static const BLOCKING_SHARED = blockingShared;
+
+  /// Blocking exclusive file lock.
+  static const blockingExclusive = const FileLock._internal(4);
+  @Deprecated("Use blockingExclusive instead")
+  static const BLOCKING_EXCLUSIVE = blockingExclusive;
+
+  final int _type;
+
+  const FileLock._internal(this._type);
+}
+
+/**
+ * A reference to a file on the file system.
+ *
+ * A File instance is an object that holds a [path] on which operations can
+ * be performed.
+ * You can get the parent directory of the file using the getter [parent],
+ * a property inherited from [FileSystemEntity].
+ *
+ * Create a new File object with a pathname to access the specified file on the
+ * file system from your program.
+ *
+ *     var myFile = new File('file.txt');
+ *
+ * The File class contains methods for manipulating files and their contents.
+ * Using methods in this class, you can open and close files, read to and write
+ * from them, create and delete them, and check for their existence.
+ *
+ * When reading or writing a file, you can use streams (with [openRead]),
+ * random access operations (with [open]),
+ * or convenience methods such as [readAsString],
+ *
+ * Most methods in this class occur in synchronous and asynchronous pairs,
+ * for example, [readAsString] and [readAsStringSync].
+ * Unless you have a specific reason for using the synchronous version
+ * of a method, prefer the asynchronous version to avoid blocking your program.
+ *
+ * ## If path is a link
+ *
+ * If [path] is a symbolic link, rather than a file,
+ * then the methods of File operate on the ultimate target of the
+ * link, except for [delete] and [deleteSync], which operate on
+ * the link.
+ *
+ * ## Read from a file
+ *
+ * The following code sample reads the entire contents from a file as a string
+ * using the asynchronous [readAsString] method:
+ *
+ *     import 'dart:async';
+ *     import 'dart:io';
+ *
+ *     void main() {
+ *       new File('file.txt').readAsString().then((String contents) {
+ *         print(contents);
+ *       });
+ *     }
+ *
+ * A more flexible and useful way to read a file is with a [Stream].
+ * Open the file with [openRead], which returns a stream that
+ * provides the data in the file as chunks of bytes.
+ * Listen to the stream for data and process as needed.
+ * You can use various transformers in succession to manipulate the
+ * data into the required format or to prepare it for output.
+ *
+ * You might want to use a stream to read large files,
+ * to manipulate the data with transformers,
+ * or for compatibility with another API, such as [WebSocket]s.
+ *
+ *     import 'dart:io';
+ *     import 'dart:convert';
+ *     import 'dart:async';
+ *
+ *     main() {
+ *       final file = new File('file.txt');
+ *       Stream<List<int>> inputStream = file.openRead();
+ *
+ *       inputStream
+ *         .transform(utf8.decoder)       // Decode bytes to UTF-8.
+ *         .transform(new LineSplitter()) // Convert stream to individual lines.
+ *         .listen((String line) {        // Process results.
+ *             print('$line: ${line.length} bytes');
+ *           },
+ *           onDone: () { print('File is now closed.'); },
+ *           onError: (e) { print(e.toString()); });
+ *     }
+ *
+ * ## Write to a file
+ *
+ * To write a string to a file, use the [writeAsString] method:
+ *
+ *     import 'dart:io';
+ *
+ *     void main() {
+ *       final filename = 'file.txt';
+ *       new File(filename).writeAsString('some content')
+ *         .then((File file) {
+ *           // Do something with the file.
+ *         });
+ *     }
+ *
+ * You can also write to a file using a [Stream]. Open the file with
+ * [openWrite], which returns an [IOSink] to which you can write data.
+ * Be sure to close the sink with the [IOSink.close] method.
+ *
+ *     import 'dart:io';
+ *
+ *     void main() {
+ *       var file = new File('file.txt');
+ *       var sink = file.openWrite();
+ *       sink.write('FILE ACCESSED ${new DateTime.now()}\n');
+ *
+ *       // Close the IOSink to free system resources.
+ *       sink.close();
+ *     }
+ *
+ * ## The use of Futures
+ *
+ * To avoid unintentional blocking of the program,
+ * several methods use a [Future] to return a value. For example,
+ * the [length] method, which gets the length of a file, returns a Future.
+ * Use `then` to register a callback function, which is called when
+ * the value is ready.
+ *
+ *     import 'dart:io';
+ *
+ *     main() {
+ *       final file = new File('file.txt');
+ *
+ *       file.length().then((len) {
+ *         print(len);
+ *       });
+ *     }
+ *
+ * In addition to length, the [exists], [lastModified], [stat], and
+ * other methods, return Futures.
+ *
+ * ## Other resources
+ *
+ * * [Dart by Example](https://www.dartlang.org/dart-by-example/#files-directories-and-symlinks)
+ *   provides additional task-oriented code samples that show how to use
+ *   various API from the Directory class and the related [File] class.
+ *
+ * * [I/O for Command-Line
+ *   Apps](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartio---io-for-command-line-apps)
+ *   a section from _A Tour of the Dart Libraries_ covers files and directories.
+ *
+ * * [Write Command-Line Apps](https://www.dartlang.org/docs/tutorials/cmdline/),
+ *   a tutorial about writing command-line apps, includes information about
+ *   files and directories.
+ */
+@pragma("vm:entry-point")
+abstract class File implements FileSystemEntity {
+  /**
+   * Creates a [File] object.
+   *
+   * If [path] is a relative path, it will be interpreted relative to the
+   * current working directory (see [Directory.current]), when used.
+   *
+   * If [path] is an absolute path, it will be immune to changes to the
+   * current working directory.
+   */
+  @pragma("vm:entry-point")
+  factory File(String path) {
+    final IOOverrides overrides = IOOverrides.current;
+    if (overrides == null) {
+      return new _File(path);
+    }
+    return overrides.createFile(path);
+  }
+
+  /**
+   * Create a File object from a URI.
+   *
+   * If [uri] cannot reference a file this throws [UnsupportedError].
+   */
+  factory File.fromUri(Uri uri) => new File(uri.toFilePath());
+
+  /**
+   * Creates a File object from a raw path, that is, a sequence of bytes
+   * as represented by the OS.
+   */
+  @pragma("vm:entry-point")
+  factory File.fromRawPath(Uint8List rawPath) {
+    // TODO(bkonyi): Handle overrides.
+    return new _File.fromRawPath(rawPath);
+  }
+
+  /**
+   * Create the file. Returns a `Future<File>` that completes with
+   * the file when it has been created.
+   *
+   * If [recursive] is false, the default, the file is created only if
+   * all directories in the path exist. If [recursive] is true, all
+   * non-existing path components are created.
+   *
+   * Existing files are left untouched by [create]. Calling [create] on an
+   * existing file might fail if there are restrictive permissions on
+   * the file.
+   *
+   * Completes the future with a [FileSystemException] if the operation fails.
+   */
+  Future<File> create({bool recursive: false});
+
+  /**
+   * Synchronously create the file. Existing files are left untouched
+   * by [createSync]. Calling [createSync] on an existing file might fail
+   * if there are restrictive permissions on the file.
+   *
+   * If [recursive] is false, the default, the file is created
+   * only if all directories in the path exist.
+   * If [recursive] is true, all non-existing path components are created.
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  void createSync({bool recursive: false});
+
+  /**
+   * Renames this file. Returns a `Future<File>` that completes
+   * with a [File] instance for the renamed file.
+   *
+   * If [newPath] identifies an existing file, that file is
+   * replaced. If [newPath] identifies an existing directory, the
+   * operation fails and the future completes with an exception.
+   */
+  Future<File> rename(String newPath);
+
+  /**
+   * Synchronously renames this file. Returns a [File]
+   * instance for the renamed file.
+   *
+   * If [newPath] identifies an existing file, that file is
+   * replaced. If [newPath] identifies an existing directory the
+   * operation fails and an exception is thrown.
+   */
+  File renameSync(String newPath);
+
+  /**
+   * Copy this file. Returns a `Future<File>` that completes
+   * with a [File] instance for the copied file.
+   *
+   * If [newPath] identifies an existing file, that file is
+   * replaced. If [newPath] identifies an existing directory, the
+   * operation fails and the future completes with an exception.
+   */
+  Future<File> copy(String newPath);
+
+  /**
+   * Synchronously copy this file. Returns a [File]
+   * instance for the copied file.
+   *
+   * If [newPath] identifies an existing file, that file is
+   * replaced. If [newPath] identifies an existing directory the
+   * operation fails and an exception is thrown.
+   */
+  File copySync(String newPath);
+
+  /**
+   * Get the length of the file. Returns a `Future<int>` that
+   * completes with the length in bytes.
+   */
+  Future<int> length();
+
+  /**
+   * Synchronously get the length of the file.
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  int lengthSync();
+
+  /**
+   * Returns a [File] instance whose path is the absolute path to [this].
+   *
+   * The absolute path is computed by prefixing
+   * a relative path with the current working directory, and returning
+   * an absolute path unchanged.
+   */
+  File get absolute;
+
+/**
+ * Get the last-accessed time of the file.
+ *
+ * Returns a `Future<DateTime>` that completes with the date and time when the
+ * file was last accessed, if the information is available.
+ *
+ * Throws a [FileSystemException] if the operation fails.
+ */
+  Future<DateTime> lastAccessed();
+
+/**
+ * Get the last-accessed time of the file.
+ *
+ * Returns the date and time when the file was last accessed,
+ * if the information is available. Blocks until the information can be returned
+ * or it is determined that the information is not available.
+ *
+ * Throws a [FileSystemException] if the operation fails.
+ */
+  DateTime lastAccessedSync();
+
+  /**
+   * Modifies the time the file was last accessed.
+   *
+   * Returns a [Future] that completes once the operation has completed.
+   *
+   * Throws a [FileSystemException] if the time cannot be set.
+   */
+  Future setLastAccessed(DateTime time);
+
+  /**
+   * Synchronously modifies the time the file was last accessed.
+   *
+   * Throws a [FileSystemException] if the time cannot be set.
+   */
+  void setLastAccessedSync(DateTime time);
+
+/**
+ * Get the last-modified time of the file.
+ *
+ * Returns a `Future<DateTime>` that completes with the date and time when the
+ * file was last modified, if the information is available.
+ *
+ * Throws a [FileSystemException] if the operation fails.
+ */
+  Future<DateTime> lastModified();
+
+/**
+ * Get the last-modified time of the file.
+ *
+ * Returns the date and time when the file was last modified,
+ * if the information is available. Blocks until the information can be returned
+ * or it is determined that the information is not available.
+ *
+ * Throws a [FileSystemException] if the operation fails.
+ */
+  DateTime lastModifiedSync();
+
+  /**
+   * Modifies the time the file was last modified.
+   *
+   * Returns a [Future] that completes once the operation has completed.
+   *
+   * Throws a [FileSystemException] if the time cannot be set.
+   */
+  Future setLastModified(DateTime time);
+
+  /**
+   * Synchronously modifies the time the file was last modified.
+   *
+   * If the attributes cannot be set, throws a [FileSystemException].
+   */
+  void setLastModifiedSync(DateTime time);
+
+  /**
+   * Open the file for random access operations. Returns a
+   * `Future<RandomAccessFile>` that completes with the opened
+   * random access file. [RandomAccessFile]s must be closed using the
+   * [RandomAccessFile.close] method.
+   *
+   * Files can be opened in three modes:
+   *
+   * [FileMode.read]: open the file for reading.
+   *
+   * [FileMode.write]: open the file for both reading and writing and
+   * truncate the file to length zero. If the file does not exist the
+   * file is created.
+   *
+   * [FileMode.append]: same as [FileMode.write] except that the file is
+   * not truncated.
+   */
+  Future<RandomAccessFile> open({FileMode mode: FileMode.read});
+
+  /**
+   * Synchronously open the file for random access operations. The
+   * result is a [RandomAccessFile] on which random access operations
+   * can be performed. Opened [RandomAccessFile]s must be closed using
+   * the [RandomAccessFile.close] method.
+   *
+   * See [open] for information on the [mode] argument.
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  RandomAccessFile openSync({FileMode mode: FileMode.read});
+
+  /**
+   * Create a new independent [Stream] for the contents of this file.
+   *
+   * If [start] is present, the file will be read from byte-offset [start].
+   * Otherwise from the beginning (index 0).
+   *
+   * If [end] is present, only up to byte-index [end] will be read. Otherwise,
+   * until end of file.
+   *
+   * In order to make sure that system resources are freed, the stream
+   * must be read to completion or the subscription on the stream must
+   * be cancelled.
+   */
+  Stream<List<int>> openRead([int start, int end]);
+
+  /**
+   * Creates a new independent [IOSink] for the file. The
+   * [IOSink] must be closed when no longer used, to free
+   * system resources.
+   *
+   * An [IOSink] for a file can be opened in two modes:
+   *
+   * * [FileMode.write]: truncates the file to length zero.
+   * * [FileMode.append]: sets the initial write position to the end
+   *   of the file.
+   *
+   *  When writing strings through the returned [IOSink] the encoding
+   *  specified using [encoding] will be used. The returned [IOSink]
+   *  has an `encoding` property which can be changed after the
+   *  [IOSink] has been created.
+   */
+  IOSink openWrite({FileMode mode: FileMode.write, Encoding encoding: utf8});
+
+  /**
+   * Read the entire file contents as a list of bytes. Returns a
+   * `Future<Uint8List>` that completes with the list of bytes that
+   * is the contents of the file.
+   */
+  Future<Uint8List> readAsBytes();
+
+  /**
+   * Synchronously read the entire file contents as a list of bytes.
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  Uint8List readAsBytesSync();
+
+  /**
+   * Read the entire file contents as a string using the given
+   * [Encoding].
+   *
+   * Returns a `Future<String>` that completes with the string once
+   * the file contents has been read.
+   */
+  Future<String> readAsString({Encoding encoding: utf8});
+
+  /**
+   * Synchronously read the entire file contents as a string using the
+   * given [Encoding].
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  String readAsStringSync({Encoding encoding: utf8});
+
+  /**
+   * Read the entire file contents as lines of text using the given
+   * [Encoding].
+   *
+   * Returns a `Future<List<String>>` that completes with the lines
+   * once the file contents has been read.
+   */
+  Future<List<String>> readAsLines({Encoding encoding: utf8});
+
+  /**
+   * Synchronously read the entire file contents as lines of text
+   * using the given [Encoding].
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  List<String> readAsLinesSync({Encoding encoding: utf8});
+
+  /**
+   * Write a list of bytes to a file.
+   *
+   * Opens the file, writes the list of bytes to it, and closes the file.
+   * Returns a `Future<File>` that completes with this [File] object once
+   * the entire operation has completed.
+   *
+   * By default [writeAsBytes] creates the file for writing and truncates the
+   * file if it already exists. In order to append the bytes to an existing
+   * file, pass [FileMode.append] as the optional mode parameter.
+   *
+   * If the argument [flush] is set to `true`, the data written will be
+   * flushed to the file system before the returned future completes.
+   */
+  Future<File> writeAsBytes(List<int> bytes,
+      {FileMode mode: FileMode.write, bool flush: false});
+
+  /**
+   * Synchronously write a list of bytes to a file.
+   *
+   * Opens the file, writes the list of bytes to it and closes the file.
+   *
+   * By default [writeAsBytesSync] creates the file for writing and truncates
+   * the file if it already exists. In order to append the bytes to an existing
+   * file, pass [FileMode.append] as the optional mode parameter.
+   *
+   * If the [flush] argument is set to `true` data written will be
+   * flushed to the file system before returning.
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  void writeAsBytesSync(List<int> bytes,
+      {FileMode mode: FileMode.write, bool flush: false});
+
+  /**
+   * Write a string to a file.
+   *
+   * Opens the file, writes the string in the given encoding, and closes the
+   * file. Returns a `Future<File>` that completes with this [File] object
+   * once the entire operation has completed.
+   *
+   * By default [writeAsString] creates the file for writing and truncates the
+   * file if it already exists. In order to append the bytes to an existing
+   * file, pass [FileMode.append] as the optional mode parameter.
+   *
+   * If the argument [flush] is set to `true`, the data written will be
+   * flushed to the file system before the returned future completes.
+   *
+   */
+  Future<File> writeAsString(String contents,
+      {FileMode mode: FileMode.write,
+      Encoding encoding: utf8,
+      bool flush: false});
+
+  /**
+   * Synchronously write a string to a file.
+   *
+   * Opens the file, writes the string in the given encoding, and closes the
+   * file.
+   *
+   * By default [writeAsStringSync] creates the file for writing and
+   * truncates the file if it already exists. In order to append the bytes
+   * to an existing file, pass [FileMode.append] as the optional mode
+   * parameter.
+   *
+   * If the [flush] argument is set to `true` data written will be
+   * flushed to the file system before returning.
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  void writeAsStringSync(String contents,
+      {FileMode mode: FileMode.write,
+      Encoding encoding: utf8,
+      bool flush: false});
+
+  /**
+   * Get the path of the file.
+   */
+  String get path;
+}
+
+/**
+ * `RandomAccessFile` provides random access to the data in a
+ * file.
+ *
+ * `RandomAccessFile` objects are obtained by calling the
+ * `open` method on a [File] object.
+ *
+ * A `RandomAccessFile` have both asynchronous and synchronous
+ * methods. The asynchronous methods all return a `Future`
+ * whereas the synchronous methods will return the result directly,
+ * and block the current isolate until the result is ready.
+ *
+ * At most one asynchronous method can be pending on a given `RandomAccessFile`
+ * instance at the time. If an asynchronous method is called when one is
+ * already in progress a [FileSystemException] is thrown.
+ *
+ * If an asynchronous method is pending it is also not possible to call any
+ * synchronous methods. This will also throw a [FileSystemException].
+ */
+abstract class RandomAccessFile {
+  /**
+   * Closes the file. Returns a `Future` that
+   * completes when it has been closed.
+   */
+  Future<void> close();
+
+  /**
+   * Synchronously closes the file.
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  void closeSync();
+
+  /**
+   * Reads a byte from the file. Returns a `Future<int>` that
+   * completes with the byte, or with -1 if end-of-file has been reached.
+   */
+  Future<int> readByte();
+
+  /**
+   * Synchronously reads a single byte from the file. If end-of-file
+   * has been reached -1 is returned.
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  int readByteSync();
+
+  /**
+   * Reads [bytes] bytes from a file and returns the result as a list of bytes.
+   */
+  Future<Uint8List> read(int bytes);
+
+  /**
+   * Synchronously reads a maximum of [bytes] bytes from a file and
+   * returns the result in a list of bytes.
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  Uint8List readSync(int bytes);
+
+  /**
+   * Reads into an existing [List<int>] from the file. If [start] is present,
+   * the bytes will be filled into [buffer] from at index [start], otherwise
+   * index 0. If [end] is present, the [end] - [start] bytes will be read into
+   * [buffer], otherwise up to [buffer.length]. If [end] == [start] nothing
+   * happens.
+   *
+   * Returns a `Future<int>` that completes with the number of bytes read.
+   */
+  Future<int> readInto(List<int> buffer, [int start = 0, int end]);
+
+  /**
+   * Synchronously reads into an existing [List<int>] from the file. If [start]
+   * is present, the bytes will be filled into [buffer] from at index [start],
+   * otherwise index 0.  If [end] is present, the [end] - [start] bytes will be
+   * read into [buffer], otherwise up to [buffer.length]. If [end] == [start]
+   * nothing happens.
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  int readIntoSync(List<int> buffer, [int start = 0, int end]);
+
+  /**
+   * Writes a single byte to the file. Returns a
+   * `Future<RandomAccessFile>` that completes with this
+   * RandomAccessFile when the write completes.
+   */
+  Future<RandomAccessFile> writeByte(int value);
+
+  /**
+   * Synchronously writes a single byte to the file. Returns the
+   * number of bytes successfully written.
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  int writeByteSync(int value);
+
+  /**
+   * Writes from a [List<int>] to the file. It will read the buffer from index
+   * [start] to index [end]. If [start] is omitted, it'll start from index 0.
+   * If [end] is omitted, it will write to end of [buffer].
+   *
+   * Returns a `Future<RandomAccessFile>` that completes with this
+   * [RandomAccessFile] when the write completes.
+   */
+  Future<RandomAccessFile> writeFrom(List<int> buffer,
+      [int start = 0, int end]);
+
+  /**
+   * Synchronously writes from a [List<int>] to the file. It will read the
+   * buffer from index [start] to index [end]. If [start] is omitted, it'll
+   * start from index 0. If [end] is omitted, it will write to the end of
+   * [buffer].
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  void writeFromSync(List<int> buffer, [int start = 0, int end]);
+
+  /**
+   * Writes a string to the file using the given [Encoding]. Returns a
+   * `Future<RandomAccessFile>` that completes with this
+   * RandomAccessFile when the write completes.
+   */
+  Future<RandomAccessFile> writeString(String string,
+      {Encoding encoding: utf8});
+
+  /**
+   * Synchronously writes a single string to the file using the given
+   * [Encoding].
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  void writeStringSync(String string, {Encoding encoding: utf8});
+
+  /**
+   * Gets the current byte position in the file. Returns a
+   * `Future<int>` that completes with the position.
+   */
+  Future<int> position();
+
+  /**
+   * Synchronously gets the current byte position in the file.
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  int positionSync();
+
+  /**
+   * Sets the byte position in the file. Returns a
+   * `Future<RandomAccessFile>` that completes with this
+   * RandomAccessFile when the position has been set.
+   */
+  Future<RandomAccessFile> setPosition(int position);
+
+  /**
+   * Synchronously sets the byte position in the file.
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  void setPositionSync(int position);
+
+  /**
+   * Truncates (or extends) the file to [length] bytes. Returns a
+   * `Future<RandomAccessFile>` that completes with this
+   * RandomAccessFile when the truncation has been performed.
+   */
+  Future<RandomAccessFile> truncate(int length);
+
+  /**
+   * Synchronously truncates (or extends) the file to [length] bytes.
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  void truncateSync(int length);
+
+  /**
+   * Gets the length of the file. Returns a `Future<int>` that
+   * completes with the length in bytes.
+   */
+  Future<int> length();
+
+  /**
+   * Synchronously gets the length of the file.
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  int lengthSync();
+
+  /**
+   * Flushes the contents of the file to disk. Returns a
+   * `Future<RandomAccessFile>` that completes with this
+   * RandomAccessFile when the flush operation completes.
+   */
+  Future<RandomAccessFile> flush();
+
+  /**
+   * Synchronously flushes the contents of the file to disk.
+   *
+   * Throws a [FileSystemException] if the operation fails.
+   */
+  void flushSync();
+
+  /**
+   * Locks the file or part of the file.
+   *
+   * By default an exclusive lock will be obtained, but that can be overridden
+   * by the [mode] argument.
+   *
+   * Locks the byte range from [start] to [end] of the file, with the
+   * byte at position `end` not included. If no arguments are
+   * specified, the full file is locked, If only `start` is specified
+   * the file is locked from byte position `start` to the end of the
+   * file, no matter how large it grows. It is possible to specify an
+   * explicit value of `end` which is past the current length of the file.
+   *
+   * To obtain an exclusive lock on a file it must be opened for writing.
+   *
+   * If [mode] is [FileLock.exclusive] or [FileLock.shared], an error is
+   * signaled if the lock cannot be obtained. If [mode] is
+   * [FileLock.blockingExclusive] or [FileLock.blockingShared], the
+   * returned [Future] is resolved only when the lock has been obtained.
+   *
+   * *NOTE* file locking does have slight differences in behavior across
+   * platforms:
+   *
+   * On Linux and OS X this uses advisory locks, which have the
+   * surprising semantics that all locks associated with a given file
+   * are removed when *any* file descriptor for that file is closed by
+   * the process. Note that this does not actually lock the file for
+   * access. Also note that advisory locks are on a process
+   * level. This means that several isolates in the same process can
+   * obtain an exclusive lock on the same file.
+   *
+   * On Windows the regions used for lock and unlock needs to match. If that
+   * is not the case unlocking will result in the OS error "The segment is
+   * already unlocked".
+   */
+  Future<RandomAccessFile> lock(
+      [FileLock mode = FileLock.exclusive, int start = 0, int end = -1]);
+
+  /**
+   * Synchronously locks the file or part of the file.
+   *
+   * By default an exclusive lock will be obtained, but that can be overridden
+   * by the [mode] argument.
+   *
+   * Locks the byte range from [start] to [end] of the file ,with the
+   * byte at position `end` not included. If no arguments are
+   * specified, the full file is locked, If only `start` is specified
+   * the file is locked from byte position `start` to the end of the
+   * file, no matter how large it grows. It is possible to specify an
+   * explicit value of `end` which is past the current length of the file.
+   *
+   * To obtain an exclusive lock on a file it must be opened for writing.
+   *
+   * If [mode] is [FileLock.exclusive] or [FileLock.shared], an exception is
+   * thrown if the lock cannot be obtained. If [mode] is
+   * [FileLock.blockingExclusive] or [FileLock.blockingShared], the
+   * call returns only after the lock has been obtained.
+   *
+   * *NOTE* file locking does have slight differences in behavior across
+   * platforms:
+   *
+   * On Linux and OS X this uses advisory locks, which have the
+   * surprising semantics that all locks associated with a given file
+   * are removed when *any* file descriptor for that file is closed by
+   * the process. Note that this does not actually lock the file for
+   * access. Also note that advisory locks are on a process
+   * level. This means that several isolates in the same process can
+   * obtain an exclusive lock on the same file.
+   *
+   * On Windows the regions used for lock and unlock needs to match. If that
+   * is not the case unlocking will result in the OS error "The segment is
+   * already unlocked".
+   *
+   */
+  void lockSync(
+      [FileLock mode = FileLock.exclusive, int start = 0, int end = -1]);
+
+  /**
+   * Unlocks the file or part of the file.
+   *
+   * Unlocks the byte range from [start] to [end] of the file, with
+   * the byte at position `end` not included. If no arguments are
+   * specified, the full file is unlocked, If only `start` is
+   * specified the file is unlocked from byte position `start` to the
+   * end of the file.
+   *
+   * *NOTE* file locking does have slight differences in behavior across
+   * platforms:
+   *
+   * See [lock] for more details.
+   */
+  Future<RandomAccessFile> unlock([int start = 0, int end = -1]);
+
+  /**
+   * Synchronously unlocks the file or part of the file.
+   *
+   * Unlocks the byte range from [start] to [end] of the file, with
+   * the byte at position `end` not included. If no arguments are
+   * specified, the full file is unlocked, If only `start` is
+   * specified the file is unlocked from byte position `start` to the
+   * end of the file.
+   *
+   * *NOTE* file locking does have slight differences in behavior across
+   * platforms:
+   *
+   * See [lockSync] for more details.
+   */
+  void unlockSync([int start = 0, int end = -1]);
+
+  /**
+   * Returns a human-readable string for this RandomAccessFile instance.
+   */
+  String toString();
+
+  /**
+   * Gets the path of the file underlying this RandomAccessFile.
+   */
+  String get path;
+}
+
+/**
+ * Exception thrown when a file operation fails.
+ */
+@pragma("vm:entry-point")
+class FileSystemException implements IOException {
+  /**
+   * Message describing the error. This does not include any detailed
+   * information form the underlying OS error. Check [osError] for
+   * that information.
+   */
+  final String message;
+
+  /**
+   * The file system path on which the error occurred. Can be `null`
+   * if the exception does not relate directly to a file system path.
+   */
+  final String path;
+
+  /**
+   * The underlying OS error. Can be `null` if the exception is not
+   * raised due to an OS error.
+   */
+  final OSError osError;
+
+  /**
+   * Creates a new FileSystemException with an optional error message
+   * [message], optional file system path [path] and optional OS error
+   * [osError].
+   */
+  @pragma("vm:entry-point")
+  const FileSystemException([this.message = "", this.path = "", this.osError]);
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write("FileSystemException");
+    if (message.isNotEmpty) {
+      sb.write(": $message");
+      if (path != null) {
+        sb.write(", path = '$path'");
+      }
+      if (osError != null) {
+        sb.write(" ($osError)");
+      }
+    } else if (osError != null) {
+      sb.write(": $osError");
+      if (path != null) {
+        sb.write(", path = '$path'");
+      }
+    } else if (path != null) {
+      sb.write(": $path");
+    }
+    return sb.toString();
+  }
+}
diff --git a/sdk_nnbd/lib/io/file_impl.dart b/sdk_nnbd/lib/io/file_impl.dart
new file mode 100644
index 0000000..410182c
--- /dev/null
+++ b/sdk_nnbd/lib/io/file_impl.dart
@@ -0,0 +1,1095 @@
+// 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 dart.io;
+
+// Read the file in blocks of size 64k.
+const int _blockSize = 64 * 1024;
+
+class _FileStream extends Stream<List<int>> {
+  // Stream controller.
+  StreamController<Uint8List> _controller;
+
+  // Information about the underlying file.
+  String _path;
+  RandomAccessFile _openedFile;
+  int _position;
+  int _end;
+  final Completer _closeCompleter = new Completer();
+
+  // Has the stream been paused or unsubscribed?
+  bool _unsubscribed = false;
+
+  // Is there a read currently in progress?
+  bool _readInProgress = true;
+  bool _closed = false;
+
+  bool _atEnd = false;
+
+  _FileStream(this._path, this._position, this._end) {
+    _position ??= 0;
+  }
+
+  _FileStream.forStdin() : _position = 0;
+
+  StreamSubscription<Uint8List> listen(void onData(Uint8List event),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    _setupController();
+    return _controller.stream.listen(onData,
+        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+  }
+
+  void _setupController() {
+    _controller = new StreamController<Uint8List>(
+        sync: true,
+        onListen: _start,
+        onResume: _readBlock,
+        onCancel: () {
+          _unsubscribed = true;
+          return _closeFile();
+        });
+  }
+
+  Future _closeFile() {
+    if (_readInProgress || _closed) {
+      return _closeCompleter.future;
+    }
+    _closed = true;
+
+    void done() {
+      _closeCompleter.complete();
+      _controller.close();
+    }
+
+    _openedFile.close().catchError(_controller.addError).whenComplete(done);
+    return _closeCompleter.future;
+  }
+
+  void _readBlock() {
+    // Don't start a new read if one is already in progress.
+    if (_readInProgress) return;
+    if (_atEnd) {
+      _closeFile();
+      return;
+    }
+    _readInProgress = true;
+    int readBytes = _blockSize;
+    if (_end != null) {
+      readBytes = min(readBytes, _end - _position);
+      if (readBytes < 0) {
+        _readInProgress = false;
+        if (!_unsubscribed) {
+          _controller.addError(new RangeError("Bad end position: $_end"));
+          _closeFile();
+          _unsubscribed = true;
+        }
+        return;
+      }
+    }
+    _openedFile.read(readBytes).then((block) {
+      _readInProgress = false;
+      if (_unsubscribed) {
+        _closeFile();
+        return;
+      }
+      _position += block.length;
+      if (block.length < readBytes || (_end != null && _position == _end)) {
+        _atEnd = true;
+      }
+      if (!_atEnd && !_controller.isPaused) {
+        _readBlock();
+      }
+      _controller.add(block);
+      if (_atEnd) {
+        _closeFile();
+      }
+    }).catchError((e, s) {
+      if (!_unsubscribed) {
+        _controller.addError(e, s);
+        _closeFile();
+        _unsubscribed = true;
+      }
+    });
+  }
+
+  void _start() {
+    if (_position < 0) {
+      _controller.addError(new RangeError("Bad start position: $_position"));
+      _controller.close();
+      _closeCompleter.complete();
+      return;
+    }
+
+    void onReady(RandomAccessFile file) {
+      _openedFile = file;
+      _readInProgress = false;
+      _readBlock();
+    }
+
+    void onOpenFile(RandomAccessFile file) {
+      if (_position > 0) {
+        file.setPosition(_position).then(onReady, onError: (e, s) {
+          _controller.addError(e, s);
+          _readInProgress = false;
+          _closeFile();
+        });
+      } else {
+        onReady(file);
+      }
+    }
+
+    void openFailed(error, stackTrace) {
+      _controller.addError(error, stackTrace);
+      _controller.close();
+      _closeCompleter.complete();
+    }
+
+    if (_path != null) {
+      new File(_path)
+          .open(mode: FileMode.read)
+          .then(onOpenFile, onError: openFailed);
+    } else {
+      try {
+        onOpenFile(_File._openStdioSync(0));
+      } catch (e, s) {
+        openFailed(e, s);
+      }
+    }
+  }
+}
+
+class _FileStreamConsumer extends StreamConsumer<List<int>> {
+  File _file;
+  Future<RandomAccessFile> _openFuture;
+
+  _FileStreamConsumer(this._file, FileMode mode) {
+    _openFuture = _file.open(mode: mode);
+  }
+
+  _FileStreamConsumer.fromStdio(int fd) {
+    _openFuture = new Future.value(_File._openStdioSync(fd));
+  }
+
+  Future<File> addStream(Stream<List<int>> stream) {
+    Completer<File> completer = new Completer<File>.sync();
+    _openFuture.then((openedFile) {
+      var _subscription;
+      void error(e, [StackTrace stackTrace]) {
+        _subscription.cancel();
+        openedFile.close();
+        completer.completeError(e, stackTrace);
+      }
+
+      _subscription = stream.listen((d) {
+        _subscription.pause();
+        try {
+          openedFile
+              .writeFrom(d, 0, d.length)
+              .then((_) => _subscription.resume(), onError: error);
+        } catch (e, stackTrace) {
+          error(e, stackTrace);
+        }
+      }, onDone: () {
+        completer.complete(_file);
+      }, onError: error, cancelOnError: true);
+    }).catchError(completer.completeError);
+    return completer.future;
+  }
+
+  Future<File> close() =>
+      _openFuture.then((openedFile) => openedFile.close()).then((_) => _file);
+}
+
+// Class for encapsulating the native implementation of files.
+class _File extends FileSystemEntity implements File {
+  String _path;
+  Uint8List _rawPath;
+
+  _File(String path) {
+    ArgumentError.checkNotNull(path, 'path');
+    _path = path;
+    _rawPath = FileSystemEntity._toUtf8Array(path);
+  }
+
+  _File.fromRawPath(Uint8List rawPath) {
+    ArgumentError.checkNotNull(rawPath, 'rawPath');
+    _rawPath = FileSystemEntity._toNullTerminatedUtf8Array(rawPath);
+    _path = FileSystemEntity._toStringFromUtf8Array(rawPath);
+  }
+
+  String get path => _path;
+
+  // WARNING:
+  // Calling this function will increase the reference count on the native
+  // namespace object. It should only be called to pass the pointer to the
+  // IOService, which will decrement the reference count when it is finished
+  // with it.
+  static int _namespacePointer() => _Namespace._namespacePointer;
+
+  static Future _dispatchWithNamespace(int request, List data) {
+    data[0] = _namespacePointer();
+    return _IOService._dispatch(request, data);
+  }
+
+  Future<bool> exists() {
+    return _dispatchWithNamespace(_IOService.fileExists, [null, _rawPath])
+        .then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, "Cannot check existence", path);
+      }
+      return response;
+    });
+  }
+
+  external static _exists(_Namespace namespace, Uint8List rawPath);
+
+  bool existsSync() {
+    var result = _exists(_Namespace._namespace, _rawPath);
+    throwIfError(result, "Cannot check existence of file", path);
+    return result;
+  }
+
+  File get absolute => new File(_absolutePath);
+
+  Future<File> create({bool recursive: false}) {
+    var result =
+        recursive ? parent.create(recursive: true) : new Future.value(null);
+    return result
+        .then((_) =>
+            _dispatchWithNamespace(_IOService.fileCreate, [null, _rawPath]))
+        .then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, "Cannot create file", path);
+      }
+      return this;
+    });
+  }
+
+  external static _create(_Namespace namespace, Uint8List rawPath);
+
+  external static _createLink(
+      _Namespace namespace, Uint8List rawPath, String target);
+
+  external static _linkTarget(_Namespace namespace, Uint8List rawPath);
+
+  void createSync({bool recursive: false}) {
+    if (recursive) {
+      parent.createSync(recursive: true);
+    }
+    var result = _create(_Namespace._namespace, _rawPath);
+    throwIfError(result, "Cannot create file", path);
+  }
+
+  Future<File> _delete({bool recursive: false}) {
+    if (recursive) {
+      return new Directory(path).delete(recursive: true).then((_) => this);
+    }
+    return _dispatchWithNamespace(_IOService.fileDelete, [null, _rawPath])
+        .then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, "Cannot delete file", path);
+      }
+      return this;
+    });
+  }
+
+  external static _deleteNative(_Namespace namespace, Uint8List rawPath);
+
+  external static _deleteLinkNative(_Namespace namespace, Uint8List rawPath);
+
+  void _deleteSync({bool recursive: false}) {
+    if (recursive) {
+      return new Directory.fromRawPath(_rawPath).deleteSync(recursive: true);
+    }
+    var result = _deleteNative(_Namespace._namespace, _rawPath);
+    throwIfError(result, "Cannot delete file", path);
+  }
+
+  Future<File> rename(String newPath) {
+    return _dispatchWithNamespace(
+        _IOService.fileRename, [null, _rawPath, newPath]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(
+            response, "Cannot rename file to '$newPath'", path);
+      }
+      return new File(newPath);
+    });
+  }
+
+  external static _rename(
+      _Namespace namespace, Uint8List oldPath, String newPath);
+
+  external static _renameLink(
+      _Namespace namespace, Uint8List oldPath, String newPath);
+
+  File renameSync(String newPath) {
+    var result = _rename(_Namespace._namespace, _rawPath, newPath);
+    throwIfError(result, "Cannot rename file to '$newPath'", path);
+    return new File(newPath);
+  }
+
+  Future<File> copy(String newPath) {
+    return _dispatchWithNamespace(
+        _IOService.fileCopy, [null, _rawPath, newPath]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(
+            response, "Cannot copy file to '$newPath'", path);
+      }
+      return new File(newPath);
+    });
+  }
+
+  external static _copy(
+      _Namespace namespace, Uint8List oldPath, String newPath);
+
+  File copySync(String newPath) {
+    var result = _copy(_Namespace._namespace, _rawPath, newPath);
+    throwIfError(result, "Cannot copy file to '$newPath'", path);
+    return new File(newPath);
+  }
+
+  Future<RandomAccessFile> open({FileMode mode: FileMode.read}) {
+    if (mode != FileMode.read &&
+        mode != FileMode.write &&
+        mode != FileMode.append &&
+        mode != FileMode.writeOnly &&
+        mode != FileMode.writeOnlyAppend) {
+      return new Future.error(
+          new ArgumentError('Invalid file mode for this operation'));
+    }
+    return _dispatchWithNamespace(
+        _IOService.fileOpen, [null, _rawPath, mode._mode]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, "Cannot open file", path);
+      }
+      return new _RandomAccessFile(response, path);
+    });
+  }
+
+  Future<int> length() {
+    return _dispatchWithNamespace(
+        _IOService.fileLengthFromPath, [null, _rawPath]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(
+            response, "Cannot retrieve length of file", path);
+      }
+      return response;
+    });
+  }
+
+  external static _lengthFromPath(_Namespace namespace, Uint8List rawPath);
+
+  int lengthSync() {
+    var result = _lengthFromPath(_Namespace._namespace, _rawPath);
+    throwIfError(result, "Cannot retrieve length of file", path);
+    return result;
+  }
+
+  Future<DateTime> lastAccessed() {
+    return _dispatchWithNamespace(_IOService.fileLastAccessed, [null, _rawPath])
+        .then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(
+            response, "Cannot retrieve access time", path);
+      }
+      return new DateTime.fromMillisecondsSinceEpoch(response);
+    });
+  }
+
+  external static _lastAccessed(_Namespace namespace, Uint8List rawPath);
+
+  DateTime lastAccessedSync() {
+    var ms = _lastAccessed(_Namespace._namespace, _rawPath);
+    throwIfError(ms, "Cannot retrieve access time", path);
+    return new DateTime.fromMillisecondsSinceEpoch(ms);
+  }
+
+  Future setLastAccessed(DateTime time) {
+    int millis = time.millisecondsSinceEpoch;
+    return _dispatchWithNamespace(
+            _IOService.fileSetLastAccessed, [null, _rawPath, millis])
+        .then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, "Cannot set access time", path);
+      }
+      return null;
+    });
+  }
+
+  external static _setLastAccessed(
+      _Namespace namespace, Uint8List rawPath, int millis);
+
+  void setLastAccessedSync(DateTime time) {
+    int millis = time.millisecondsSinceEpoch;
+    var result = _setLastAccessed(_Namespace._namespace, _rawPath, millis);
+    if (result is OSError) {
+      throw new FileSystemException(
+          "Failed to set file access time", path, result);
+    }
+  }
+
+  Future<DateTime> lastModified() {
+    return _dispatchWithNamespace(_IOService.fileLastModified, [null, _rawPath])
+        .then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(
+            response, "Cannot retrieve modification time", path);
+      }
+      return new DateTime.fromMillisecondsSinceEpoch(response);
+    });
+  }
+
+  external static _lastModified(_Namespace namespace, Uint8List rawPath);
+
+  DateTime lastModifiedSync() {
+    var ms = _lastModified(_Namespace._namespace, _rawPath);
+    throwIfError(ms, "Cannot retrieve modification time", path);
+    return new DateTime.fromMillisecondsSinceEpoch(ms);
+  }
+
+  Future setLastModified(DateTime time) {
+    int millis = time.millisecondsSinceEpoch;
+    return _dispatchWithNamespace(
+            _IOService.fileSetLastModified, [null, _rawPath, millis])
+        .then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(
+            response, "Cannot set modification time", path);
+      }
+      return null;
+    });
+  }
+
+  external static _setLastModified(
+      _Namespace namespace, Uint8List rawPath, int millis);
+
+  void setLastModifiedSync(DateTime time) {
+    int millis = time.millisecondsSinceEpoch;
+    var result = _setLastModified(_Namespace._namespace, _rawPath, millis);
+    if (result is OSError) {
+      throw new FileSystemException(
+          "Failed to set file modification time", path, result);
+    }
+  }
+
+  external static _open(_Namespace namespace, Uint8List rawPath, int mode);
+
+  RandomAccessFile openSync({FileMode mode: FileMode.read}) {
+    if (mode != FileMode.read &&
+        mode != FileMode.write &&
+        mode != FileMode.append &&
+        mode != FileMode.writeOnly &&
+        mode != FileMode.writeOnlyAppend) {
+      throw new ArgumentError('Invalid file mode for this operation');
+    }
+    var id = _open(_Namespace._namespace, _rawPath, mode._mode);
+    throwIfError(id, "Cannot open file", path);
+    return new _RandomAccessFile(id, _path);
+  }
+
+  external static int _openStdio(int fd);
+
+  static RandomAccessFile _openStdioSync(int fd) {
+    var id = _openStdio(fd);
+    if (id == 0) {
+      throw new FileSystemException("Cannot open stdio file for: $fd");
+    }
+    return new _RandomAccessFile(id, "");
+  }
+
+  Stream<List<int>> openRead([int start, int end]) {
+    return new _FileStream(path, start, end);
+  }
+
+  IOSink openWrite({FileMode mode: FileMode.write, Encoding encoding: utf8}) {
+    if (mode != FileMode.write &&
+        mode != FileMode.append &&
+        mode != FileMode.writeOnly &&
+        mode != FileMode.writeOnlyAppend) {
+      throw new ArgumentError('Invalid file mode for this operation');
+    }
+    var consumer = new _FileStreamConsumer(this, mode);
+    return new IOSink(consumer, encoding: encoding);
+  }
+
+  Future<Uint8List> readAsBytes() {
+    Future<Uint8List> readDataChunked(RandomAccessFile file) {
+      var builder = new BytesBuilder(copy: false);
+      var completer = new Completer<Uint8List>();
+      void read() {
+        file.read(_blockSize).then((data) {
+          if (data.length > 0) {
+            builder.add(data);
+            read();
+          } else {
+            completer.complete(builder.takeBytes());
+          }
+        }, onError: completer.completeError);
+      }
+
+      read();
+      return completer.future;
+    }
+
+    return open().then((file) {
+      return file.length().then((length) {
+        if (length == 0) {
+          // May be character device, try to read it in chunks.
+          return readDataChunked(file);
+        }
+        return file.read(length);
+      }).whenComplete(file.close);
+    });
+  }
+
+  Uint8List readAsBytesSync() {
+    var opened = openSync();
+    try {
+      Uint8List data;
+      var length = opened.lengthSync();
+      if (length == 0) {
+        // May be character device, try to read it in chunks.
+        var builder = new BytesBuilder(copy: false);
+        do {
+          data = opened.readSync(_blockSize);
+          if (data.length > 0) builder.add(data);
+        } while (data.length > 0);
+        data = builder.takeBytes();
+      } else {
+        data = opened.readSync(length);
+      }
+      return data;
+    } finally {
+      opened.closeSync();
+    }
+  }
+
+  String _tryDecode(List<int> bytes, Encoding encoding) {
+    try {
+      return encoding.decode(bytes);
+    } catch (_) {
+      throw new FileSystemException(
+          "Failed to decode data using encoding '${encoding.name}'", path);
+    }
+  }
+
+  Future<String> readAsString({Encoding encoding: utf8}) {
+    // TODO(dart:io): If the change in async semantics to run synchronously
+    // until await lands, this is as efficient as
+    // return _tryDecode(await readAsBytes(), encoding);
+    var stack = StackTrace.current;
+    return readAsBytes().then((bytes) {
+      try {
+        return _tryDecode(bytes, encoding);
+      } catch (e) {
+        return new Future.error(e, stack);
+      }
+    });
+  }
+
+  String readAsStringSync({Encoding encoding: utf8}) =>
+      _tryDecode(readAsBytesSync(), encoding);
+
+  Future<List<String>> readAsLines({Encoding encoding: utf8}) =>
+      readAsString(encoding: encoding).then(const LineSplitter().convert);
+
+  List<String> readAsLinesSync({Encoding encoding: utf8}) =>
+      const LineSplitter().convert(readAsStringSync(encoding: encoding));
+
+  Future<File> writeAsBytes(List<int> bytes,
+      {FileMode mode: FileMode.write, bool flush: false}) {
+    return open(mode: mode).then((file) {
+      return file.writeFrom(bytes, 0, bytes.length).then<File>((_) {
+        if (flush) return file.flush().then((_) => this);
+        return this;
+      }).whenComplete(file.close);
+    });
+  }
+
+  void writeAsBytesSync(List<int> bytes,
+      {FileMode mode: FileMode.write, bool flush: false}) {
+    RandomAccessFile opened = openSync(mode: mode);
+    try {
+      opened.writeFromSync(bytes, 0, bytes.length);
+      if (flush) opened.flushSync();
+    } finally {
+      opened.closeSync();
+    }
+  }
+
+  Future<File> writeAsString(String contents,
+      {FileMode mode: FileMode.write,
+      Encoding encoding: utf8,
+      bool flush: false}) {
+    try {
+      return writeAsBytes(encoding.encode(contents), mode: mode, flush: flush);
+    } catch (e) {
+      return new Future.error(e);
+    }
+  }
+
+  void writeAsStringSync(String contents,
+      {FileMode mode: FileMode.write,
+      Encoding encoding: utf8,
+      bool flush: false}) {
+    writeAsBytesSync(encoding.encode(contents), mode: mode, flush: flush);
+  }
+
+  String toString() => "File: '$path'";
+
+  static throwIfError(Object result, String msg, String path) {
+    if (result is OSError) {
+      throw new FileSystemException(msg, path, result);
+    }
+  }
+}
+
+abstract class _RandomAccessFileOps {
+  external factory _RandomAccessFileOps(int pointer);
+
+  int getPointer();
+  int close();
+  readByte();
+  read(int bytes);
+  readInto(List<int> buffer, int start, int end);
+  writeByte(int value);
+  writeFrom(List<int> buffer, int start, int end);
+  position();
+  setPosition(int position);
+  truncate(int length);
+  length();
+  flush();
+  lock(int lock, int start, int end);
+}
+
+class _RandomAccessFile implements RandomAccessFile {
+  static bool _connectedResourceHandler = false;
+
+  final String path;
+
+  bool _asyncDispatched = false;
+  SendPort _fileService;
+
+  _FileResourceInfo _resourceInfo;
+  _RandomAccessFileOps _ops;
+
+  _RandomAccessFile(int pointer, this.path) {
+    _ops = new _RandomAccessFileOps(pointer);
+    _resourceInfo = new _FileResourceInfo(this);
+    _maybeConnectHandler();
+  }
+
+  void _maybePerformCleanup() {
+    if (closed) {
+      _FileResourceInfo.FileClosed(_resourceInfo);
+    }
+  }
+
+  _maybeConnectHandler() {
+    if (!_connectedResourceHandler) {
+      // TODO(ricow): We probably need to set these in some initialization code.
+      // We need to make sure that these are always available from the
+      // observatory even if no files (or sockets for the socket ones) are
+      // open.
+      registerExtension(
+          'ext.dart.io.getOpenFiles', _FileResourceInfo.getOpenFiles);
+      registerExtension(
+          'ext.dart.io.getFileByID', _FileResourceInfo.getFileInfoMapByID);
+      _connectedResourceHandler = true;
+    }
+  }
+
+  Future<void> close() {
+    return _dispatch(_IOService.fileClose, [null], markClosed: true)
+        .then((result) {
+      if (result == -1) {
+        throw new FileSystemException("Cannot close file", path);
+      }
+      closed = closed || (result == 0);
+      _maybePerformCleanup();
+    });
+  }
+
+  void closeSync() {
+    _checkAvailable();
+    var id = _ops.close();
+    if (id == -1) {
+      throw new FileSystemException("Cannot close file", path);
+    }
+    closed = closed || (id == 0);
+    _maybePerformCleanup();
+  }
+
+  Future<int> readByte() {
+    return _dispatch(_IOService.fileReadByte, [null]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, "readByte failed", path);
+      }
+      _resourceInfo.addRead(1);
+      return response;
+    });
+  }
+
+  int readByteSync() {
+    _checkAvailable();
+    var result = _ops.readByte();
+    if (result is OSError) {
+      throw new FileSystemException("readByte failed", path, result);
+    }
+    _resourceInfo.addRead(1);
+    return result;
+  }
+
+  Future<Uint8List> read(int bytes) {
+    ArgumentError.checkNotNull(bytes, 'bytes');
+    return _dispatch(_IOService.fileRead, [null, bytes]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, "read failed", path);
+      }
+      _resourceInfo.addRead(response[1].length);
+      Uint8List result = response[1];
+      return result;
+    });
+  }
+
+  Uint8List readSync(int bytes) {
+    _checkAvailable();
+    ArgumentError.checkNotNull(bytes, 'bytes');
+    var result = _ops.read(bytes);
+    if (result is OSError) {
+      throw new FileSystemException("readSync failed", path, result);
+    }
+    _resourceInfo.addRead(result.length);
+    return result;
+  }
+
+  Future<int> readInto(List<int> buffer, [int start = 0, int end]) {
+    if ((buffer is! List) ||
+        ((start != null) && (start is! int)) ||
+        ((end != null) && (end is! int))) {
+      throw new ArgumentError();
+    }
+    end = RangeError.checkValidRange(start, end, buffer.length);
+    if (end == start) {
+      return new Future.value(0);
+    }
+    int length = end - start;
+    return _dispatch(_IOService.fileReadInto, [null, length]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, "readInto failed", path);
+      }
+      int read = response[1];
+      List<int> data = response[2];
+      buffer.setRange(start, start + read, data);
+      _resourceInfo.addRead(read);
+      return read;
+    });
+  }
+
+  int readIntoSync(List<int> buffer, [int start = 0, int end]) {
+    _checkAvailable();
+    if ((buffer is! List) ||
+        ((start != null) && (start is! int)) ||
+        ((end != null) && (end is! int))) {
+      throw new ArgumentError();
+    }
+    end = RangeError.checkValidRange(start, end, buffer.length);
+    if (end == start) {
+      return 0;
+    }
+    var result = _ops.readInto(buffer, start, end);
+    if (result is OSError) {
+      throw new FileSystemException("readInto failed", path, result);
+    }
+    _resourceInfo.addRead(result);
+    return result;
+  }
+
+  Future<RandomAccessFile> writeByte(int value) {
+    ArgumentError.checkNotNull(value, 'value');
+    return _dispatch(_IOService.fileWriteByte, [null, value]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, "writeByte failed", path);
+      }
+      _resourceInfo.addWrite(1);
+      return this;
+    });
+  }
+
+  int writeByteSync(int value) {
+    _checkAvailable();
+    ArgumentError.checkNotNull(value, 'value');
+    var result = _ops.writeByte(value);
+    if (result is OSError) {
+      throw new FileSystemException("writeByte failed", path, result);
+    }
+    _resourceInfo.addWrite(1);
+    return result;
+  }
+
+  Future<RandomAccessFile> writeFrom(List<int> buffer,
+      [int start = 0, int end]) {
+    if ((buffer is! List) ||
+        ((start != null) && (start is! int)) ||
+        ((end != null) && (end is! int))) {
+      throw new ArgumentError("Invalid arguments to writeFrom");
+    }
+    end = RangeError.checkValidRange(start, end, buffer.length);
+    if (end == start) {
+      return new Future.value(this);
+    }
+    _BufferAndStart result;
+    try {
+      result = _ensureFastAndSerializableByteData(buffer, start, end);
+    } catch (e) {
+      return new Future.error(e);
+    }
+
+    List request = new List(4);
+    request[0] = null;
+    request[1] = result.buffer;
+    request[2] = result.start;
+    request[3] = end - (start - result.start);
+    return _dispatch(_IOService.fileWriteFrom, request).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, "writeFrom failed", path);
+      }
+      _resourceInfo.addWrite(end - (start - result.start));
+      return this;
+    });
+  }
+
+  void writeFromSync(List<int> buffer, [int start = 0, int end]) {
+    _checkAvailable();
+    if ((buffer is! List) ||
+        ((start != null) && (start is! int)) ||
+        ((end != null) && (end is! int))) {
+      throw new ArgumentError("Invalid arguments to writeFromSync");
+    }
+    end = RangeError.checkValidRange(start, end, buffer.length);
+    if (end == start) {
+      return;
+    }
+    _BufferAndStart bufferAndStart =
+        _ensureFastAndSerializableByteData(buffer, start, end);
+    var result = _ops.writeFrom(bufferAndStart.buffer, bufferAndStart.start,
+        end - (start - bufferAndStart.start));
+    if (result is OSError) {
+      throw new FileSystemException("writeFrom failed", path, result);
+    }
+    _resourceInfo.addWrite(end - (start - bufferAndStart.start));
+  }
+
+  Future<RandomAccessFile> writeString(String string,
+      {Encoding encoding: utf8}) {
+    ArgumentError.checkNotNull(encoding, 'encoding');
+    var data = encoding.encode(string);
+    return writeFrom(data, 0, data.length);
+  }
+
+  void writeStringSync(String string, {Encoding encoding: utf8}) {
+    ArgumentError.checkNotNull(encoding, 'encoding');
+    var data = encoding.encode(string);
+    writeFromSync(data, 0, data.length);
+  }
+
+  Future<int> position() {
+    return _dispatch(_IOService.filePosition, [null]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, "position failed", path);
+      }
+      return response;
+    });
+  }
+
+  int positionSync() {
+    _checkAvailable();
+    var result = _ops.position();
+    if (result is OSError) {
+      throw new FileSystemException("position failed", path, result);
+    }
+    return result;
+  }
+
+  Future<RandomAccessFile> setPosition(int position) {
+    return _dispatch(_IOService.fileSetPosition, [null, position])
+        .then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, "setPosition failed", path);
+      }
+      return this;
+    });
+  }
+
+  void setPositionSync(int position) {
+    _checkAvailable();
+    var result = _ops.setPosition(position);
+    if (result is OSError) {
+      throw new FileSystemException("setPosition failed", path, result);
+    }
+  }
+
+  Future<RandomAccessFile> truncate(int length) {
+    return _dispatch(_IOService.fileTruncate, [null, length]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, "truncate failed", path);
+      }
+      return this;
+    });
+  }
+
+  void truncateSync(int length) {
+    _checkAvailable();
+    var result = _ops.truncate(length);
+    if (result is OSError) {
+      throw new FileSystemException("truncate failed", path, result);
+    }
+  }
+
+  Future<int> length() {
+    return _dispatch(_IOService.fileLength, [null]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, "length failed", path);
+      }
+      return response;
+    });
+  }
+
+  int lengthSync() {
+    _checkAvailable();
+    var result = _ops.length();
+    if (result is OSError) {
+      throw new FileSystemException("length failed", path, result);
+    }
+    return result;
+  }
+
+  Future<RandomAccessFile> flush() {
+    return _dispatch(_IOService.fileFlush, [null]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, "flush failed", path);
+      }
+      return this;
+    });
+  }
+
+  void flushSync() {
+    _checkAvailable();
+    var result = _ops.flush();
+    if (result is OSError) {
+      throw new FileSystemException("flush failed", path, result);
+    }
+  }
+
+  static const int lockUnlock = 0;
+  // static const int lockShared = 1;
+  // static const int lockExclusive = 2;
+  // static const int lockBlockingShared = 3;
+  // static const int lockBlockingExclusive = 4;
+
+  int _fileLockValue(FileLock fl) => fl._type;
+
+  Future<RandomAccessFile> lock(
+      [FileLock mode = FileLock.exclusive, int start = 0, int end = -1]) {
+    if ((mode is! FileLock) || (start is! int) || (end is! int)) {
+      throw new ArgumentError();
+    }
+    if ((start < 0) || (end < -1) || ((end != -1) && (start >= end))) {
+      throw new ArgumentError();
+    }
+    int lock = _fileLockValue(mode);
+    return _dispatch(_IOService.fileLock, [null, lock, start, end])
+        .then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, 'lock failed', path);
+      }
+      return this;
+    });
+  }
+
+  Future<RandomAccessFile> unlock([int start = 0, int end = -1]) {
+    if ((start is! int) || (end is! int)) {
+      throw new ArgumentError();
+    }
+    if (start == end) {
+      throw new ArgumentError();
+    }
+    return _dispatch(_IOService.fileLock, [null, lockUnlock, start, end])
+        .then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, 'unlock failed', path);
+      }
+      return this;
+    });
+  }
+
+  void lockSync(
+      [FileLock mode = FileLock.exclusive, int start = 0, int end = -1]) {
+    _checkAvailable();
+    if ((mode is! FileLock) || (start is! int) || (end is! int)) {
+      throw new ArgumentError();
+    }
+    if ((start < 0) || (end < -1) || ((end != -1) && (start >= end))) {
+      throw new ArgumentError();
+    }
+    int lock = _fileLockValue(mode);
+    var result = _ops.lock(lock, start, end);
+    if (result is OSError) {
+      throw new FileSystemException('lock failed', path, result);
+    }
+  }
+
+  void unlockSync([int start = 0, int end = -1]) {
+    _checkAvailable();
+    if ((start is! int) || (end is! int)) {
+      throw new ArgumentError();
+    }
+    if (start == end) {
+      throw new ArgumentError();
+    }
+    var result = _ops.lock(lockUnlock, start, end);
+    if (result is OSError) {
+      throw new FileSystemException('unlock failed', path, result);
+    }
+  }
+
+  bool closed = false;
+
+  // WARNING:
+  // Calling this function will increase the reference count on the native
+  // object that implements the file operations. It should only be called to
+  // pass the pointer to the IO Service, which will decrement the reference
+  // count when it is finished with it.
+  int _pointer() => _ops.getPointer();
+
+  Future _dispatch(int request, List data, {bool markClosed: false}) {
+    if (closed) {
+      return new Future.error(new FileSystemException("File closed", path));
+    }
+    if (_asyncDispatched) {
+      var msg = "An async operation is currently pending";
+      return new Future.error(new FileSystemException(msg, path));
+    }
+    if (markClosed) {
+      // Set closed to true to ensure that no more async requests can be issued
+      // for this file.
+      closed = true;
+    }
+    _asyncDispatched = true;
+    data[0] = _pointer();
+    return _IOService._dispatch(request, data).whenComplete(() {
+      _asyncDispatched = false;
+    });
+  }
+
+  void _checkAvailable() {
+    if (_asyncDispatched) {
+      throw new FileSystemException(
+          "An async operation is currently pending", path);
+    }
+    if (closed) {
+      throw new FileSystemException("File closed", path);
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/io/file_system_entity.dart b/sdk_nnbd/lib/io/file_system_entity.dart
new file mode 100644
index 0000000..16e99e6
--- /dev/null
+++ b/sdk_nnbd/lib/io/file_system_entity.dart
@@ -0,0 +1,1002 @@
+// 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 dart.io;
+
+/**
+ * The type of an entity on the file system, such as a file, directory, or link.
+ *
+ * These constants are used by the [FileSystemEntity] class
+ * to indicate the object's type.
+ *
+ */
+
+class FileSystemEntityType {
+  static const file = const FileSystemEntityType._internal(0);
+  @Deprecated("Use file instead")
+  static const FILE = file;
+
+  static const directory = const FileSystemEntityType._internal(1);
+  @Deprecated("Use directory instead")
+  static const DIRECTORY = directory;
+
+  static const link = const FileSystemEntityType._internal(2);
+  @Deprecated("Use link instead")
+  static const LINK = link;
+
+  static const notFound = const FileSystemEntityType._internal(3);
+  @Deprecated("Use notFound instead")
+  static const NOT_FOUND = notFound;
+
+  static const _typeList = const [
+    FileSystemEntityType.file,
+    FileSystemEntityType.directory,
+    FileSystemEntityType.link,
+    FileSystemEntityType.notFound,
+  ];
+  final int _type;
+
+  const FileSystemEntityType._internal(this._type);
+
+  static FileSystemEntityType _lookup(int type) => _typeList[type];
+  String toString() => const ['file', 'directory', 'link', 'notFound'][_type];
+}
+
+/**
+ * A FileStat object represents the result of calling the POSIX stat() function
+ * on a file system object.  It is an immutable object, representing the
+ * snapshotted values returned by the stat() call.
+ */
+class FileStat {
+  // These must agree with enum FileStat in file.h.
+  static const _type = 0;
+  static const _changedTime = 1;
+  static const _modifiedTime = 2;
+  static const _accessedTime = 3;
+  static const _mode = 4;
+  static const _size = 5;
+
+  static const _notFound = const FileStat._internalNotFound();
+
+  /**
+   * The time of the last change to the data or metadata of the file system
+   * object.
+   *
+   * On Windows platforms, this is instead the file creation time.
+   */
+  final DateTime changed;
+
+  /**
+   * The time of the last change to the data of the file system object.
+   */
+  final DateTime modified;
+
+  /**
+   * The time of the last access to the data of the file system object.
+   *
+   * On Windows platforms, this may have 1 day granularity, and be
+   * out of date by an hour.
+   */
+  final DateTime accessed;
+
+  /**
+   * The type of the underlying file system object.
+   *
+   * [FileSystemEntityType.notFound] if [stat] or [statSync] failed.
+   */
+  final FileSystemEntityType type;
+
+  /**
+   * The mode of the file system object.
+   *
+   * Permissions are encoded in the lower 16 bits of this number, and can be
+   * decoded using the [modeString] getter.
+   */
+  final int mode;
+
+  /**
+   * The size of the file system object.
+   */
+  final int size;
+
+  FileStat._internal(this.changed, this.modified, this.accessed, this.type,
+      this.mode, this.size);
+
+  const FileStat._internalNotFound()
+      : changed = null,
+        modified = null,
+        accessed = null,
+        type = FileSystemEntityType.notFound,
+        mode = 0,
+        size = -1;
+
+  external static _statSync(_Namespace namespace, String path);
+
+  /**
+   * Calls the operating system's `stat()` function (or equivalent) on [path].
+   *
+   * Returns a [FileStat] object containing the data returned by `stat()`.
+   * If the call fails, returns a [FileStat] object with [FileStat.type] set to
+   * [FileSystemEntityType.notFound] and the other fields invalid.
+   */
+  static FileStat statSync(String path) {
+    final IOOverrides overrides = IOOverrides.current;
+    if (overrides == null) {
+      return _statSyncInternal(path);
+    }
+    return overrides.statSync(path);
+  }
+
+  static FileStat _statSyncInternal(String path) {
+    // Trailing path is not supported on Windows.
+    if (Platform.isWindows) {
+      path = FileSystemEntity._trimTrailingPathSeparators(path);
+    }
+    var data = _statSync(_Namespace._namespace, path);
+    if (data is OSError) return FileStat._notFound;
+    return new FileStat._internal(
+        new DateTime.fromMillisecondsSinceEpoch(data[_changedTime]),
+        new DateTime.fromMillisecondsSinceEpoch(data[_modifiedTime]),
+        new DateTime.fromMillisecondsSinceEpoch(data[_accessedTime]),
+        FileSystemEntityType._lookup(data[_type]),
+        data[_mode],
+        data[_size]);
+  }
+
+  /**
+   * Asynchronously calls the operating system's `stat()` function (or
+   * equivalent) on [path].
+   *
+   * Returns a [Future] which completes with the same results as [statSync].
+   */
+  static Future<FileStat> stat(String path) {
+    final IOOverrides overrides = IOOverrides.current;
+    if (overrides == null) {
+      return _stat(path);
+    }
+    return overrides.stat(path);
+  }
+
+  static Future<FileStat> _stat(String path) {
+    // Trailing path is not supported on Windows.
+    if (Platform.isWindows) {
+      path = FileSystemEntity._trimTrailingPathSeparators(path);
+    }
+    return _File._dispatchWithNamespace(_IOService.fileStat, [null, path])
+        .then((response) {
+      if (_isErrorResponse(response)) {
+        return FileStat._notFound;
+      }
+      // Unwrap the real list from the "I'm not an error" wrapper.
+      List data = response[1];
+      return new FileStat._internal(
+          new DateTime.fromMillisecondsSinceEpoch(data[_changedTime]),
+          new DateTime.fromMillisecondsSinceEpoch(data[_modifiedTime]),
+          new DateTime.fromMillisecondsSinceEpoch(data[_accessedTime]),
+          FileSystemEntityType._lookup(data[_type]),
+          data[_mode],
+          data[_size]);
+    });
+  }
+
+  String toString() => """
+FileStat: type $type
+          changed $changed
+          modified $modified
+          accessed $accessed
+          mode ${modeString()}
+          size $size""";
+
+  /**
+   * Returns the mode value as a human-readable string.
+   *
+   * The string is in the format "rwxrwxrwx", reflecting the user, group, and
+   * world permissions to read, write, and execute the file system object, with
+   * "-" replacing the letter for missing permissions.  Extra permission bits
+   * may be represented by prepending "(suid)", "(guid)", and/or "(sticky)" to
+   * the mode string.
+   */
+  String modeString() {
+    var permissions = mode & 0xFFF;
+    var codes = const ['---', '--x', '-w-', '-wx', 'r--', 'r-x', 'rw-', 'rwx'];
+    var result = [];
+    if ((permissions & 0x800) != 0) result.add("(suid) ");
+    if ((permissions & 0x400) != 0) result.add("(guid) ");
+    if ((permissions & 0x200) != 0) result.add("(sticky) ");
+    result
+      ..add(codes[(permissions >> 6) & 0x7])
+      ..add(codes[(permissions >> 3) & 0x7])
+      ..add(codes[permissions & 0x7]);
+    return result.join();
+  }
+}
+
+/**
+ * The common super class for [File], [Directory], and [Link] objects.
+ *
+ * [FileSystemEntity] objects are returned from directory listing
+ * operations. To determine if a FileSystemEntity is a [File], a
+ * [Directory], or a [Link] perform a type check:
+ *
+ *     if (entity is File) (entity as File).readAsStringSync();
+ *
+ * You can also use the [type] or [typeSync] methods to determine
+ * the type of a file system object.
+ *
+ * Most methods in this class occur in synchronous and asynchronous pairs,
+ * for example, [exists] and [existsSync].
+ * Unless you have a specific reason for using the synchronous version
+ * of a method, prefer the asynchronous version to avoid blocking your program.
+ *
+ * Here's the exists method in action:
+ *
+ *     entity.exists().then((isThere) {
+ *       isThere ? print('exists') : print('non-existent');
+ *     });
+ *
+ *
+ * ## Other resources
+ *
+ * * [Dart by
+ *   Example](https://www.dartlang.org/dart-by-example/#files-directories-and-symlinks)
+ *   provides additional task-oriented code samples that show how to use various
+ *   API from the [Directory] class and the [File] class, both subclasses of
+ *   FileSystemEntity.
+ *
+ * * [I/O for Command-Line
+ *   Apps](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartio---io-for-command-line-apps),
+ *   a section from _A Tour of the Dart Libraries_ covers files and directories.
+ *
+ * * [Write Command-Line Apps](https://www.dartlang.org/docs/tutorials/cmdline/),
+ *   a tutorial about writing command-line apps, includes information about
+ *   files and directories.
+ */
+abstract class FileSystemEntity {
+  String _path;
+  Uint8List _rawPath;
+
+  String get path;
+
+  /**
+   * Returns a [Uri] representing the file system entity's location.
+   *
+   * The returned URI's scheme is always "file" if the entity's [path] is
+   * absolute, otherwise the scheme will be empty.
+   */
+  Uri get uri => new Uri.file(path);
+
+  /**
+   * Checks whether the file system entity with this path exists. Returns
+   * a [:Future<bool>:] that completes with the result.
+   *
+   * Since FileSystemEntity is abstract, every FileSystemEntity object
+   * is actually an instance of one of the subclasses [File],
+   * [Directory], and [Link].  Calling [exists] on an instance of one
+   * of these subclasses checks whether the object exists in the file
+   * system object exists and is of the correct type (file, directory,
+   * or link).  To check whether a path points to an object on the
+   * file system, regardless of the object's type, use the [type]
+   * static method.
+   *
+   */
+  Future<bool> exists();
+
+  /**
+   * Synchronously checks whether the file system entity with this path
+   * exists.
+   *
+   * Since FileSystemEntity is abstract, every FileSystemEntity object
+   * is actually an instance of one of the subclasses [File],
+   * [Directory], and [Link].  Calling [existsSync] on an instance of
+   * one of these subclasses checks whether the object exists in the
+   * file system object exists and is of the correct type (file,
+   * directory, or link).  To check whether a path points to an object
+   * on the file system, regardless of the object's type, use the
+   * [typeSync] static method.
+   */
+  bool existsSync();
+
+  /**
+   * Renames this file system entity.
+   *
+   * Returns a `Future<FileSystemEntity>` that completes with a
+   * [FileSystemEntity] instance for the renamed file system entity.
+   *
+   * If [newPath] identifies an existing entity of the same type, that entity
+   * is replaced. If [newPath] identifies an existing entity of a different
+   * type, the operation fails and the future completes with an exception.
+   */
+  Future<FileSystemEntity> rename(String newPath);
+
+  /**
+   * Synchronously renames this file system entity.
+   *
+   * Returns a [FileSystemEntity] instance for the renamed entity.
+   *
+   * If [newPath] identifies an existing entity of the same type, that entity
+   * is replaced. If [newPath] identifies an existing entity of a different
+   * type, the operation fails and an exception is thrown.
+   */
+  FileSystemEntity renameSync(String newPath);
+
+  /**
+   * Resolves the path of a file system object relative to the
+   * current working directory.
+   *
+   * Resolves all symbolic links on the path and resolves all `..` and `.` path
+   * segments.
+   *
+   * [resolveSymbolicLinks] uses the operating system's native
+   * file system API to resolve the path, using the `realpath` function
+   * on linux and OS X, and the `GetFinalPathNameByHandle` function on
+   * Windows. If the path does not point to an existing file system object,
+   * `resolveSymbolicLinks` throws a `FileSystemException`.
+   *
+   * On Windows the `..` segments are resolved _before_ resolving the symbolic
+   * link, and on other platforms the symbolic links are _resolved to their
+   * target_ before applying a `..` that follows.
+   *
+   * To ensure the same behavior on all platforms resolve `..` segments before
+   * calling `resolveSymbolicLinks`. One way of doing this is with the `Uri`
+   * class:
+   *
+   *     var path = Uri.parse('.').resolveUri(new Uri.file(input)).toFilePath();
+   *     if (path == '') path = '.';
+   *     new File(path).resolveSymbolicLinks().then((resolved) {
+   *       print(resolved);
+   *     });
+   *
+   * since `Uri.resolve` removes `..` segments. This will result in the Windows
+   * behavior.
+   */
+  Future<String> resolveSymbolicLinks() {
+    return _File._dispatchWithNamespace(
+        _IOService.fileResolveSymbolicLinks, [null, _rawPath]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(
+            response, "Cannot resolve symbolic links", path);
+      }
+      return response;
+    });
+  }
+
+  /**
+   * Resolves the path of a file system object relative to the
+   * current working directory.
+   *
+   * Resolves all symbolic links on the path and resolves all `..` and `.` path
+   * segments.
+   *
+   * [resolveSymbolicLinksSync] uses the operating system's native
+   * file system API to resolve the path, using the `realpath` function
+   * on linux and OS X, and the `GetFinalPathNameByHandle` function on
+   * Windows. If the path does not point to an existing file system object,
+   * `resolveSymbolicLinksSync` throws a `FileSystemException`.
+   *
+   * On Windows the `..` segments are resolved _before_ resolving the symbolic
+   * link, and on other platforms the symbolic links are _resolved to their
+   * target_ before applying a `..` that follows.
+   *
+   * To ensure the same behavior on all platforms resolve `..` segments before
+   * calling `resolveSymbolicLinksSync`. One way of doing this is with the `Uri`
+   * class:
+   *
+   *     var path = Uri.parse('.').resolveUri(new Uri.file(input)).toFilePath();
+   *     if (path == '') path = '.';
+   *     var resolved = new File(path).resolveSymbolicLinksSync();
+   *     print(resolved);
+   *
+   * since `Uri.resolve` removes `..` segments. This will result in the Windows
+   * behavior.
+   */
+  String resolveSymbolicLinksSync() {
+    var result = _resolveSymbolicLinks(_Namespace._namespace, _rawPath);
+    _throwIfError(result, "Cannot resolve symbolic links", path);
+    return result;
+  }
+
+  /**
+   * Calls the operating system's stat() function on the [path] of this
+   * [FileSystemEntity].
+   *
+   * Identical to [:FileStat.stat(this.path):].
+   *
+   * Returns a [:Future<FileStat>:] object containing the data returned by
+   * stat().
+   *
+   * If the call fails, completes the future with a [FileStat] object
+   * with `.type` set to [FileSystemEntityType.notFound] and the other fields
+   * invalid.
+   */
+  Future<FileStat> stat() => FileStat.stat(path);
+
+  /**
+   * Synchronously calls the operating system's stat() function on the
+   * [path] of this [FileSystemEntity].
+   *
+   * Identical to [:FileStat.statSync(this.path):].
+   *
+   * Returns a [FileStat] object containing the data returned by stat().
+   *
+   * If the call fails, returns a [FileStat] object with `.type` set to
+   * [FileSystemEntityType.notFound] and the other fields invalid.
+   */
+  FileStat statSync() => FileStat.statSync(path);
+
+  /**
+   * Deletes this [FileSystemEntity].
+   *
+   * If the [FileSystemEntity] is a directory, and if [recursive] is false,
+   * the directory must be empty. Otherwise, if [recursive] is true, the
+   * directory and all sub-directories and files in the directories are
+   * deleted. Links are not followed when deleting recursively. Only the link
+   * is deleted, not its target.
+   *
+   * If [recursive] is true, the [FileSystemEntity] is deleted even if the type
+   * of the [FileSystemEntity] doesn't match the content of the file system.
+   * This behavior allows [delete] to be used to unconditionally delete any file
+   * system object.
+   *
+   * Returns a [:Future<FileSystemEntity>:] that completes with this
+   * [FileSystemEntity] when the deletion is done. If the [FileSystemEntity]
+   * cannot be deleted, the future completes with an exception.
+   */
+  Future<FileSystemEntity> delete({bool recursive: false}) =>
+      _delete(recursive: recursive);
+
+  /**
+   * Synchronously deletes this [FileSystemEntity].
+   *
+   * If the [FileSystemEntity] is a directory, and if [recursive] is false,
+   * the directory must be empty. Otherwise, if [recursive] is true, the
+   * directory and all sub-directories and files in the directories are
+   * deleted. Links are not followed when deleting recursively. Only the link
+   * is deleted, not its target.
+   *
+   * If [recursive] is true, the [FileSystemEntity] is deleted even if the type
+   * of the [FileSystemEntity] doesn't match the content of the file system.
+   * This behavior allows [deleteSync] to be used to unconditionally delete any
+   * file system object.
+   *
+   * Throws an exception if the [FileSystemEntity] cannot be deleted.
+   */
+  void deleteSync({bool recursive: false}) => _deleteSync(recursive: recursive);
+
+  /**
+   * Start watching the [FileSystemEntity] for changes.
+   *
+   * The implementation uses platform-dependent event-based APIs for receiving
+   * file-system notifications, thus behavior depends on the platform.
+   *
+   *   * `Windows`: Uses `ReadDirectoryChangesW`. The implementation only
+   *     supports watching directories. Recursive watching is supported.
+   *   * `Linux`: Uses `inotify`. The implementation supports watching both
+   *     files and directories. Recursive watching is not supported.
+   *     Note: When watching files directly, delete events might not happen
+   *     as expected.
+   *   * `OS X`: Uses `FSEvents`. The implementation supports watching both
+   *     files and directories. Recursive watching is supported.
+   *
+   * The system will start listening for events once the returned [Stream] is
+   * being listened to, not when the call to [watch] is issued.
+   *
+   * The returned value is an endless broadcast [Stream], that only stops when
+   * one of the following happens:
+   *
+   *   * The [Stream] is canceled, e.g. by calling `cancel` on the
+   *      [StreamSubscription].
+   *   * The [FileSystemEntity] being watches, is deleted.
+   *
+   * Use `events` to specify what events to listen for. The constants in
+   * [FileSystemEvent] can be or'ed together to mix events. Default is
+   * [FileSystemEvent.ALL].
+   *
+   * A move event may be reported as seperate delete and create events.
+   */
+  Stream<FileSystemEvent> watch(
+      {int events: FileSystemEvent.all, bool recursive: false}) {
+    // FIXME(bkonyi): find a way to do this using the raw path.
+    final String trimmedPath = _trimTrailingPathSeparators(path);
+    final IOOverrides overrides = IOOverrides.current;
+    if (overrides == null) {
+      return _FileSystemWatcher._watch(trimmedPath, events, recursive);
+    }
+    return overrides.fsWatch(trimmedPath, events, recursive);
+  }
+
+  Future<FileSystemEntity> _delete({bool recursive: false});
+  void _deleteSync({bool recursive: false});
+
+  static Future<bool> _identical(String path1, String path2) {
+    return _File._dispatchWithNamespace(
+        _IOService.fileIdentical, [null, path1, path2]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response,
+            "Error in FileSystemEntity.identical($path1, $path2)", "");
+      }
+      return response;
+    });
+  }
+
+  /**
+   * Checks whether two paths refer to the same object in the
+   * file system.
+   *
+   * Returns a [:Future<bool>:] that completes with the result.
+   *
+   * Comparing a link to its target returns false, as does comparing two links
+   * that point to the same target.  To check the target of a link, use
+   * Link.target explicitly to fetch it.  Directory links appearing
+   * inside a path are followed, though, to find the file system object.
+   *
+   * Completes the returned Future with an error if one of the paths points
+   * to an object that does not exist.
+   */
+  static Future<bool> identical(String path1, String path2) {
+    IOOverrides overrides = IOOverrides.current;
+    if (overrides == null) {
+      return _identical(path1, path2);
+    }
+    return overrides.fseIdentical(path1, path2);
+  }
+
+  static final RegExp _absoluteWindowsPathPattern =
+      new RegExp(r'^(\\\\|[a-zA-Z]:[/\\])');
+
+  /**
+   * Returns a [bool] indicating whether this object's path is absolute.
+   *
+   * On Windows, a path is absolute if it starts with \\\\ or a drive letter
+   * between a and z (upper or lower case) followed by :\\ or :/.
+   * On non-Windows, a path is absolute if it starts with /.
+   */
+  bool get isAbsolute {
+    if (Platform.isWindows) {
+      return path.startsWith(_absoluteWindowsPathPattern);
+    } else {
+      return path.startsWith('/');
+    }
+  }
+
+  /**
+   * Returns a [FileSystemEntity] whose path is the absolute path to [this].
+   *
+   * The type of the returned instance is the type of [this].
+   *
+   * The absolute path is computed by prefixing
+   * a relative path with the current working directory, and returning
+   * an absolute path unchanged.
+   */
+  FileSystemEntity get absolute;
+
+  String get _absolutePath {
+    if (isAbsolute) return path;
+    String current = Directory.current.path;
+    if (current.endsWith('/') ||
+        (Platform.isWindows && current.endsWith('\\'))) {
+      return '$current$path';
+    } else {
+      return '$current${Platform.pathSeparator}$path';
+    }
+  }
+
+  Uint8List get _rawAbsolutePath {
+    if (isAbsolute) return _rawPath;
+    var current = Directory.current._rawPath.toList();
+    assert(current.last == 0);
+    current.removeLast(); // Remove null terminator.
+    if ((current.last == '/'.codeUnitAt(0)) ||
+        (Platform.isWindows && (current.last == '\\'.codeUnitAt(0)))) {
+      current.addAll(_rawPath);
+      return new Uint8List.fromList(current);
+    } else {
+      current.addAll(utf8.encode(Platform.pathSeparator));
+      current.addAll(_rawPath);
+      return new Uint8List.fromList(current);
+    }
+  }
+
+  static bool _identicalSync(String path1, String path2) {
+    var result = _identicalNative(_Namespace._namespace, path1, path2);
+    _throwIfError(result, 'Error in FileSystemEntity.identicalSync');
+    return result;
+  }
+
+  /**
+   * Synchronously checks whether two paths refer to the same object in the
+   * file system.
+   *
+   * Comparing a link to its target returns false, as does comparing two links
+   * that point to the same target.  To check the target of a link, use
+   * Link.target explicitly to fetch it.  Directory links appearing
+   * inside a path are followed, though, to find the file system object.
+   *
+   * Throws an error if one of the paths points to an object that does not
+   * exist.
+   */
+  static bool identicalSync(String path1, String path2) {
+    IOOverrides overrides = IOOverrides.current;
+    if (overrides == null) {
+      return _identicalSync(path1, path2);
+    }
+    return overrides.fseIdenticalSync(path1, path2);
+  }
+
+  /**
+   * Test if [watch] is supported on the current system.
+   *
+   * OS X 10.6 and below is not supported.
+   */
+  static bool get isWatchSupported {
+    final IOOverrides overrides = IOOverrides.current;
+    if (overrides == null) {
+      return _FileSystemWatcher.isSupported;
+    }
+    return overrides.fsWatchIsSupported();
+  }
+
+  // The native methods which determine type of the FileSystemEntity require
+  // that the buffer provided is null terminated.
+  static Uint8List _toUtf8Array(String s) =>
+      _toNullTerminatedUtf8Array(utf8.encode(s));
+
+  static Uint8List _toNullTerminatedUtf8Array(Uint8List l) {
+    if (l == null) {
+      return null;
+    }
+    if (l.isNotEmpty && l.last != 0) {
+      final tmp = new Uint8List(l.length + 1);
+      tmp.setRange(0, l.length, l);
+      return tmp;
+    } else {
+      return l;
+    }
+  }
+
+  static String _toStringFromUtf8Array(Uint8List l) {
+    if (l == null) {
+      return '';
+    }
+    Uint8List nonNullTerminated = l;
+    if (l.last == 0) {
+      nonNullTerminated = new Uint8List.view(l.buffer, 0, l.length - 1);
+    }
+    return utf8.decode(nonNullTerminated, allowMalformed: true);
+  }
+
+  /**
+   * Finds the type of file system object that a path points to.
+   *
+   * Returns a [:Future<FileSystemEntityType>:] that completes with the same
+   * results as [typeSync].
+   */
+  static Future<FileSystemEntityType> type(String path,
+      {bool followLinks: true}) {
+    return _getType(_toUtf8Array(path), followLinks);
+  }
+
+  /**
+   * Synchronously finds the type of file system object that a path points to.
+   *
+   * Returns a [FileSystemEntityType].
+   *
+   * Returns [FileSystemEntityType.link] only if [followLinks] is false and if
+   * [path] points to a link.
+   *
+   * Returns [FileSystemEntityType.notFound] if [path] does not point to a file
+   * system object or if any other error occurs in looking up the path.
+   */
+  static FileSystemEntityType typeSync(String path, {bool followLinks: true}) {
+    return _getTypeSync(_toUtf8Array(path), followLinks);
+  }
+
+  /**
+   * Checks if type(path, followLinks: false) returns FileSystemEntityType.link.
+   */
+  static Future<bool> isLink(String path) => _isLinkRaw(_toUtf8Array(path));
+
+  static Future<bool> _isLinkRaw(Uint8List rawPath) => _getType(rawPath, false)
+      .then((type) => (type == FileSystemEntityType.link));
+
+  /**
+   * Checks if type(path) returns FileSystemEntityType.file.
+   */
+  static Future<bool> isFile(String path) => _getType(_toUtf8Array(path), true)
+      .then((type) => (type == FileSystemEntityType.file));
+
+  /**
+   * Checks if type(path) returns FileSystemEntityType.directory.
+   */
+  static Future<bool> isDirectory(String path) =>
+      _getType(_toUtf8Array(path), true)
+          .then((type) => (type == FileSystemEntityType.directory));
+
+  /**
+   * Synchronously checks if typeSync(path, followLinks: false) returns
+   * FileSystemEntityType.link.
+   */
+  static bool isLinkSync(String path) => _isLinkRawSync(_toUtf8Array(path));
+
+  static bool _isLinkRawSync(rawPath) =>
+      (_getTypeSync(rawPath, false) == FileSystemEntityType.link);
+
+  /**
+   * Synchronously checks if typeSync(path) returns
+   * FileSystemEntityType.file.
+   */
+  static bool isFileSync(String path) =>
+      (_getTypeSync(_toUtf8Array(path), true) == FileSystemEntityType.file);
+
+  /**
+   * Synchronously checks if typeSync(path) returns
+   * FileSystemEntityType.directory.
+   */
+  static bool isDirectorySync(String path) =>
+      (_getTypeSync(_toUtf8Array(path), true) ==
+          FileSystemEntityType.directory);
+
+  external static _getTypeNative(
+      _Namespace namespace, Uint8List rawPath, bool followLinks);
+  external static _identicalNative(
+      _Namespace namespace, String path1, String path2);
+  external static _resolveSymbolicLinks(_Namespace namespace, Uint8List path);
+
+  // Finds the next-to-last component when dividing at path separators.
+  static final RegExp _parentRegExp = Platform.isWindows
+      ? new RegExp(r'[^/\\][/\\]+[^/\\]')
+      : new RegExp(r'[^/]/+[^/]');
+
+  /**
+   * Removes the final path component of a path, using the platform's
+   * path separator to split the path.
+   *
+   * Will not remove the root component of a Windows path, like "C:\\" or
+   * "\\\\server_name\\". Ignores trailing path separators, and leaves no
+   * trailing path separators.
+   */
+  static String parentOf(String path) {
+    int rootEnd = -1;
+    if (Platform.isWindows) {
+      if (path.startsWith(_absoluteWindowsPathPattern)) {
+        // Root ends at first / or \ after the first two characters.
+        rootEnd = path.indexOf(new RegExp(r'[/\\]'), 2);
+        if (rootEnd == -1) return path;
+      } else if (path.startsWith('\\') || path.startsWith('/')) {
+        rootEnd = 0;
+      }
+    } else if (path.startsWith('/')) {
+      rootEnd = 0;
+    }
+    // Ignore trailing slashes.
+    // All non-trivial cases have separators between two non-separators.
+    int pos = path.lastIndexOf(_parentRegExp);
+    if (pos > rootEnd) {
+      return path.substring(0, pos + 1);
+    } else if (rootEnd > -1) {
+      return path.substring(0, rootEnd + 1);
+    } else {
+      return '.';
+    }
+  }
+
+  /**
+   * The directory containing [this].
+   */
+  Directory get parent => new Directory(parentOf(path));
+
+  static FileSystemEntityType _getTypeSyncHelper(
+      Uint8List rawPath, bool followLinks) {
+    var result = _getTypeNative(_Namespace._namespace, rawPath, followLinks);
+    _throwIfError(result, 'Error getting type of FileSystemEntity');
+    return FileSystemEntityType._lookup(result);
+  }
+
+  static FileSystemEntityType _getTypeSync(
+      Uint8List rawPath, bool followLinks) {
+    IOOverrides overrides = IOOverrides.current;
+    if (overrides == null) {
+      return _getTypeSyncHelper(rawPath, followLinks);
+    }
+    return overrides.fseGetTypeSync(
+        utf8.decode(rawPath, allowMalformed: true), followLinks);
+  }
+
+  static Future<FileSystemEntityType> _getTypeRequest(
+      Uint8List rawPath, bool followLinks) {
+    return _File._dispatchWithNamespace(
+        _IOService.fileType, [null, rawPath, followLinks]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, "Error getting type",
+            utf8.decode(rawPath, allowMalformed: true));
+      }
+      return FileSystemEntityType._lookup(response);
+    });
+  }
+
+  static Future<FileSystemEntityType> _getType(
+      Uint8List rawPath, bool followLinks) {
+    IOOverrides overrides = IOOverrides.current;
+    if (overrides == null) {
+      return _getTypeRequest(rawPath, followLinks);
+    }
+    return overrides.fseGetType(
+        utf8.decode(rawPath, allowMalformed: true), followLinks);
+  }
+
+  static _throwIfError(Object result, String msg, [String path]) {
+    if (result is OSError) {
+      throw new FileSystemException(msg, path, result);
+    } else if (result is ArgumentError) {
+      throw result;
+    }
+  }
+
+  // TODO(bkonyi): find a way to do this with raw paths.
+  static String _trimTrailingPathSeparators(String path) {
+    // Don't handle argument errors here.
+    if (path == null) return path;
+    if (Platform.isWindows) {
+      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;
+  }
+
+  // TODO(bkonyi): find a way to do this with raw paths.
+  static String _ensureTrailingPathSeparators(String path) {
+    // Don't handle argument errors here.
+    if (path == null) return path;
+    if (path.isEmpty) path = '.';
+    if (Platform.isWindows) {
+      while (!path.endsWith(Platform.pathSeparator) && !path.endsWith('/')) {
+        path = "$path${Platform.pathSeparator}";
+      }
+    } else {
+      while (!path.endsWith(Platform.pathSeparator)) {
+        path = "$path${Platform.pathSeparator}";
+      }
+    }
+    return path;
+  }
+}
+
+/**
+ * Base event class emitted by [FileSystemEntity.watch].
+ */
+class FileSystemEvent {
+  /**
+   * Bitfield for [FileSystemEntity.watch], to enable [FileSystemCreateEvent]s.
+   */
+  static const int create = 1 << 0;
+  @Deprecated("Use create instead")
+  static const int CREATE = 1 << 0;
+
+  /**
+   * Bitfield for [FileSystemEntity.watch], to enable [FileSystemModifyEvent]s.
+   */
+  static const int modify = 1 << 1;
+  @Deprecated("Use modify instead")
+  static const int MODIFY = 1 << 1;
+
+  /**
+   * Bitfield for [FileSystemEntity.watch], to enable [FileSystemDeleteEvent]s.
+   */
+  static const int delete = 1 << 2;
+  @Deprecated("Use delete instead")
+  static const int DELETE = 1 << 2;
+
+  /**
+   * Bitfield for [FileSystemEntity.watch], to enable [FileSystemMoveEvent]s.
+   */
+  static const int move = 1 << 3;
+  @Deprecated("Use move instead")
+  static const int MOVE = 1 << 3;
+
+  /**
+   * Bitfield for [FileSystemEntity.watch], for enabling all of [create],
+   * [modify], [delete] and [move].
+   */
+  static const int all = create | modify | delete | move;
+  @Deprecated("Use all instead")
+  static const int ALL = create | modify | delete | move;
+
+  static const int _modifyAttributes = 1 << 4;
+  static const int _deleteSelf = 1 << 5;
+  static const int _isDir = 1 << 6;
+
+  /**
+   * The type of event. See [FileSystemEvent] for a list of events.
+   */
+  final int type;
+
+  /**
+   * The path that triggered the event.
+   *
+   * Depending on the platform and the FileSystemEntity, the path may be
+   * relative.
+   */
+  final String path;
+
+  /**
+   * Is `true` if the event target was a directory.
+   *
+   * Note that if the file has been deleted by the time the event has arrived,
+   * this will always be `false` on Windows. In particular, it will always be
+   * `false` for `delete` events.
+   */
+  final bool isDirectory;
+
+  FileSystemEvent._(this.type, this.path, this.isDirectory);
+}
+
+/**
+ * File system event for newly created file system objects.
+ */
+class FileSystemCreateEvent extends FileSystemEvent {
+  FileSystemCreateEvent._(path, isDirectory)
+      : super._(FileSystemEvent.create, path, isDirectory);
+
+  String toString() => "FileSystemCreateEvent('$path')";
+}
+
+/**
+ * File system event for modifications of file system objects.
+ */
+class FileSystemModifyEvent extends FileSystemEvent {
+  /**
+   * If the content was changed and not only the attributes, [contentChanged]
+   * is `true`.
+   */
+  final bool contentChanged;
+
+  FileSystemModifyEvent._(path, isDirectory, this.contentChanged)
+      : super._(FileSystemEvent.modify, path, isDirectory);
+
+  String toString() =>
+      "FileSystemModifyEvent('$path', contentChanged=$contentChanged)";
+}
+
+/**
+ * File system event for deletion of file system objects.
+ */
+class FileSystemDeleteEvent extends FileSystemEvent {
+  FileSystemDeleteEvent._(path, isDirectory)
+      : super._(FileSystemEvent.delete, path, isDirectory);
+
+  String toString() => "FileSystemDeleteEvent('$path')";
+}
+
+/**
+ * File system event for moving of file system objects.
+ */
+class FileSystemMoveEvent extends FileSystemEvent {
+  /**
+   * If the underlying implementation is able to identify the destination of
+   * the moved file, [destination] will be set. Otherwise, it will be `null`.
+   */
+  final String destination;
+
+  FileSystemMoveEvent._(path, isDirectory, this.destination)
+      : super._(FileSystemEvent.move, path, isDirectory);
+
+  String toString() {
+    var buffer = new StringBuffer();
+    buffer.write("FileSystemMoveEvent('$path'");
+    if (destination != null) buffer.write(", '$destination'");
+    buffer.write(')');
+    return buffer.toString();
+  }
+}
+
+class _FileSystemWatcher {
+  external static Stream<FileSystemEvent> _watch(
+      String path, int events, bool recursive);
+  external static bool get isSupported;
+}
diff --git a/sdk_nnbd/lib/io/io.dart b/sdk_nnbd/lib/io/io.dart
new file mode 100644
index 0000000..c640c5b
--- /dev/null
+++ b/sdk_nnbd/lib/io/io.dart
@@ -0,0 +1,227 @@
+// Copyright (c) 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.
+
+/**
+ * File, socket, HTTP, and other I/O support for non-web applications.
+ *
+ * **Important:** Browser-based applications can't use this library.
+ * Only servers, command-line scripts, and Flutter mobile apps can import
+ * and use dart:io.
+ *
+ * This library allows you to work with files, directories,
+ * sockets, processes, HTTP servers and clients, and more.
+ * Many operations related to input and output are asynchronous
+ * and are handled using [Future]s or [Stream]s, both of which
+ * are defined in the [dart:async
+ * library](../dart-async/dart-async-library.html).
+ *
+ * To use the dart:io library in your code:
+ *
+ *     import 'dart:io';
+ *
+ * For an introduction to I/O in Dart, see the [dart:io library
+ * tour](https://www.dartlang.org/dart-vm/io-library-tour).
+ *
+ * ## File, Directory, and Link
+ *
+ * An instance of [File], [Directory], or [Link] represents a file,
+ * directory, or link, respectively, in the native file system.
+ *
+ * You can manipulate the file system through objects of these types.
+ * For example, you can rename a file or directory:
+ *
+ *     File myFile = new File('myFile.txt');
+ *     myFile.rename('yourFile.txt').then((_) => print('file renamed'));
+ *
+ * Many methods provided by the File, Directory, and Link classes
+ * run asynchronously and return a Future.
+ *
+ * ## FileSystemEntity
+ *
+ * File, Directory, and Link all extend [FileSystemEntity].
+ * In addition to being the superclass for these classes,
+ * FileSystemEntity has a number of static methods for working with paths.
+ *
+ * To get information about a path,
+ * you can use the FileSystemEntity static methods
+ * such as 'isDirectory', 'isFile', and 'exists'.
+ * Because file system access involves I/O, these methods
+ * are asynchronous and return a Future.
+ *
+ *     FileSystemEntity.isDirectory(myPath).then((isDir) {
+ *       if (isDir) {
+ *         print('$myPath is a directory');
+ *       } else {
+ *         print('$myPath is not a directory');
+ *       }
+ *     });
+ *
+ * ## HttpServer and HttpClient
+ *
+ * The classes [HttpServer] and [HttpClient]
+ * provide HTTP server and HTTP client functionality.
+ *
+ * The [HttpServer] class provides the basic functionality for
+ * implementing an HTTP server.
+ * For some higher-level building-blocks, we recommend that you try
+ * the [shelf](https://pub.dartlang.org/packages/shelf)
+ * pub package, which contains
+ * a set of high-level classes that, together with the [HttpServer] class
+ * in this library, make it easier to implement HTTP servers.
+ *
+ * ## Process
+ *
+ * The [Process] class provides a way to run a process on
+ * the native machine.
+ * For example, the following code spawns a process that recursively lists
+ * the files under `web`.
+ *
+ *     Process.start('ls', ['-R', 'web']).then((process) {
+ *       stdout.addStream(process.stdout);
+ *       stderr.addStream(process.stderr);
+ *       process.exitCode.then(print);
+ *     });
+ *
+ * Using `start()` returns a Future, which completes with a [Process] object
+ * when the process has started. This [Process] object allows you to interact
+ * with the process while it is running. Using `run()` returns a Future, which
+ * completes with a [ProcessResult] object when the spawned process has
+ * terminated. This [ProcessResult] object collects the output and exit code
+ * from the process.
+ *
+ * When using `start()`,
+ * you need to read all data coming on the stdout and stderr streams otherwise
+ * the system resources will not be freed.
+ *
+ * ## WebSocket
+ *
+ * The [WebSocket] class provides support for the web socket protocol. This
+ * allows full-duplex communications between client and server applications.
+ *
+ * A web socket server uses a normal HTTP server for accepting web socket
+ * connections. The initial handshake is a HTTP request which is then upgraded to a
+ * web socket connection.
+ * The server upgrades the request using [WebSocketTransformer]
+ * and listens for the data on the returned web socket.
+ * For example, here's a mini server that listens for 'ws' data
+ * on a WebSocket:
+ *
+ *     runZoned(() async {
+ *       var server = await HttpServer.bind('127.0.0.1', 4040);
+ *       server.listen((HttpRequest req) async {
+ *         if (req.uri.path == '/ws') {
+ *           var socket = await WebSocketTransformer.upgrade(req);
+ *           socket.listen(handleMsg);
+ *         }
+ *       });
+ *     }, onError: (e) => print("An error occurred."));
+ *
+ * The client connects to the WebSocket using the `connect()` method
+ * and a URI that uses the Web Socket protocol.
+ * The client can write to the WebSocket with the `add()` method.
+ * For example,
+ *
+ *     var socket = await WebSocket.connect('ws://127.0.0.1:4040/ws');
+ *     socket.add('Hello, World!');
+ *
+ * Check out the
+ * [websocket_sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/websockets/basics)
+ * app, which uses WebSockets to communicate with a server.
+ *
+ * ## Socket and ServerSocket
+ *
+ * Clients and servers use [Socket]s to communicate using the TCP protocol.
+ * Use [ServerSocket] on the server side and [Socket] on the client.
+ * The server creates a listening socket using the `bind()` method and
+ * then listens for incoming connections on the socket. For example:
+ *
+ *     ServerSocket.bind('127.0.0.1', 4041)
+ *       .then((serverSocket) {
+ *         serverSocket.listen((socket) {
+ *           socket.transform(utf8.decoder).listen(print);
+ *         });
+ *       });
+ *
+ * A client connects a Socket using the `connect()` method,
+ * which returns a Future.
+ * Using `write()`, `writeln()`, or `writeAll()` are the easiest ways to
+ * send data over the socket.
+ * For example:
+ *
+ *     Socket.connect('127.0.0.1', 4041).then((socket) {
+ *       socket.write('Hello, World!');
+ *     });
+ *
+ * Besides [Socket] and [ServerSocket], the [RawSocket] and
+ * [RawServerSocket] classes are available for lower-level access
+ * to async socket IO.
+ *
+ * ## Standard output, error, and input streams
+ *
+ * This library provides the standard output, error, and input
+ * streams, named 'stdout', 'stderr', and 'stdin', respectively.
+ *
+ * The stdout and stderr streams are both [IOSink]s and have the same set
+ * of methods and properties.
+ *
+ * To write a string to 'stdout':
+ *
+ *     stdout.writeln('Hello, World!');
+ *
+ * To write a list of objects to 'stderr':
+ *
+ *     stderr.writeAll([ 'That ', 'is ', 'an ', 'error.', '\n']);
+ *
+ * The standard input stream is a true [Stream], so it inherits
+ * properties and methods from the Stream class.
+ *
+ * To read text synchronously from the command line
+ * (the program blocks waiting for user to type information):
+ *
+ *      String inputText = stdin.readLineSync();
+ *
+ * {@category VM}
+ */
+library dart.io;
+
+import 'dart:async';
+import 'dart:_internal' hide Symbol;
+import 'dart:collection'
+    show HashMap, HashSet, Queue, ListQueue, MapBase, UnmodifiableMapView;
+import 'dart:convert';
+import 'dart:developer' hide log;
+import 'dart:isolate';
+import 'dart:math';
+import 'dart:typed_data';
+
+export 'dart:_http';
+export 'dart:_internal' show HttpStatus;
+
+part 'bytes_builder.dart';
+part 'common.dart';
+part 'data_transformer.dart';
+part 'directory.dart';
+part 'directory_impl.dart';
+part 'embedder_config.dart';
+part 'eventhandler.dart';
+part 'file.dart';
+part 'file_impl.dart';
+part 'file_system_entity.dart';
+part 'io_resource_info.dart';
+part 'io_sink.dart';
+part 'io_service.dart';
+part 'link.dart';
+part 'namespace_impl.dart';
+part 'overrides.dart';
+part 'platform.dart';
+part 'platform_impl.dart';
+part 'process.dart';
+part 'secure_server_socket.dart';
+part 'secure_socket.dart';
+part 'security_context.dart';
+part 'service_object.dart';
+part 'socket.dart';
+part 'stdio.dart';
+part 'string_transformer.dart';
+part 'sync_socket.dart';
diff --git a/sdk_nnbd/lib/io/io_resource_info.dart b/sdk_nnbd/lib/io/io_resource_info.dart
new file mode 100644
index 0000000..3e29221
--- /dev/null
+++ b/sdk_nnbd/lib/io/io_resource_info.dart
@@ -0,0 +1,282 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.io;
+
+abstract class _IOResourceInfo {
+  final String type;
+  final int id;
+  String get name;
+  static int _count = 0;
+
+  static final Stopwatch _sw = new Stopwatch()..start();
+  static final _startTime = new DateTime.now().millisecondsSinceEpoch;
+
+  static double get timestamp => _startTime + _sw.elapsedMicroseconds / 1000;
+
+  _IOResourceInfo(this.type) : id = _IOResourceInfo.getNextID();
+
+  /// Get the full set of values for a specific implementation. This is normally
+  /// looked up based on an id from a referenceValueMap.
+  Map<String, dynamic> get fullValueMap;
+
+  /// The reference map, used to return a list of values, e.g., getting
+  /// all open sockets. The structure of this is shared among all subclasses.
+  Map<String, dynamic> get referenceValueMap => {
+        // The type for a reference object is prefixed with @ in observatory.
+        'type': '@$type',
+        'id': id,
+        'name': name,
+      };
+
+  static int getNextID() => _count++;
+}
+
+abstract class _ReadWriteResourceInfo extends _IOResourceInfo {
+  int totalRead;
+  int totalWritten;
+  int readCount;
+  int writeCount;
+  double lastRead;
+  double lastWrite;
+
+  // Not all call sites use this. In some cases, e.g., a socket, a read does
+  // not always mean that we actually read some bytes (we may do a read to see
+  // if there are some bytes available).
+  void addRead(int bytes) {
+    totalRead += bytes;
+    readCount++;
+    lastRead = _IOResourceInfo.timestamp;
+  }
+
+  // In cases where we read but did not necessarily get any bytes, use this to
+  // update the readCount and timestamp. Manually update totalRead if any bytes
+  // where actually read.
+  void didRead() {
+    addRead(0);
+  }
+
+  void addWrite(int bytes) {
+    totalWritten += bytes;
+    writeCount++;
+    lastWrite = _IOResourceInfo.timestamp;
+  }
+
+  _ReadWriteResourceInfo(String type)
+      : totalRead = 0,
+        totalWritten = 0,
+        readCount = 0,
+        writeCount = 0,
+        lastRead = 0.0,
+        lastWrite = 0.0,
+        super(type);
+
+  Map<String, dynamic> get fullValueMap => {
+        'type': type,
+        'id': id,
+        'name': name,
+        'totalRead': totalRead,
+        'totalWritten': totalWritten,
+        'readCount': readCount,
+        'writeCount': writeCount,
+        'lastRead': lastRead,
+        'lastWrite': lastWrite
+      };
+}
+
+class _FileResourceInfo extends _ReadWriteResourceInfo {
+  static const String _type = '_file';
+
+  final file;
+
+  static Map<int, _FileResourceInfo> openFiles =
+      new Map<int, _FileResourceInfo>();
+
+  _FileResourceInfo(this.file) : super(_type) {
+    FileOpened(this);
+  }
+
+  static FileOpened(_FileResourceInfo info) {
+    assert(!openFiles.containsKey(info.id));
+    openFiles[info.id] = info;
+  }
+
+  static FileClosed(_FileResourceInfo info) {
+    assert(openFiles.containsKey(info.id));
+    openFiles.remove(info.id);
+  }
+
+  static Iterable<Map<String, dynamic>> getOpenFilesList() {
+    return new List.from(openFiles.values.map((e) => e.referenceValueMap));
+  }
+
+  static Future<ServiceExtensionResponse> getOpenFiles(function, params) {
+    assert(function == 'ext.dart.io.getOpenFiles');
+    var data = {'type': '_openfiles', 'data': getOpenFilesList()};
+    var jsonValue = json.encode(data);
+    return new Future.value(new ServiceExtensionResponse.result(jsonValue));
+  }
+
+  Map<String, dynamic> getFileInfoMap() {
+    return fullValueMap;
+  }
+
+  static Future<ServiceExtensionResponse> getFileInfoMapByID(function, params) {
+    assert(params.containsKey('id'));
+    var id = int.parse(params['id']);
+    var result =
+        openFiles.containsKey(id) ? openFiles[id].getFileInfoMap() : {};
+    var jsonValue = json.encode(result);
+    return new Future.value(new ServiceExtensionResponse.result(jsonValue));
+  }
+
+  String get name {
+    return '${file.path}';
+  }
+}
+
+class _ProcessResourceInfo extends _IOResourceInfo {
+  static const String _type = '_process';
+  final process;
+  final double startedAt;
+
+  static Map<int, _ProcessResourceInfo> startedProcesses =
+      new Map<int, _ProcessResourceInfo>();
+
+  _ProcessResourceInfo(this.process)
+      : startedAt = _IOResourceInfo.timestamp,
+        super(_type) {
+    ProcessStarted(this);
+  }
+
+  String get name => process._path;
+
+  void stopped() {
+    ProcessStopped(this);
+  }
+
+  Map<String, dynamic> get fullValueMap => {
+        'type': type,
+        'id': id,
+        'name': name,
+        'pid': process.pid,
+        'startedAt': startedAt,
+        'arguments': process._arguments,
+        'workingDirectory':
+            process._workingDirectory == null ? '.' : process._workingDirectory,
+      };
+
+  static ProcessStarted(_ProcessResourceInfo info) {
+    assert(!startedProcesses.containsKey(info.id));
+    startedProcesses[info.id] = info;
+  }
+
+  static ProcessStopped(_ProcessResourceInfo info) {
+    assert(startedProcesses.containsKey(info.id));
+    startedProcesses.remove(info.id);
+  }
+
+  static Iterable<Map<String, dynamic>> getStartedProcessesList() =>
+      new List.from(startedProcesses.values.map((e) => e.referenceValueMap));
+
+  static Future<ServiceExtensionResponse> getStartedProcesses(
+      String function, Map<String, String> params) {
+    assert(function == 'ext.dart.io.getProcesses');
+    var data = {'type': '_startedprocesses', 'data': getStartedProcessesList()};
+    var jsonValue = json.encode(data);
+    return new Future.value(new ServiceExtensionResponse.result(jsonValue));
+  }
+
+  static Future<ServiceExtensionResponse> getProcessInfoMapById(
+      String function, Map<String, String> params) {
+    var id = int.parse(params['id']);
+    var result = startedProcesses.containsKey(id)
+        ? startedProcesses[id].fullValueMap
+        : {};
+    var jsonValue = json.encode(result);
+    return new Future.value(new ServiceExtensionResponse.result(jsonValue));
+  }
+}
+
+class _SocketResourceInfo extends _ReadWriteResourceInfo {
+  static const String _tcpString = 'TCP';
+  static const String _udpString = 'UDP';
+  static const String _type = '_socket';
+
+  final /*_NativeSocket|*/ socket;
+
+  static Map<int, _SocketResourceInfo> openSockets =
+      new Map<int, _SocketResourceInfo>();
+
+  _SocketResourceInfo(this.socket) : super(_type) {
+    SocketOpened(this);
+  }
+
+  String get name {
+    if (socket.isListening) {
+      return 'listening:${socket.address.host}:${socket.port}';
+    }
+    var remote = '';
+    try {
+      var remoteHost = socket.remoteAddress.host;
+      var remotePort = socket.remotePort;
+      remote = ' -> $remoteHost:$remotePort';
+    } catch (e) {} // ignored if we can't get the information
+    return '${socket.address.host}:${socket.port}$remote';
+  }
+
+  static Iterable<Map<String, dynamic>> getOpenSocketsList() {
+    return new List.from(openSockets.values.map((e) => e.referenceValueMap));
+  }
+
+  Map<String, dynamic> getSocketInfoMap() {
+    var result = fullValueMap;
+    result['socketType'] = socket.isTcp ? _tcpString : _udpString;
+    result['listening'] = socket.isListening;
+    result['host'] = socket.address.host;
+    result['port'] = socket.port;
+    if (!socket.isListening) {
+      try {
+        result['remoteHost'] = socket.remoteAddress.host;
+        result['remotePort'] = socket.remotePort;
+      } catch (e) {
+        // UDP.
+        result['remotePort'] = 'NA';
+        result['remoteHost'] = 'NA';
+      }
+    } else {
+      result['remotePort'] = 'NA';
+      result['remoteHost'] = 'NA';
+    }
+    result['addressType'] = socket.address.type.name;
+    return result;
+  }
+
+  static Future<ServiceExtensionResponse> getSocketInfoMapByID(
+      String function, Map<String, String> params) {
+    assert(params.containsKey('id'));
+    var id = int.parse(params['id']);
+    var result =
+        openSockets.containsKey(id) ? openSockets[id].getSocketInfoMap() : {};
+    var jsonValue = json.encode(result);
+    return new Future.value(new ServiceExtensionResponse.result(jsonValue));
+  }
+
+  static Future<ServiceExtensionResponse> getOpenSockets(function, params) {
+    assert(function == 'ext.dart.io.getOpenSockets');
+    var data = {'type': '_opensockets', 'data': getOpenSocketsList()};
+    var jsonValue = json.encode(data);
+    return new Future.value(new ServiceExtensionResponse.result(jsonValue));
+  }
+
+  static SocketOpened(_SocketResourceInfo info) {
+    assert(!openSockets.containsKey(info.id));
+    openSockets[info.id] = info;
+  }
+
+  static SocketClosed(_SocketResourceInfo info) {
+    assert(openSockets.containsKey(info.id));
+    openSockets.remove(info.id);
+  }
+}
diff --git a/sdk_nnbd/lib/io/io_service.dart b/sdk_nnbd/lib/io/io_service.dart
new file mode 100644
index 0000000..7af382c
--- /dev/null
+++ b/sdk_nnbd/lib/io/io_service.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.
+
+part of dart.io;
+
+class _IOService {
+  // This list must be kept in sync with the list in runtime/bin/io_service.h
+  static const int fileExists = 0;
+  static const int fileCreate = 1;
+  static const int fileDelete = 2;
+  static const int fileRename = 3;
+  static const int fileCopy = 4;
+  static const int fileOpen = 5;
+  static const int fileResolveSymbolicLinks = 6;
+  static const int fileClose = 7;
+  static const int filePosition = 8;
+  static const int fileSetPosition = 9;
+  static const int fileTruncate = 10;
+  static const int fileLength = 11;
+  static const int fileLengthFromPath = 12;
+  static const int fileLastAccessed = 13;
+  static const int fileSetLastAccessed = 14;
+  static const int fileLastModified = 15;
+  static const int fileSetLastModified = 16;
+  static const int fileFlush = 17;
+  static const int fileReadByte = 18;
+  static const int fileWriteByte = 19;
+  static const int fileRead = 20;
+  static const int fileReadInto = 21;
+  static const int fileWriteFrom = 22;
+  static const int fileCreateLink = 23;
+  static const int fileDeleteLink = 24;
+  static const int fileRenameLink = 25;
+  static const int fileLinkTarget = 26;
+  static const int fileType = 27;
+  static const int fileIdentical = 28;
+  static const int fileStat = 29;
+  static const int fileLock = 30;
+  static const int socketLookup = 31;
+  static const int socketListInterfaces = 32;
+  static const int socketReverseLookup = 33;
+  static const int directoryCreate = 34;
+  static const int directoryDelete = 35;
+  static const int directoryExists = 36;
+  static const int directoryCreateTemp = 37;
+  static const int directoryListStart = 38;
+  static const int directoryListNext = 39;
+  static const int directoryListStop = 40;
+  static const int directoryRename = 41;
+  static const int sslProcessFilter = 42;
+
+  external static Future _dispatch(int request, List data);
+}
diff --git a/sdk_nnbd/lib/io/io_sink.dart b/sdk_nnbd/lib/io/io_sink.dart
new file mode 100644
index 0000000..5481265
--- /dev/null
+++ b/sdk_nnbd/lib/io/io_sink.dart
@@ -0,0 +1,316 @@
+// 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 dart.io;
+
+/**
+ * A combined byte and text output.
+ *
+ * An [IOSink] combines a [StreamSink] of bytes with a [StringSink],
+ * and allows easy output of both bytes and text.
+ *
+ * Writing text ([write]) and adding bytes ([add]) may be interleaved freely.
+ *
+ * While a stream is being added using [addStream], any further attempts
+ * to add or write to the [IOSink] will fail until the [addStream] completes.
+ *
+ * It is an error to add data to the [IOSink] after the sink is closed.
+ */
+abstract class IOSink implements StreamSink<List<int>>, StringSink {
+  /**
+   * Create an [IOSink] that outputs to a [target] [StreamConsumer] of bytes.
+   *
+   * Text written to [StreamSink] methods is encoded to bytes using [encoding]
+   * before being output on [target].
+   */
+  factory IOSink(StreamConsumer<List<int>> target, {Encoding encoding: utf8}) =>
+      new _IOSinkImpl(target, encoding);
+
+  /**
+   * The [Encoding] used when writing strings. Depending on the
+   * underlying consumer this property might be mutable.
+   */
+  Encoding encoding;
+
+  /**
+   * Adds byte [data] to the target consumer, ignoring [encoding].
+   *
+   * The [encoding] does not apply to this method, and the `data` list is passed
+   * directly to the target consumer as a stream event.
+   *
+   * This function must not be called when a stream is currently being added
+   * using [addStream].
+   *
+   * This operation is non-blocking. See [flush] or [done] for how to get any
+   * errors generated by this call.
+   *
+   * The data list should not be modified after it has been passed to `add`.
+   */
+  void add(List<int> data);
+
+  /**
+   * Converts [obj] to a String by invoking [Object.toString] and
+   * [add]s the encoding of the result to the target consumer.
+   *
+   * This operation is non-blocking. See [flush] or [done] for how to get any
+   * errors generated by this call.
+   */
+  void write(Object obj);
+
+  /**
+   * Iterates over the given [objects] and [write]s them in sequence.
+   *
+   * If [separator] is provided, a `write` with the `separator` is performed
+   * between any two elements of objects`.
+   *
+   * This operation is non-blocking. See [flush] or [done] for how to get any
+   * errors generated by this call.
+   */
+  void writeAll(Iterable objects, [String separator = ""]);
+
+  /**
+   * Converts [obj] to a String by invoking [Object.toString] and
+   * writes the result to `this`, followed by a newline.
+   *
+   * This operation is non-blocking. See [flush] or [done] for how to get any
+   * errors generated by this call.
+   */
+  void writeln([Object obj = ""]);
+
+  /**
+   * Writes the character of [charCode].
+   *
+   * This method is equivalent to `write(new String.fromCharCode(charCode))`.
+   *
+   * This operation is non-blocking. See [flush] or [done] for how to get any
+   * errors generated by this call.
+   */
+  void writeCharCode(int charCode);
+
+  /**
+   * Passes the error to the target consumer as an error event.
+   *
+   * This function must not be called when a stream is currently being added
+   * using [addStream].
+   *
+   * This operation is non-blocking. See [flush] or [done] for how to get any
+   * errors generated by this call.
+   */
+  void addError(error, [StackTrace stackTrace]);
+
+  /**
+   * Adds all elements of the given [stream] to `this`.
+   *
+   * Returns a [Future] that completes when
+   * all elements of the given [stream] are added to `this`.
+   *
+   * This function must not be called when a stream is currently being added
+   * using this function.
+   */
+  Future addStream(Stream<List<int>> stream);
+
+  /**
+   * Returns a [Future] that completes once all buffered data is accepted by the
+   * underlying [StreamConsumer].
+   *
+   * This method must not be called while an [addStream] is incomplete.
+   *
+   * NOTE: This is not necessarily the same as the data being flushed by the
+   * operating system.
+   */
+  Future flush();
+
+  /**
+   * Close the target consumer.
+   *
+   * NOTE: Writes to the [IOSink] may be buffered, and may not be flushed by
+   * a call to `close()`. To flush all buffered writes, call `flush()` before
+   * calling `close()`.
+   */
+  Future close();
+
+  /**
+   * Get a future that will complete when the consumer closes, or when an
+   * error occurs. This future is identical to the future returned by
+   * [close].
+   */
+  Future get done;
+}
+
+class _StreamSinkImpl<T> implements StreamSink<T> {
+  final StreamConsumer<T> _target;
+  final Completer _doneCompleter = new Completer();
+  StreamController<T> _controllerInstance;
+  Completer _controllerCompleter;
+  bool _isClosed = false;
+  bool _isBound = false;
+  bool _hasError = false;
+
+  _StreamSinkImpl(this._target);
+
+  void add(T data) {
+    if (_isClosed) {
+      throw StateError("StreamSink is closed");
+    }
+    _controller.add(data);
+  }
+
+  void addError(error, [StackTrace stackTrace]) {
+    if (_isClosed) {
+      throw StateError("StreamSink is closed");
+    }
+    _controller.addError(error, stackTrace);
+  }
+
+  Future addStream(Stream<T> stream) {
+    if (_isBound) {
+      throw new StateError("StreamSink is already bound to a stream");
+    }
+    if (_hasError) return done;
+
+    _isBound = true;
+    var future = _controllerCompleter == null
+        ? _target.addStream(stream)
+        : _controllerCompleter.future.then((_) => _target.addStream(stream));
+    _controllerInstance?.close();
+
+    // Wait for any pending events in [_controller] to be dispatched before
+    // adding [stream].
+    return future.whenComplete(() {
+      _isBound = false;
+    });
+  }
+
+  Future flush() {
+    if (_isBound) {
+      throw new StateError("StreamSink is bound to a stream");
+    }
+    if (_controllerInstance == null) return new Future.value(this);
+    // Adding an empty stream-controller will return a future that will complete
+    // when all data is done.
+    _isBound = true;
+    var future = _controllerCompleter.future;
+    _controllerInstance.close();
+    return future.whenComplete(() {
+      _isBound = false;
+    });
+  }
+
+  Future close() {
+    if (_isBound) {
+      throw new StateError("StreamSink is bound to a stream");
+    }
+    if (!_isClosed) {
+      _isClosed = true;
+      if (_controllerInstance != null) {
+        _controllerInstance.close();
+      } else {
+        _closeTarget();
+      }
+    }
+    return done;
+  }
+
+  void _closeTarget() {
+    _target.close().then(_completeDoneValue, onError: _completeDoneError);
+  }
+
+  Future get done => _doneCompleter.future;
+
+  void _completeDoneValue(value) {
+    if (!_doneCompleter.isCompleted) {
+      _doneCompleter.complete(value);
+    }
+  }
+
+  void _completeDoneError(error, StackTrace stackTrace) {
+    if (!_doneCompleter.isCompleted) {
+      _hasError = true;
+      _doneCompleter.completeError(error, stackTrace);
+    }
+  }
+
+  StreamController<T> get _controller {
+    if (_isBound) {
+      throw new StateError("StreamSink is bound to a stream");
+    }
+    if (_isClosed) {
+      throw new StateError("StreamSink is closed");
+    }
+    if (_controllerInstance == null) {
+      _controllerInstance = new StreamController<T>(sync: true);
+      _controllerCompleter = new Completer();
+      _target.addStream(_controller.stream).then((_) {
+        if (_isBound) {
+          // A new stream takes over - forward values to that stream.
+          _controllerCompleter.complete(this);
+          _controllerCompleter = null;
+          _controllerInstance = null;
+        } else {
+          // No new stream, .close was called. Close _target.
+          _closeTarget();
+        }
+      }, onError: (error, stackTrace) {
+        if (_isBound) {
+          // A new stream takes over - forward errors to that stream.
+          _controllerCompleter.completeError(error, stackTrace);
+          _controllerCompleter = null;
+          _controllerInstance = null;
+        } else {
+          // No new stream. No need to close target, as it has already
+          // failed.
+          _completeDoneError(error, stackTrace);
+        }
+      });
+    }
+    return _controllerInstance;
+  }
+}
+
+class _IOSinkImpl extends _StreamSinkImpl<List<int>> implements IOSink {
+  Encoding _encoding;
+  bool _encodingMutable = true;
+
+  _IOSinkImpl(StreamConsumer<List<int>> target, this._encoding) : super(target);
+
+  Encoding get encoding => _encoding;
+
+  void set encoding(Encoding value) {
+    if (!_encodingMutable) {
+      throw new StateError("IOSink encoding is not mutable");
+    }
+    _encoding = value;
+  }
+
+  void write(Object obj) {
+    String string = '$obj';
+    if (string.isEmpty) return;
+    add(_encoding.encode(string));
+  }
+
+  void writeAll(Iterable objects, [String separator = ""]) {
+    Iterator iterator = objects.iterator;
+    if (!iterator.moveNext()) return;
+    if (separator.isEmpty) {
+      do {
+        write(iterator.current);
+      } while (iterator.moveNext());
+    } else {
+      write(iterator.current);
+      while (iterator.moveNext()) {
+        write(separator);
+        write(iterator.current);
+      }
+    }
+  }
+
+  void writeln([Object object = ""]) {
+    write(object);
+    write("\n");
+  }
+
+  void writeCharCode(int charCode) {
+    write(new String.fromCharCode(charCode));
+  }
+}
diff --git a/sdk_nnbd/lib/io/io_sources.gni b/sdk_nnbd/lib/io/io_sources.gni
new file mode 100644
index 0000000..51e283a
--- /dev/null
+++ b/sdk_nnbd/lib/io/io_sources.gni
@@ -0,0 +1,36 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+io_sdk_sources = [
+  "io.dart",
+
+  # The above file needs to be first if additional parts are added to the lib.
+  "bytes_builder.dart",
+  "common.dart",
+  "data_transformer.dart",
+  "directory.dart",
+  "directory_impl.dart",
+  "embedder_config.dart",
+  "eventhandler.dart",
+  "file.dart",
+  "file_impl.dart",
+  "file_system_entity.dart",
+  "io_resource_info.dart",
+  "io_sink.dart",
+  "io_service.dart",
+  "link.dart",
+  "namespace_impl.dart",
+  "overrides.dart",
+  "platform.dart",
+  "platform_impl.dart",
+  "process.dart",
+  "service_object.dart",
+  "secure_server_socket.dart",
+  "secure_socket.dart",
+  "security_context.dart",
+  "socket.dart",
+  "stdio.dart",
+  "string_transformer.dart",
+  "sync_socket.dart",
+]
diff --git a/sdk_nnbd/lib/io/link.dart b/sdk_nnbd/lib/io/link.dart
new file mode 100644
index 0000000..79f8656
--- /dev/null
+++ b/sdk_nnbd/lib/io/link.dart
@@ -0,0 +1,300 @@
+// 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 dart.io;
+
+/**
+ * [Link] objects are references to filesystem links.
+ *
+ */
+@pragma("vm:entry-point")
+abstract class Link implements FileSystemEntity {
+  /**
+   * Creates a Link object.
+   */
+  @pragma("vm:entry-point")
+  factory Link(String path) {
+    final IOOverrides overrides = IOOverrides.current;
+    if (overrides == null) {
+      return new _Link(path);
+    }
+    return overrides.createLink(path);
+  }
+
+  @pragma("vm:entry-point")
+  factory Link.fromRawPath(Uint8List rawPath) {
+    // TODO(bkonyi): handle overrides
+    return new _Link.fromRawPath(rawPath);
+  }
+
+  /**
+   * Creates a [Link] object.
+   *
+   * If [path] is a relative path, it will be interpreted relative to the
+   * current working directory (see [Directory.current]), when used.
+   *
+   * If [path] is an absolute path, it will be immune to changes to the
+   * current working directory.
+   */
+  factory Link.fromUri(Uri uri) => new Link(uri.toFilePath());
+
+  /**
+   * Creates a symbolic link. Returns a [:Future<Link>:] that completes with
+   * the link when it has been created. If the link exists,
+   * the future will complete with an error.
+   *
+   * If [recursive] is false, the default, the link is created
+   * only if all directories in its path exist.
+   * If [recursive] is true, all non-existing path
+   * components are created. The directories in the path of [target] are
+   * not affected, unless they are also in [path].
+   *
+   * On the Windows platform, this call will create a true symbolic link
+   * instead of a Junction. In order to create a symbolic link on Windows, Dart
+   * must be run in Administrator mode or the system must have Developer Mode
+   * enabled, otherwise a [FileSystemException] will be raised with 
+   * `ERROR_PRIVILEGE_NOT_HELD` set as the errno when this call is made.
+   *
+   * On other platforms, the posix symlink() call is used to make a symbolic
+   * link containing the string [target].  If [target] is a relative path,
+   * it will be interpreted relative to the directory containing the link.
+   */
+  Future<Link> create(String target, {bool recursive: false});
+
+  /**
+   * Synchronously create the link. Calling [createSync] on an existing link
+   * will throw an exception.
+   *
+   * If [recursive] is false, the default, the link is created only if all
+   * directories in its path exist. If [recursive] is true, all
+   * non-existing path components are created. The directories in
+   * the path of [target] are not affected, unless they are also in [path].
+   *
+   * On the Windows platform, this call will create a true symbolic link
+   * instead of a Junction. In order to create a symbolic link on Windows, Dart
+   * must be run in Administrator mode or the system must have Developer Mode
+   * enabled, otherwise a [FileSystemException] will be raised with 
+   * `ERROR_PRIVILEGE_NOT_HELD` set as the errno when this call is made.
+   *
+   * On other platforms, the posix symlink() call is used to make a symbolic
+   * link containing the string [target].  If [target] is a relative path,
+   * it will be interpreted relative to the directory containing the link.
+   */
+  void createSync(String target, {bool recursive: false});
+
+  /**
+   * Synchronously updates the link. Calling [updateSync] on a non-existing link
+   * will throw an exception.
+   */
+  void updateSync(String target);
+
+  /**
+   * Updates the link. Returns a [:Future<Link>:] that completes with the
+   * link when it has been updated.  Calling [update] on a non-existing link
+   * will complete its returned future with an exception.
+   */
+  Future<Link> update(String target);
+
+  Future<String> resolveSymbolicLinks();
+
+  String resolveSymbolicLinksSync();
+
+  /**
+   * Renames this link. Returns a `Future<Link>` that completes
+   * with a [Link] instance for the renamed link.
+   *
+   * If [newPath] identifies an existing link, that link is
+   * replaced. If [newPath] identifies an existing file or directory,
+   * the operation fails and the future completes with an exception.
+   */
+  Future<Link> rename(String newPath);
+
+  /**
+   * Synchronously renames this link. Returns a [Link]
+   * instance for the renamed link.
+   *
+   * If [newPath] identifies an existing link, that link is
+   * replaced. If [newPath] identifies an existing file or directory
+   * the operation fails and an exception is thrown.
+   */
+  Link renameSync(String newPath);
+
+  /**
+   * Returns a [Link] instance whose path is the absolute path to [this].
+   *
+   * The absolute path is computed by prefixing
+   * a relative path with the current working directory, and returning
+   * an absolute path unchanged.
+   */
+  Link get absolute;
+
+  /**
+   * Gets the target of the link. Returns a future that completes with
+   * the path to the target.
+   *
+   * If the returned target is a relative path, it is relative to the
+   * directory containing the link.
+   *
+   * If the link does not exist, or is not a link, the future completes with
+   * a FileSystemException.
+   */
+  Future<String> target();
+
+  /**
+   * Synchronously gets the target of the link. Returns the path to the target.
+   *
+   * If the returned target is a relative path, it is relative to the
+   * directory containing the link.
+   *
+   * If the link does not exist, or is not a link, throws a FileSystemException.
+   */
+  String targetSync();
+}
+
+class _Link extends FileSystemEntity implements Link {
+  String _path;
+  Uint8List _rawPath;
+
+  _Link(String path) {
+    ArgumentError.checkNotNull(path, 'path');
+    _path = path;
+    _rawPath = FileSystemEntity._toUtf8Array(path);
+  }
+
+  _Link.fromRawPath(Uint8List rawPath) {
+    _rawPath = FileSystemEntity._toNullTerminatedUtf8Array(rawPath);
+    _path = FileSystemEntity._toStringFromUtf8Array(rawPath);
+  }
+
+  String get path => _path;
+
+  String toString() => "Link: '$path'";
+
+  Future<bool> exists() => FileSystemEntity._isLinkRaw(_rawPath);
+
+  bool existsSync() => FileSystemEntity._isLinkRawSync(_rawPath);
+
+  Link get absolute => new Link.fromRawPath(_rawAbsolutePath);
+
+  Future<Link> create(String target, {bool recursive: false}) {
+    var result =
+        recursive ? parent.create(recursive: true) : new Future.value(null);
+    return result
+        .then((_) => _File._dispatchWithNamespace(
+            _IOService.fileCreateLink, [null, _rawPath, target]))
+        .then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(
+            response, "Cannot create link to target '$target'", path);
+      }
+      return this;
+    });
+  }
+
+  void createSync(String target, {bool recursive: false}) {
+    if (recursive) {
+      parent.createSync(recursive: true);
+    }
+    var result = _File._createLink(_Namespace._namespace, _rawPath, target);
+    throwIfError(result, "Cannot create link", path);
+  }
+
+  void updateSync(String target) {
+    // TODO(12414): Replace with atomic update, where supported by platform.
+    // Atomically changing a link can be done by creating the new link, with
+    // a different name, and using the rename() posix call to move it to
+    // the old name atomically.
+    deleteSync();
+    createSync(target);
+  }
+
+  Future<Link> update(String target) {
+    // TODO(12414): Replace with atomic update, where supported by platform.
+    // Atomically changing a link can be done by creating the new link, with
+    // a different name, and using the rename() posix call to move it to
+    // the old name atomically.
+    return delete().then<Link>((_) => create(target));
+  }
+
+  Future<Link> _delete({bool recursive: false}) {
+    if (recursive) {
+      return new Directory.fromRawPath(_rawPath)
+          .delete(recursive: true)
+          .then((_) => this);
+    }
+    return _File._dispatchWithNamespace(
+        _IOService.fileDeleteLink, [null, _rawPath]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response, "Cannot delete link", path);
+      }
+      return this;
+    });
+  }
+
+  void _deleteSync({bool recursive: false}) {
+    if (recursive) {
+      return new Directory.fromRawPath(_rawPath).deleteSync(recursive: true);
+    }
+    var result = _File._deleteLinkNative(_Namespace._namespace, _rawPath);
+    throwIfError(result, "Cannot delete link", path);
+  }
+
+  Future<Link> rename(String newPath) {
+    return _File._dispatchWithNamespace(
+        _IOService.fileRenameLink, [null, _rawPath, newPath]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(
+            response, "Cannot rename link to '$newPath'", path);
+      }
+      return new Link(newPath);
+    });
+  }
+
+  Link renameSync(String newPath) {
+    var result = _File._renameLink(_Namespace._namespace, _rawPath, newPath);
+    throwIfError(result, "Cannot rename link '$path' to '$newPath'");
+    return new Link(newPath);
+  }
+
+  Future<String> target() {
+    return _File._dispatchWithNamespace(
+        _IOService.fileLinkTarget, [null, _rawPath]).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(
+            response, "Cannot get target of link", path);
+      }
+      return response;
+    });
+  }
+
+  String targetSync() {
+    var result = _File._linkTarget(_Namespace._namespace, _rawPath);
+    throwIfError(result, "Cannot read link", path);
+    return result;
+  }
+
+  static throwIfError(Object result, String msg, [String path = ""]) {
+    if (result is OSError) {
+      throw new FileSystemException(msg, path, result);
+    }
+  }
+
+  bool _isErrorResponse(response) {
+    return response is List && response[0] != _successResponse;
+  }
+
+  _exceptionFromResponse(response, String message, String path) {
+    assert(_isErrorResponse(response));
+    switch (response[_errorResponseErrorType]) {
+      case _illegalArgumentResponse:
+        return new ArgumentError();
+      case _osErrorResponse:
+        var err = new OSError(response[_osErrorResponseMessage],
+            response[_osErrorResponseErrorCode]);
+        return new FileSystemException(message, path, err);
+      default:
+        return new Exception("Unknown error");
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/io/namespace_impl.dart b/sdk_nnbd/lib/io/namespace_impl.dart
new file mode 100644
index 0000000..88987b6
--- /dev/null
+++ b/sdk_nnbd/lib/io/namespace_impl.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.io;
+
+// Each Isolate may run in a different "namespace", which provides the scope in
+// which file paths are resolved.
+abstract class _Namespace {
+  // This getter does not increase the reference count on the underlying native
+  // object. It cannot be passed in a dispatch message to the IOService thread.
+  external static _Namespace get _namespace;
+
+  // This getter does increase the reference count on the underlying native
+  // object. It must be passed in a dispatch message to the IOService thread.
+  external static int get _namespacePointer;
+
+  // This sets up the Isolate's namespace. It should be set up by the embedder.
+  // If it is not set up by the embedder, relative paths will be resolved
+  // relative to the process's current working directory and absolute paths will
+  // be left relative to the file system root.
+  @pragma("vm:entry-point")
+  external static void _setupNamespace(var namespace);
+}
diff --git a/sdk_nnbd/lib/io/overrides.dart b/sdk_nnbd/lib/io/overrides.dart
new file mode 100644
index 0000000..1a71881
--- /dev/null
+++ b/sdk_nnbd/lib/io/overrides.dart
@@ -0,0 +1,481 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.io;
+
+final _ioOverridesToken = new Object();
+
+const _asyncRunZoned = runZoned;
+
+/// This class facilitates overriding various APIs of dart:io with mock
+/// implementations.
+///
+/// This abstract base class should be extended with overrides for the
+/// operations needed to construct mocks. The implementations in this base class
+/// default to the actual dart:io implementation. For example:
+///
+/// ```
+/// class MyDirectory implements Directory {
+///   ...
+///   // An implementation of the Directory interface
+///   ...
+/// }
+///
+/// main() {
+///   IOOverrides.runZoned(() {
+///     ...
+///     // Operations will use MyDirectory instead of dart:io's Directory
+///     // implementation whenever Directory is used.
+///     ...
+///   }, createDirectory: (String path) => new MyDirectory(path));
+/// }
+/// ```
+abstract class IOOverrides {
+  static IOOverrides _global;
+
+  static IOOverrides get current {
+    return Zone.current[_ioOverridesToken] ?? _global;
+  }
+
+  /// The [IOOverrides] to use in the root [Zone].
+  ///
+  /// These are the [IOOverrides] that will be used in the root Zone, and in
+  /// Zone's that do not set [IOOverrides] and whose ancestors up to the root
+  /// Zone do not set [IOOverrides].
+  static set global(IOOverrides overrides) {
+    _global = overrides;
+  }
+
+  /// Runs [body] in a fresh [Zone] using the provided overrides.
+  ///
+  /// See the documentation on the corresponding methods of IOOverrides for
+  /// information about what the optional arguments do.
+  static R runZoned<R>(R body(),
+      {
+      // Directory
+      Directory Function(String) createDirectory,
+      Directory Function() getCurrentDirectory,
+      void Function(String) setCurrentDirectory,
+      Directory Function() getSystemTempDirectory,
+
+      // File
+      File Function(String) createFile,
+
+      // FileStat
+      Future<FileStat> Function(String) stat,
+      FileStat Function(String) statSync,
+
+      // FileSystemEntity
+      Future<bool> Function(String, String) fseIdentical,
+      bool Function(String, String) fseIdenticalSync,
+      Future<FileSystemEntityType> Function(String, bool) fseGetType,
+      FileSystemEntityType Function(String, bool) fseGetTypeSync,
+
+      // _FileSystemWatcher
+      Stream<FileSystemEvent> Function(String, int, bool) fsWatch,
+      bool Function() fsWatchIsSupported,
+
+      // Link
+      Link Function(String) createLink,
+
+      // Socket
+      Future<Socket> Function(dynamic, int,
+              {dynamic sourceAddress, Duration timeout})
+          socketConnect,
+      Future<ConnectionTask<Socket>> Function(dynamic, int,
+              {dynamic sourceAddress})
+          socketStartConnect,
+
+      // Optional Zone parameters
+      ZoneSpecification zoneSpecification,
+      Function onError}) {
+    IOOverrides overrides = new _IOOverridesScope(
+      // Directory
+      createDirectory,
+      getCurrentDirectory,
+      setCurrentDirectory,
+      getSystemTempDirectory,
+
+      // File
+      createFile,
+
+      // FileStat
+      stat,
+      statSync,
+
+      // FileSystemEntity
+      fseIdentical,
+      fseIdenticalSync,
+      fseGetType,
+      fseGetTypeSync,
+
+      // _FileSystemWatcher
+      fsWatch,
+      fsWatchIsSupported,
+
+      // Link
+      createLink,
+
+      // Socket
+      socketConnect,
+      socketStartConnect,
+    );
+    return _asyncRunZoned<R>(body,
+        zoneValues: {_ioOverridesToken: overrides},
+        zoneSpecification: zoneSpecification,
+        onError: onError);
+  }
+
+  /// Runs [body] in a fresh [Zone] using the overrides found in [overrides].
+  ///
+  /// Note that [overrides] should be an instance of a class that extends
+  /// [IOOverrides].
+  static R runWithIOOverrides<R>(R body(), IOOverrides overrides,
+      {ZoneSpecification zoneSpecification, Function onError}) {
+    return _asyncRunZoned<R>(body,
+        zoneValues: {_ioOverridesToken: overrides},
+        zoneSpecification: zoneSpecification,
+        onError: onError);
+  }
+
+  // Directory
+
+  /// Creates a new [Directory] object for the given [path].
+  ///
+  /// When this override is installed, this function overrides the behavior of
+  /// `new Directory()` and `new Directory.fromUri()`.
+  Directory createDirectory(String path) => new _Directory(path);
+
+  /// Returns the current working directory.
+  ///
+  /// When this override is installed, this function overrides the behavior of
+  /// the static getter `Directory.current`
+  Directory getCurrentDirectory() => _Directory.current;
+
+  /// Sets the current working directory to be [path].
+  ///
+  /// When this override is installed, this function overrides the behavior of
+  /// the setter `Directory.current`.
+  void setCurrentDirectory(String path) {
+    _Directory.current = path;
+  }
+
+  /// Returns the system temporary directory.
+  ///
+  /// When this override is installed, this function overrides the behavior of
+  /// `Directory.systemTemp`.
+  Directory getSystemTempDirectory() => _Directory.systemTemp;
+
+  // File
+
+  /// Creates a new [File] object for the given [path].
+  ///
+  /// When this override is installed, this function overrides the behavior of
+  /// `new File()` and `new File.fromUri()`.
+  File createFile(String path) => new _File(path);
+
+  // FileStat
+
+  /// Asynchronously returns [FileStat] information for [path].
+  ///
+  /// When this override is installed, this function overrides the behavior of
+  /// `FileStat.stat()`.
+  Future<FileStat> stat(String path) {
+    return FileStat._stat(path);
+  }
+
+  /// Returns [FileStat] information for [path].
+  ///
+  /// When this override is installed, this function overrides the behavior of
+  /// `FileStat.statSync()`.
+  FileStat statSync(String path) {
+    return FileStat._statSyncInternal(path);
+  }
+
+  // FileSystemEntity
+
+  /// Asynchronously returns `true` if [path1] and [path2] are paths to the
+  /// same file system object.
+  ///
+  /// When this override is installed, this function overrides the behavior of
+  /// `FileSystemEntity.identical`.
+  Future<bool> fseIdentical(String path1, String path2) {
+    return FileSystemEntity._identical(path1, path2);
+  }
+
+  /// Returns `true` if [path1] and [path2] are paths to the
+  /// same file system object.
+  ///
+  /// When this override is installed, this function overrides the behavior of
+  /// `FileSystemEntity.identicalSync`.
+  bool fseIdenticalSync(String path1, String path2) {
+    return FileSystemEntity._identicalSync(path1, path2);
+  }
+
+  /// Asynchronously returns the [FileSystemEntityType] for [path].
+  ///
+  /// When this override is installed, this function overrides the behavior of
+  /// `FileSystemEntity.type`.
+  Future<FileSystemEntityType> fseGetType(String path, bool followLinks) {
+    return FileSystemEntity._getTypeRequest(utf8.encode(path), followLinks);
+  }
+
+  /// Returns the [FileSystemEntityType] for [path].
+  ///
+  /// When this override is installed, this function overrides the behavior of
+  /// `FileSystemEntity.typeSync`.
+  FileSystemEntityType fseGetTypeSync(String path, bool followLinks) {
+    return FileSystemEntity._getTypeSyncHelper(utf8.encode(path), followLinks);
+  }
+
+  // _FileSystemWatcher
+
+  /// Returns a [Stream] of [FileSystemEvent]s.
+  ///
+  /// When this override is installed, this function overrides the behavior of
+  /// `FileSystemEntity.watch()`.
+  Stream<FileSystemEvent> fsWatch(String path, int events, bool recursive) {
+    return _FileSystemWatcher._watch(path, events, recursive);
+  }
+
+  /// Returns `true` when [FileSystemEntity.watch] is supported.
+  ///
+  /// When this override is installed, this function overrides the behavior of
+  /// `FileSystemEntity.isWatchSupported`.
+  bool fsWatchIsSupported() => _FileSystemWatcher.isSupported;
+
+  // Link
+
+  /// Returns a new [Link] object for the given [path].
+  ///
+  /// When this override is installed, this function overrides the behavior of
+  /// `new Link()` and `new Link.fromUri()`.
+  Link createLink(String path) => new _Link(path);
+
+  // Socket
+
+  /// Asynchronously returns a [Socket] connected to the given host and port.
+  ///
+  /// When this override is installed, this functions overrides the behavior of
+  /// `Socket.connect(...)`.
+  Future<Socket> socketConnect(host, int port,
+      {sourceAddress, Duration timeout}) {
+    return Socket._connect(host, port,
+        sourceAddress: sourceAddress, timeout: timeout);
+  }
+
+  /// Asynchronously returns a [ConnectionTask] that connects to the given host
+  /// and port when successful.
+  ///
+  /// When this override is installed, this functions overrides the behavior of
+  /// `Socket.startConnect(...)`.
+  Future<ConnectionTask<Socket>> socketStartConnect(host, int port,
+      {sourceAddress}) {
+    return Socket._startConnect(host, port, sourceAddress: sourceAddress);
+  }
+}
+
+class _IOOverridesScope extends IOOverrides {
+  final IOOverrides _previous = IOOverrides.current;
+
+  // Directory
+  Directory Function(String) _createDirectory;
+  Directory Function() _getCurrentDirectory;
+  void Function(String) _setCurrentDirectory;
+  Directory Function() _getSystemTempDirectory;
+
+  // File
+  File Function(String) _createFile;
+
+  // FileStat
+  Future<FileStat> Function(String) _stat;
+  FileStat Function(String) _statSync;
+
+  // FileSystemEntity
+  Future<bool> Function(String, String) _fseIdentical;
+  bool Function(String, String) _fseIdenticalSync;
+  Future<FileSystemEntityType> Function(String, bool) _fseGetType;
+  FileSystemEntityType Function(String, bool) _fseGetTypeSync;
+
+  // _FileSystemWatcher
+  Stream<FileSystemEvent> Function(String, int, bool) _fsWatch;
+  bool Function() _fsWatchIsSupported;
+
+  // Link
+  Link Function(String) _createLink;
+
+  // Socket
+  Future<Socket> Function(dynamic, int,
+      {dynamic sourceAddress, Duration timeout}) _socketConnect;
+  Future<ConnectionTask<Socket>> Function(dynamic, int, {dynamic sourceAddress})
+      _socketStartConnect;
+
+  _IOOverridesScope(
+    // Directory
+    this._createDirectory,
+    this._getCurrentDirectory,
+    this._setCurrentDirectory,
+    this._getSystemTempDirectory,
+
+    // File
+    this._createFile,
+
+    // FileStat
+    this._stat,
+    this._statSync,
+
+    // FileSystemEntity
+    this._fseIdentical,
+    this._fseIdenticalSync,
+    this._fseGetType,
+    this._fseGetTypeSync,
+
+    // _FileSystemWatcher
+    this._fsWatch,
+    this._fsWatchIsSupported,
+
+    // Link
+    this._createLink,
+
+    // Socket
+    this._socketConnect,
+    this._socketStartConnect,
+  );
+
+  // Directory
+  @override
+  Directory createDirectory(String path) {
+    if (_createDirectory != null) return _createDirectory(path);
+    if (_previous != null) return _previous.createDirectory(path);
+    return super.createDirectory(path);
+  }
+
+  @override
+  Directory getCurrentDirectory() {
+    if (_getCurrentDirectory != null) return _getCurrentDirectory();
+    if (_previous != null) return _previous.getCurrentDirectory();
+    return super.getCurrentDirectory();
+  }
+
+  @override
+  void setCurrentDirectory(String path) {
+    if (_setCurrentDirectory != null)
+      _setCurrentDirectory(path);
+    else if (_previous != null)
+      _previous.setCurrentDirectory(path);
+    else
+      super.setCurrentDirectory(path);
+  }
+
+  @override
+  Directory getSystemTempDirectory() {
+    if (_getSystemTempDirectory != null) return _getSystemTempDirectory();
+    if (_previous != null) return _previous.getSystemTempDirectory();
+    return super.getSystemTempDirectory();
+  }
+
+  // File
+  @override
+  File createFile(String path) {
+    if (_createFile != null) return _createFile(path);
+    if (_previous != null) return _previous.createFile(path);
+    return super.createFile(path);
+  }
+
+  // FileStat
+  @override
+  Future<FileStat> stat(String path) {
+    if (_stat != null) return _stat(path);
+    if (_previous != null) return _previous.stat(path);
+    return super.stat(path);
+  }
+
+  @override
+  FileStat statSync(String path) {
+    if (_stat != null) return _statSync(path);
+    if (_previous != null) return _previous.statSync(path);
+    return super.statSync(path);
+  }
+
+  // FileSystemEntity
+  @override
+  Future<bool> fseIdentical(String path1, String path2) {
+    if (_fseIdentical != null) return _fseIdentical(path1, path2);
+    if (_previous != null) return _previous.fseIdentical(path1, path2);
+    return super.fseIdentical(path1, path2);
+  }
+
+  @override
+  bool fseIdenticalSync(String path1, String path2) {
+    if (_fseIdenticalSync != null) return _fseIdenticalSync(path1, path2);
+    if (_previous != null) return _previous.fseIdenticalSync(path1, path2);
+    return super.fseIdenticalSync(path1, path2);
+  }
+
+  @override
+  Future<FileSystemEntityType> fseGetType(String path, bool followLinks) {
+    if (_fseGetType != null) return _fseGetType(path, followLinks);
+    if (_previous != null) return _previous.fseGetType(path, followLinks);
+    return super.fseGetType(path, followLinks);
+  }
+
+  @override
+  FileSystemEntityType fseGetTypeSync(String path, bool followLinks) {
+    if (_fseGetTypeSync != null) return _fseGetTypeSync(path, followLinks);
+    if (_previous != null) return _previous.fseGetTypeSync(path, followLinks);
+    return super.fseGetTypeSync(path, followLinks);
+  }
+
+  // _FileSystemWatcher
+  @override
+  Stream<FileSystemEvent> fsWatch(String path, int events, bool recursive) {
+    if (_fsWatch != null) return _fsWatch(path, events, recursive);
+    if (_previous != null) return _previous.fsWatch(path, events, recursive);
+    return super.fsWatch(path, events, recursive);
+  }
+
+  @override
+  bool fsWatchIsSupported() {
+    if (_fsWatchIsSupported != null) return _fsWatchIsSupported();
+    if (_previous != null) return _previous.fsWatchIsSupported();
+    return super.fsWatchIsSupported();
+  }
+
+  // Link
+  @override
+  Link createLink(String path) {
+    if (_createLink != null) return _createLink(path);
+    if (_previous != null) return _previous.createLink(path);
+    return super.createLink(path);
+  }
+
+  // Socket
+  @override
+  Future<Socket> socketConnect(host, int port,
+      {sourceAddress, Duration timeout}) {
+    if (_socketConnect != null) {
+      return _socketConnect(host, port,
+          sourceAddress: sourceAddress, timeout: timeout);
+    }
+    if (_previous != null) {
+      return _previous.socketConnect(host, port,
+          sourceAddress: sourceAddress, timeout: timeout);
+    }
+    return super.socketConnect(host, port,
+        sourceAddress: sourceAddress, timeout: timeout);
+  }
+
+  @override
+  Future<ConnectionTask<Socket>> socketStartConnect(host, int port,
+      {sourceAddress}) {
+    if (_socketStartConnect != null) {
+      return _socketStartConnect(host, port, sourceAddress: sourceAddress);
+    }
+    if (_previous != null) {
+      return _previous.socketStartConnect(host, port,
+          sourceAddress: sourceAddress);
+    }
+    return super.socketStartConnect(host, port, sourceAddress: sourceAddress);
+  }
+}
diff --git a/sdk_nnbd/lib/io/platform.dart b/sdk_nnbd/lib/io/platform.dart
new file mode 100644
index 0000000..f7c9053
--- /dev/null
+++ b/sdk_nnbd/lib/io/platform.dart
@@ -0,0 +1,232 @@
+// Copyright (c) 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 dart.io;
+
+/**
+ * Information about the environment in which the current program is running.
+ *
+ * Platform provides information such as the operating system,
+ * the hostname of the computer, the value of environment variables,
+ * the path to the running program,
+ * and so on.
+ *
+ * ## Get the URI to the current Dart script
+ *
+ * Use the [script] getter to get the URI to the currently running
+ * Dart script.
+ *
+ *     import 'dart:io' show Platform;
+ *
+ *     void main() {
+ *       // Get the URI of the script being run.
+ *       var uri = Platform.script;
+ *       // Convert the URI to a path.
+ *       var path = uri.toFilePath();
+ *     }
+ *
+ * ## Get the value of an environment variable
+ *
+ * The [environment] getter returns a the names and values of environment
+ * variables in a [Map] that contains key-value pairs of strings. The Map is
+ * unmodifiable. This sample shows how to get the value of the `PATH`
+ * environment variable.
+ *
+ *     import 'dart:io' show Platform;
+ *
+ *     void main() {
+ *       Map<String, String> envVars = Platform.environment;
+ *       print(envVars['PATH']);
+ *     }
+ *
+ * ## Determine the OS
+ *
+ * You can get the name of the operating system as a string with the
+ * [operatingSystem] getter. You can also use one of the static boolean
+ * getters: [isMacOS], [isLinux], and [isWindows].
+ *
+ *     import 'dart:io' show Platform, stdout;
+ *
+ *     void main() {
+ *       // Get the operating system as a string.
+ *       String os = Platform.operatingSystem;
+ *       // Or, use a predicate getter.
+ *       if (Platform.isMacOS) {
+ *         print('is a Mac');
+ *       } else {
+ *         print('is not a Mac');
+ *       }
+ *     }
+ *
+ * ## Other resources
+ *
+ * [Dart by Example](https://www.dartlang.org/dart-by-example/#dart-io-and-command-line-apps)
+ * provides additional task-oriented code samples that show how to use
+ * various API from the [dart:io] library.
+ */
+class Platform {
+  static final _numberOfProcessors = _Platform.numberOfProcessors;
+  static final _pathSeparator = _Platform.pathSeparator;
+  static final _operatingSystem = _Platform.operatingSystem;
+  static final _operatingSystemVersion = _Platform.operatingSystemVersion;
+  static final _localHostname = _Platform.localHostname;
+  static final _version = _Platform.version;
+
+  /**
+   * The number of individual execution units of the machine.
+   */
+  static int get numberOfProcessors => _numberOfProcessors;
+
+  /**
+   * The path separator used by the operating system to separate
+   * components in file paths.
+   */
+  static String get pathSeparator => _pathSeparator;
+
+  /**
+   * Get the name of the current locale.
+   */
+  static String get localeName => _Platform.localeName();
+
+  /**
+   * A string representing the operating system or platform.
+   */
+  static String get operatingSystem => _operatingSystem;
+
+  /**
+   * A string representing the version of the operating system or platform.
+   */
+  static String get operatingSystemVersion => _operatingSystemVersion;
+
+  /**
+   * The local hostname for the system.
+   */
+  static String get localHostname => _localHostname;
+
+  /**
+   * Whether the operating system is a version of
+   * [Linux](https://en.wikipedia.org/wiki/Linux).
+   *
+   * This value is `false` if the operating system is a specialized
+   * version of Linux that identifies itself by a different name,
+   * for example Android (see [isAndroid]).
+   */
+  static final bool isLinux = (_operatingSystem == "linux");
+
+  /**
+   * Whether the operating system is a version of
+   * [macOS](https://en.wikipedia.org/wiki/MacOS).
+   */
+  static final bool isMacOS = (_operatingSystem == "macos");
+
+  /**
+   * Whether the operating system is a version of
+   * [Microsoft Windows](https://en.wikipedia.org/wiki/Microsoft_Windows).
+   */
+  static final bool isWindows = (_operatingSystem == "windows");
+
+  /**
+   * Whether the operating system is a version of
+   * [Android](https://en.wikipedia.org/wiki/Android_%28operating_system%29).
+   */
+  static final bool isAndroid = (_operatingSystem == "android");
+
+  /**
+   * Whether the operating system is a version of
+   * [iOS](https://en.wikipedia.org/wiki/IOS).
+   */
+  static final bool isIOS = (_operatingSystem == "ios");
+
+  /**
+   * Whether the operating system is a version of
+   * [Fuchsia](https://en.wikipedia.org/wiki/Google_Fuchsia).
+   */
+  static final bool isFuchsia = (_operatingSystem == "fuchsia");
+
+  /**
+   * The environment for this process as a map from string key to string value.
+   *
+   * The map is unmodifiable,
+   * and its content is retrieved from the operating system on its first use.
+   *
+   * Environment variables on Windows are case-insensitive,
+   * so on Windows the map is case-insensitive and will convert
+   * all keys to upper case.
+   * On other platforms, keys can be distinguished by case.
+   */
+  static Map<String, String> get environment => _Platform.environment;
+
+  /**
+   * The path of the executable used to run the script in this isolate.
+   *
+   * The literal path used to identify the script.
+   * This path might be relative or just be a name from which the executable
+   * was found by searching the system path.
+   *
+   * Use [resolvedExecutable] to get an absolute path to the executable.
+   */
+  static String get executable => _Platform.executable;
+
+  /**
+   * The path of the executable used to run the script in this
+   * isolate after it has been resolved by the OS.
+   *
+   * This is the absolute path, with all symlinks resolved, to the
+   * executable used to run the script.
+   */
+  static String get resolvedExecutable => _Platform.resolvedExecutable;
+
+  /**
+   * The absolute URI of the script being run in this isolate.
+   *
+   * If the script argument on the command line is relative,
+   * it is resolved to an absolute URI before fetching the script, and
+   * that absolute URI is returned.
+   *
+   * URI resolution only does string manipulation on the script path, and this
+   * may be different from the file system's path resolution behavior. For
+   * example, a symbolic link immediately followed by '..' will not be
+   * looked up.
+   *
+   * If the executable environment does not support [script],
+   * the URI is empty.
+   */
+  static Uri get script => _Platform.script;
+
+  /**
+   * The flags passed to the executable used to run the script in this isolate.
+   *
+   * These are the command-line flags to the executable that precedes
+   * the script name.
+   * Provides a new list every time the value is read.
+   */
+  static List<String> get executableArguments => _Platform.executableArguments;
+
+  /**
+   * This returns `null`, as `packages/` directories are no longer supported.
+   *
+   */
+  @Deprecated('packages/ directory resolution is not supported in Dart 2')
+  static String get packageRoot => null; // TODO(mfairhurst): remove this
+
+  /**
+   * The `--packages` flag passed to the executable used to run the script
+   * in this isolate.
+   *
+   * If present, it specifies a file describing how Dart packages are looked up.
+   *
+   * Is `null` if there is no `--packages` flag.
+   */
+  static String get packageConfig => _Platform.packageConfig;
+
+  /**
+   * The version of the current Dart runtime.
+   *
+   * The value is a [semantic versioning](http://semver.org)
+   * string representing the version of the current Dart runtime,
+   * possibly followed by whitespace and other version and
+   * build details.
+   */
+  static String get version => _version;
+}
diff --git a/sdk_nnbd/lib/io/platform_impl.dart b/sdk_nnbd/lib/io/platform_impl.dart
new file mode 100644
index 0000000..a350119
--- /dev/null
+++ b/sdk_nnbd/lib/io/platform_impl.dart
@@ -0,0 +1,178 @@
+// Copyright (c) 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 dart.io;
+
+class _Platform {
+  external static int _numberOfProcessors();
+  external static String _pathSeparator();
+  external static String _operatingSystem();
+  external static _operatingSystemVersion();
+  external static _localHostname();
+  external static _executable();
+  external static _resolvedExecutable();
+
+  /**
+   * Retrieve the entries of the process environment.
+   *
+   * The result is an [Iterable] of strings, where each string represents
+   * an environment entry.
+   *
+   * Environment entries should be strings containing
+   * a non-empty name and a value separated by a '=' character.
+   * The name does not contain a '=' character,
+   * so the name is everything up to the first '=' character.
+   * Values are everything after the first '=' character.
+   * A value may contain further '=' characters, and it may be empty.
+   *
+   * Returns an [OSError] if retrieving the environment fails.
+   */
+  external static _environment();
+  external static List<String> _executableArguments();
+  external static String _packageRoot(); // TODO(mfairhurst): remove this
+  external static String _packageConfig();
+  external static String _version();
+  external static String _localeName();
+  external static Uri _script();
+
+  static String executable = _executable();
+  static String resolvedExecutable = _resolvedExecutable();
+  static String packageRoot; // TODO(mfairhurst): remove this
+  static String packageConfig = _packageConfig();
+
+  @pragma("vm:entry-point")
+  static String Function() _localeClosure;
+  static String localeName() {
+    final result = (_localeClosure == null) ? _localeName() : _localeClosure();
+    if (result is OSError) {
+      throw result;
+    }
+    return result;
+  }
+
+  // Cache the OS environment. This can be an OSError instance if
+  // retrieving the environment failed.
+  static var /*OSError|Map<String,String>*/ _environmentCache;
+
+  static int get numberOfProcessors => _numberOfProcessors();
+  static String get pathSeparator => _pathSeparator();
+  static String get operatingSystem => _operatingSystem();
+  static Uri get script => _script();
+
+  static String _cachedOSVersion;
+  static String get operatingSystemVersion {
+    if (_cachedOSVersion == null) {
+      var result = _operatingSystemVersion();
+      if (result is OSError) {
+        throw result;
+      }
+      _cachedOSVersion = result;
+    }
+    return _cachedOSVersion;
+  }
+
+  static String get localHostname {
+    var result = _localHostname();
+    if (result is OSError) {
+      throw result;
+    }
+    return result;
+  }
+
+  static List<String> get executableArguments => _executableArguments();
+
+  static Map<String, String> get environment {
+    if (_environmentCache == null) {
+      var env = _environment();
+      if (env is! OSError) {
+        var isWindows = operatingSystem == 'windows';
+        var result = isWindows
+            ? new _CaseInsensitiveStringMap<String>()
+            : new Map<String, String>();
+        for (var str in env) {
+          if (str == null) {
+            continue;
+          }
+          // The Strings returned by [_environment()] are expected to be
+          // valid environment entries, but exceptions have been seen
+          // (e.g., an entry of just '=' has been seen on OS/X).
+          // Invalid entries (lines without a '=' or with an empty name)
+          // are discarded.
+          var equalsIndex = str.indexOf('=');
+          if (equalsIndex > 0) {
+            result[str.substring(0, equalsIndex)] =
+                str.substring(equalsIndex + 1);
+          }
+        }
+        _environmentCache = new UnmodifiableMapView<String, String>(result);
+      } else {
+        _environmentCache = env;
+      }
+    }
+
+    if (_environmentCache is OSError) {
+      throw _environmentCache;
+    } else {
+      return _environmentCache;
+    }
+  }
+
+  static String get version => _version();
+}
+
+// Environment variables are case-insensitive on Windows. In order
+// to reflect that we use a case-insensitive string map on Windows.
+class _CaseInsensitiveStringMap<V> extends MapBase<String, V> {
+  final Map<String, V> _map = new Map<String, V>();
+
+  bool containsKey(Object key) =>
+      key is String && _map.containsKey(key.toUpperCase());
+  bool containsValue(Object value) => _map.containsValue(value);
+  V operator [](Object key) => key is String ? _map[key.toUpperCase()] : null;
+  void operator []=(String key, V value) {
+    _map[key.toUpperCase()] = value;
+  }
+
+  V putIfAbsent(String key, V ifAbsent()) {
+    return _map.putIfAbsent(key.toUpperCase(), ifAbsent);
+  }
+
+  void addAll(Map<String, V> other) {
+    other.forEach((key, value) => this[key.toUpperCase()] = value);
+  }
+
+  V remove(Object key) => key is String ? _map.remove(key.toUpperCase()) : null;
+
+  void clear() {
+    _map.clear();
+  }
+
+  void forEach(void f(String key, V value)) {
+    _map.forEach(f);
+  }
+
+  Iterable<String> get keys => _map.keys;
+  Iterable<V> get values => _map.values;
+  int get length => _map.length;
+  bool get isEmpty => _map.isEmpty;
+  bool get isNotEmpty => _map.isNotEmpty;
+
+  Iterable<MapEntry<String, V>> get entries => _map.entries;
+
+  Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> transform(String key, V value)) =>
+      _map.map(transform);
+
+  V update(String key, V update(V value), {V ifAbsent()}) =>
+      _map.update(key.toUpperCase(), update, ifAbsent: ifAbsent);
+
+  void updateAll(V update(String key, V value)) {
+    _map.updateAll(update);
+  }
+
+  void removeWhere(bool test(String key, V value)) {
+    _map.removeWhere(test);
+  }
+
+  String toString() => _map.toString();
+}
diff --git a/sdk_nnbd/lib/io/process.dart b/sdk_nnbd/lib/io/process.dart
new file mode 100644
index 0000000..4cf78b9
--- /dev/null
+++ b/sdk_nnbd/lib/io/process.dart
@@ -0,0 +1,700 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.io;
+
+// TODO(ager): The only reason for this class is that we
+// cannot patch a top-level at this point.
+class _ProcessUtils {
+  external static void _exit(int status);
+  external static void _setExitCode(int status);
+  external static int _getExitCode();
+  external static void _sleep(int millis);
+  external static int _pid(Process process);
+  external static Stream<ProcessSignal> _watchSignal(ProcessSignal signal);
+}
+
+/**
+ * Exit the Dart VM process immediately with the given exit code.
+ *
+ * This does not wait for any asynchronous operations to terminate. Using
+ * [exit] is therefore very likely to lose data.
+ *
+ * While debugging, the VM will not respect the `--pause-isolates-on-exit`
+ * flag if [exit] is called as invoking this method causes the Dart VM
+ * process to shutdown immediately. To properly break on exit, consider
+ * calling [debugger] from `dart:developer` or [Isolate.pause] from
+ * `dart:isolate` on [Isolate.current] to pause the isolate before
+ * invoking [exit].
+ *
+ * The handling of exit codes is platform specific.
+ *
+ * On Linux and OS X an exit code for normal termination will always
+ * be in the range [0..255]. If an exit code outside this range is
+ * set the actual exit code will be the lower 8 bits masked off and
+ * treated as an unsigned value. E.g. using an exit code of -1 will
+ * result in an actual exit code of 255 being reported.
+ *
+ * On Windows the exit code can be set to any 32-bit value. However
+ * some of these values are reserved for reporting system errors like
+ * crashes.
+ *
+ * Besides this the Dart executable itself uses an exit code of `254`
+ * for reporting compile time errors and an exit code of `255` for
+ * reporting runtime error (unhandled exception).
+ *
+ * Due to these facts it is recommended to only use exit codes in the
+ * range [0..127] for communicating the result of running a Dart
+ * program to the surrounding environment. This will avoid any
+ * cross-platform issues.
+ */
+void exit(int code) {
+  ArgumentError.checkNotNull(code, "code");
+  if (!_EmbedderConfig._mayExit) {
+    throw new UnsupportedError(
+        "This embedder disallows calling dart:io's exit()");
+  }
+  _ProcessUtils._exit(code);
+}
+
+/**
+ * Set the global exit code for the Dart VM.
+ *
+ * The exit code is global for the Dart VM and the last assignment to
+ * exitCode from any isolate determines the exit code of the Dart VM
+ * on normal termination.
+ *
+ * Default value is `0`.
+ *
+ * See [exit] for more information on how to chose a value for the
+ * exit code.
+ */
+void set exitCode(int code) {
+  ArgumentError.checkNotNull(code, "code");
+  _ProcessUtils._setExitCode(code);
+}
+
+/**
+ * Get the global exit code for the Dart VM.
+ *
+ * The exit code is global for the Dart VM and the last assignment to
+ * exitCode from any isolate determines the exit code of the Dart VM
+ * on normal termination.
+ *
+ * See [exit] for more information on how to chose a value for the
+ * exit code.
+ */
+int get exitCode => _ProcessUtils._getExitCode();
+
+/**
+ * Sleep for the duration specified in [duration].
+ *
+ * Use this with care, as no asynchronous operations can be processed
+ * in a isolate while it is blocked in a [sleep] call.
+ */
+void sleep(Duration duration) {
+  int milliseconds = duration.inMilliseconds;
+  if (milliseconds < 0) {
+    throw new ArgumentError("sleep: duration cannot be negative");
+  }
+  if (!_EmbedderConfig._maySleep) {
+    throw new UnsupportedError(
+        "This embedder disallows calling dart:io's sleep()");
+  }
+  _ProcessUtils._sleep(milliseconds);
+}
+
+/**
+ * Returns the PID of the current process.
+ */
+int get pid => _ProcessUtils._pid(null);
+
+/**
+ * [ProcessInfo] provides methods for retrieving information about the
+ * current process.
+ */
+class ProcessInfo {
+  /**
+   * The current resident set size of memory for the process.
+   *
+   * Note that the meaning of this field is platform dependent. For example,
+   * some memory accounted for here may be shared with other processes, or if
+   * the same page is mapped into a process's address space, it may be counted
+   * twice.
+   */
+  external static int get currentRss;
+
+  /**
+   * The high-watermark in bytes for the resident set size of memory for the
+   * process.
+   *
+   * Note that the meaning of this field is platform dependent. For example,
+   * some memory accounted for here may be shared with other processes, or if
+   * the same page is mapped into a process's address space, it may be counted
+   * twice.
+   */
+  external static int get maxRss;
+}
+
+/**
+ * Modes for running a new process.
+ */
+class ProcessStartMode {
+  /// Normal child process.
+  static const normal = const ProcessStartMode._internal(0);
+  @Deprecated("Use normal instead")
+  static const NORMAL = normal;
+
+  /// Stdio handles are inherited by the child process.
+  static const inheritStdio = const ProcessStartMode._internal(1);
+  @Deprecated("Use inheritStdio instead")
+  static const INHERIT_STDIO = inheritStdio;
+
+  /// Detached child process with no open communication channel.
+  static const detached = const ProcessStartMode._internal(2);
+  @Deprecated("Use detached instead")
+  static const DETACHED = detached;
+
+  /// Detached child process with stdin, stdout and stderr still open
+  /// for communication with the child.
+  static const detachedWithStdio = const ProcessStartMode._internal(3);
+  @Deprecated("Use detachedWithStdio instead")
+  static const DETACHED_WITH_STDIO = detachedWithStdio;
+
+  static List<ProcessStartMode> get values => const <ProcessStartMode>[
+        normal,
+        inheritStdio,
+        detached,
+        detachedWithStdio
+      ];
+  String toString() =>
+      const ["normal", "inheritStdio", "detached", "detachedWithStdio"][_mode];
+
+  final int _mode;
+  const ProcessStartMode._internal(this._mode);
+}
+
+/**
+ * The means to execute a program.
+ *
+ * Use the static [start] and [run] methods to start a new process.
+ * The run method executes the process non-interactively to completion.
+ * In contrast, the start method allows your code to interact with the
+ * running process.
+ *
+ * ## Start a process with the run method
+ *
+ * The following code sample uses the run method to create a process
+ * that runs the UNIX command `ls`, which lists the contents of a directory.
+ * The run method completes with a [ProcessResult] object when the process
+ * terminates. This provides access to the output and exit code from the
+ * process. The run method does not return a Process object; this prevents your
+ * code from interacting with the running process.
+ *
+ *     import 'dart:io';
+ *
+ *     main() {
+ *       // List all files in the current directory in UNIX-like systems.
+ *       Process.run('ls', ['-l']).then((ProcessResult results) {
+ *         print(results.stdout);
+ *       });
+ *     }
+ *
+ * ## Start a process with the start method
+ *
+ * The following example uses start to create the process.
+ * The start method returns a [Future] for a Process object.
+ * When the future completes the process is started and
+ * your code can interact with the
+ * Process: writing to stdin, listening to stdout, and so on.
+ *
+ * The following sample starts the UNIX `cat` utility, which when given no
+ * command-line arguments, echos its input.
+ * The program writes to the process's standard input stream
+ * and prints data from its standard output stream.
+ *
+ *     import 'dart:io';
+ *     import 'dart:convert';
+ *
+ *     main() {
+ *       Process.start('cat', []).then((Process process) {
+ *         process.stdout
+ *             .transform(utf8.decoder)
+ *             .listen((data) { print(data); });
+ *         process.stdin.writeln('Hello, world!');
+ *         process.stdin.writeln('Hello, galaxy!');
+ *         process.stdin.writeln('Hello, universe!');
+ *       });
+ *     }
+ *
+ * ## Standard I/O streams
+ *
+ * As seen in the previous code sample, you can interact with the Process's
+ * standard output stream through the getter [stdout],
+ * and you can interact with the Process's standard input stream through
+ * the getter [stdin].
+ * In addition, Process provides a getter [stderr] for using the Process's
+ * standard error stream.
+ *
+ * A Process's streams are distinct from the top-level streams
+ * for the current program.
+ *
+ * ## Exit codes
+ *
+ * Call the [exitCode] method to get the exit code of the process.
+ * The exit code indicates whether the program terminated successfully
+ * (usually indicated with an exit code of 0) or with an error.
+ *
+ * If the start method is used, the exitCode is available through a future
+ * on the Process object (as shown in the example below).
+ * If the run method is used, the exitCode is available
+ * through a getter on the ProcessResult instance.
+ *
+ *     import 'dart:io';
+ *
+ *     main() {
+ *       Process.start('ls', ['-l']).then((process) {
+ *         // Get the exit code from the new process.
+ *         process.exitCode.then((exitCode) {
+ *           print('exit code: $exitCode');
+ *         });
+ *       });
+ *     }
+ *
+ * ## Other resources
+ *
+ * [Dart by Example](https://www.dartlang.org/dart-by-example/#dart-io-and-command-line-apps)
+ * provides additional task-oriented code samples that show how to use
+ * various API from the [dart:io] library.
+ */
+abstract class Process {
+  /**
+   * Returns a [:Future:] which completes with the exit code of the process
+   * when the process completes.
+   *
+   * The handling of exit codes is platform specific.
+   *
+   * On Linux and OS X a normal exit code will be a positive value in
+   * the range [0..255]. If the process was terminated due to a signal
+   * the exit code will be a negative value in the range [-255..-1],
+   * where the absolute value of the exit code is the signal
+   * number. For example, if a process crashes due to a segmentation
+   * violation the exit code will be -11, as the signal SIGSEGV has the
+   * number 11.
+   *
+   * On Windows a process can report any 32-bit value as an exit
+   * code. When returning the exit code this exit code is turned into
+   * a signed value. Some special values are used to report
+   * termination due to some system event. E.g. if a process crashes
+   * due to an access violation the 32-bit exit code is `0xc0000005`,
+   * which will be returned as the negative number `-1073741819`. To
+   * get the original 32-bit value use `(0x100000000 + exitCode) &
+   * 0xffffffff`.
+   *
+   * There is no guarantee that [stdout] and [stderr] have finished reporting
+   * the buffered output of the process when the returned future completes.
+   * To be sure that all output is captured,
+   * wait for the done event on the streams.
+   */
+  Future<int> get exitCode;
+
+  /**
+   * Starts a process running the [executable] with the specified
+   * [arguments]. Returns a [:Future<Process>:] that completes with a
+   * Process instance when the process has been successfully
+   * started. That [Process] object can be used to interact with the
+   * process. If the process cannot be started the returned [Future]
+   * completes with an exception.
+   *
+   * Use [workingDirectory] to set the working directory for the process. Note
+   * that the change of directory occurs before executing the process on some
+   * platforms, which may have impact when using relative paths for the
+   * executable and the arguments.
+   *
+   * Use [environment] to set the environment variables for the process. If not
+   * set the environment of the parent process is inherited. Currently, only
+   * US-ASCII environment variables are supported and errors are likely to occur
+   * 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 OS X, [:/bin/sh:] is used, while
+   * [:%WINDIR%\system32\cmd.exe:] is used on Windows.
+   *
+   * Users must read all data coming on the [stdout] and [stderr]
+   * streams of processes started with [:Process.start:]. If the user
+   * does not read all data on the streams the underlying system
+   * resources will not be released since there is still pending data.
+   *
+   * The following code uses `Process.start` to grep for `main` in the
+   * file `test.dart` on Linux.
+   *
+   *     Process.start('grep', ['-i', 'main', 'test.dart']).then((process) {
+   *       stdout.addStream(process.stdout);
+   *       stderr.addStream(process.stderr);
+   *     });
+   *
+   * If [mode] is [ProcessStartMode.normal] (the default) a child
+   * process will be started with `stdin`, `stdout` and `stderr`
+   * connected.
+   *
+   * If `mode` is [ProcessStartMode.detached] a detached process will
+   * be created. A detached process has no connection to its parent,
+   * and can keep running on its own when the parent dies. The only
+   * information available from a detached process is its `pid`. There
+   * is no connection to its `stdin`, `stdout` or `stderr`, nor will
+   * the process' exit code become available when it terminates.
+   *
+   * If `mode` is [ProcessStartMode.detachedWithStdio] a detached
+   * process will be created where the `stdin`, `stdout` and `stderr`
+   * are connected. The creator can communicate with the child through
+   * these. The detached process will keep running even if these
+   * communication channels are closed. The process' exit code will
+   * not become available when it terminated.
+   *
+   * The default value for `mode` is `ProcessStartMode.normal`.
+   */
+  external static Future<Process> start(
+      String executable, List<String> arguments,
+      {String workingDirectory,
+      Map<String, String> environment,
+      bool includeParentEnvironment: true,
+      bool runInShell: false,
+      ProcessStartMode mode: ProcessStartMode.normal});
+
+  /**
+   * Starts a process and runs it non-interactively to completion. The
+   * process run is [executable] with the specified [arguments].
+   *
+   * Use [workingDirectory] to set the working directory for the process. Note
+   * that the change of directory occurs before executing the process on some
+   * platforms, which may have impact when using relative paths for the
+   * executable and the arguments.
+   *
+   * Use [environment] to set the environment variables for the process. If not
+   * set the environment of the parent process is inherited. Currently, only
+   * US-ASCII environment variables are supported and errors are likely to occur
+   * 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 OS X, `/bin/sh` is used, while
+   * `%WINDIR%\system32\cmd.exe` is used on Windows.
+   *
+   * The encoding used for decoding `stdout` and `stderr` into text is
+   * controlled through [stdoutEncoding] and [stderrEncoding]. The
+   * default encoding is [systemEncoding]. If `null` is used no
+   * decoding will happen and the [ProcessResult] will hold binary
+   * data.
+   *
+   * Returns a `Future<ProcessResult>` that completes with the
+   * result of running the process, i.e., exit code, standard out and
+   * standard in.
+   *
+   * The following code uses `Process.run` to grep for `main` in the
+   * file `test.dart` on Linux.
+   *
+   *     Process.run('grep', ['-i', 'main', 'test.dart']).then((result) {
+   *       stdout.write(result.stdout);
+   *       stderr.write(result.stderr);
+   *     });
+   */
+  external static Future<ProcessResult> run(
+      String executable, List<String> arguments,
+      {String workingDirectory,
+      Map<String, String> environment,
+      bool includeParentEnvironment: true,
+      bool runInShell: false,
+      Encoding stdoutEncoding: systemEncoding,
+      Encoding stderrEncoding: systemEncoding});
+
+  /**
+   * Starts a process and runs it to completion. This is a synchronous
+   * call and will block until the child process terminates.
+   *
+   * The arguments are the same as for `Process.run`.
+   *
+   * Returns a `ProcessResult` with the result of running the process,
+   * i.e., exit code, standard out and standard in.
+   */
+  external static ProcessResult runSync(
+      String executable, List<String> arguments,
+      {String workingDirectory,
+      Map<String, String> environment,
+      bool includeParentEnvironment: true,
+      bool runInShell: false,
+      Encoding stdoutEncoding: systemEncoding,
+      Encoding stderrEncoding: systemEncoding});
+
+  /**
+   * Kills the process with id [pid].
+   *
+   * Where possible, sends the [signal] to the process with id
+   * `pid`. This includes Linux and OS X. The default signal is
+   * [ProcessSignal.sigterm] which will normally terminate the
+   * process.
+   *
+   * On platforms without signal support, including Windows, the call
+   * just terminates the process with id `pid` in a platform specific
+   * way, and the `signal` parameter is ignored.
+   *
+   * Returns `true` if the signal is successfully delivered to the
+   * process. Otherwise the signal could not be sent, usually meaning
+   * that the process is already dead.
+   */
+  external static bool killPid(int pid,
+      [ProcessSignal signal = ProcessSignal.sigterm]);
+
+  /**
+   * Returns the standard output stream of the process as a [:Stream:].
+   */
+  Stream<List<int>> get stdout;
+
+  /**
+   * Returns the standard error stream of the process as a [:Stream:].
+   */
+  Stream<List<int>> get stderr;
+
+  /**
+   * Returns the standard input stream of the process as an [IOSink].
+   */
+  IOSink get stdin;
+
+  /**
+   * Returns the process id of the process.
+   */
+  int get pid;
+
+  /**
+   * Kills the process.
+   *
+   * Where possible, sends the [signal] to the process. This includes
+   * Linux and OS X. The default signal is [ProcessSignal.sigterm]
+   * which will normally terminate the process.
+   *
+   * On platforms without signal support, including Windows, the call
+   * just terminates the process in a platform specific way, and the
+   * `signal` parameter is ignored.
+   *
+   * Returns `true` if the signal is successfully delivered to the
+   * process. Otherwise the signal could not be sent, usually meaning
+   * that the process is already dead.
+   */
+  bool kill([ProcessSignal signal = ProcessSignal.sigterm]);
+}
+
+/**
+ * [ProcessResult] represents the result of running a non-interactive
+ * process started with [Process.run] or [Process.runSync].
+ */
+class ProcessResult {
+  /**
+   * Exit code for the process.
+   *
+   * See [Process.exitCode] for more information in the exit code
+   * value.
+   */
+  final int exitCode;
+
+  /**
+   * Standard output from the process. The value used for the
+   * `stdoutEncoding` argument to `Process.run` determines the type. If
+   * `null` was used this value is of type `List<int>` otherwise it is
+   * of type `String`.
+   */
+  final stdout;
+
+  /**
+   * Standard error from the process. The value used for the
+   * `stderrEncoding` argument to `Process.run` determines the type. If
+   * `null` was used this value is of type `List<int>`
+   * otherwise it is of type `String`.
+   */
+  final stderr;
+
+  /**
+   * Process id of the process.
+   */
+  final int pid;
+
+  ProcessResult(this.pid, this.exitCode, this.stdout, this.stderr);
+}
+
+/**
+ * On Posix systems, [ProcessSignal] is used to send a specific signal
+ * to a child process, see [:Process.kill:].
+ *
+ * Some [ProcessSignal]s can also be watched, as a way to intercept the default
+ * signal handler and implement another. See [ProcessSignal.watch] for more
+ * information.
+ */
+class ProcessSignal {
+  static const ProcessSignal sighup = const ProcessSignal._(1, "SIGHUP");
+  static const ProcessSignal sigint = const ProcessSignal._(2, "SIGINT");
+  static const ProcessSignal sigquit = const ProcessSignal._(3, "SIGQUIT");
+  static const ProcessSignal sigill = const ProcessSignal._(4, "SIGILL");
+  static const ProcessSignal sigtrap = const ProcessSignal._(5, "SIGTRAP");
+  static const ProcessSignal sigabrt = const ProcessSignal._(6, "SIGABRT");
+  static const ProcessSignal sigbus = const ProcessSignal._(7, "SIGBUS");
+  static const ProcessSignal sigfpe = const ProcessSignal._(8, "SIGFPE");
+  static const ProcessSignal sigkill = const ProcessSignal._(9, "SIGKILL");
+  static const ProcessSignal sigusr1 = const ProcessSignal._(10, "SIGUSR1");
+  static const ProcessSignal sigsegv = const ProcessSignal._(11, "SIGSEGV");
+  static const ProcessSignal sigusr2 = const ProcessSignal._(12, "SIGUSR2");
+  static const ProcessSignal sigpipe = const ProcessSignal._(13, "SIGPIPE");
+  static const ProcessSignal sigalrm = const ProcessSignal._(14, "SIGALRM");
+  static const ProcessSignal sigterm = const ProcessSignal._(15, "SIGTERM");
+  static const ProcessSignal sigchld = const ProcessSignal._(17, "SIGCHLD");
+  static const ProcessSignal sigcont = const ProcessSignal._(18, "SIGCONT");
+  static const ProcessSignal sigstop = const ProcessSignal._(19, "SIGSTOP");
+  static const ProcessSignal sigtstp = const ProcessSignal._(20, "SIGTSTP");
+  static const ProcessSignal sigttin = const ProcessSignal._(21, "SIGTTIN");
+  static const ProcessSignal sigttou = const ProcessSignal._(22, "SIGTTOU");
+  static const ProcessSignal sigurg = const ProcessSignal._(23, "SIGURG");
+  static const ProcessSignal sigxcpu = const ProcessSignal._(24, "SIGXCPU");
+  static const ProcessSignal sigxfsz = const ProcessSignal._(25, "SIGXFSZ");
+  static const ProcessSignal sigvtalrm = const ProcessSignal._(26, "SIGVTALRM");
+  static const ProcessSignal sigprof = const ProcessSignal._(27, "SIGPROF");
+  static const ProcessSignal sigwinch = const ProcessSignal._(28, "SIGWINCH");
+  static const ProcessSignal sigpoll = const ProcessSignal._(29, "SIGPOLL");
+  static const ProcessSignal sigsys = const ProcessSignal._(31, "SIGSYS");
+
+  @Deprecated("Use sighup instead")
+  static const ProcessSignal SIGHUP = sighup;
+  @Deprecated("Use sigint instead")
+  static const ProcessSignal SIGINT = sigint;
+  @Deprecated("Use sigquit instead")
+  static const ProcessSignal SIGQUIT = sigquit;
+  @Deprecated("Use sigill instead")
+  static const ProcessSignal SIGILL = sigill;
+  @Deprecated("Use sigtrap instead")
+  static const ProcessSignal SIGTRAP = sigtrap;
+  @Deprecated("Use sigabrt instead")
+  static const ProcessSignal SIGABRT = sigabrt;
+  @Deprecated("Use sigbus instead")
+  static const ProcessSignal SIGBUS = sigbus;
+  @Deprecated("Use sigfpe instead")
+  static const ProcessSignal SIGFPE = sigfpe;
+  @Deprecated("Use sigkill instead")
+  static const ProcessSignal SIGKILL = sigkill;
+  @Deprecated("Use sigusr1 instead")
+  static const ProcessSignal SIGUSR1 = sigusr1;
+  @Deprecated("Use sigsegv instead")
+  static const ProcessSignal SIGSEGV = sigsegv;
+  @Deprecated("Use sigusr2 instead")
+  static const ProcessSignal SIGUSR2 = sigusr2;
+  @Deprecated("Use sigpipe instead")
+  static const ProcessSignal SIGPIPE = sigpipe;
+  @Deprecated("Use sigalrm instead")
+  static const ProcessSignal SIGALRM = sigalrm;
+  @Deprecated("Use sigterm instead")
+  static const ProcessSignal SIGTERM = sigterm;
+  @Deprecated("Use sigchld instead")
+  static const ProcessSignal SIGCHLD = sigchld;
+  @Deprecated("Use sigcont instead")
+  static const ProcessSignal SIGCONT = sigcont;
+  @Deprecated("Use sigstop instead")
+  static const ProcessSignal SIGSTOP = sigstop;
+  @Deprecated("Use sigtstp instead")
+  static const ProcessSignal SIGTSTP = sigtstp;
+  @Deprecated("Use sigttin instead")
+  static const ProcessSignal SIGTTIN = sigttin;
+  @Deprecated("Use sigttou instead")
+  static const ProcessSignal SIGTTOU = sigttou;
+  @Deprecated("Use sigurg instead")
+  static const ProcessSignal SIGURG = sigurg;
+  @Deprecated("Use sigxcpu instead")
+  static const ProcessSignal SIGXCPU = sigxcpu;
+  @Deprecated("Use sigxfsz instead")
+  static const ProcessSignal SIGXFSZ = sigxfsz;
+  @Deprecated("Use sigvtalrm instead")
+  static const ProcessSignal SIGVTALRM = sigvtalrm;
+  @Deprecated("Use sigprof instead")
+  static const ProcessSignal SIGPROF = sigprof;
+  @Deprecated("Use sigwinch instead")
+  static const ProcessSignal SIGWINCH = sigwinch;
+  @Deprecated("Use sigpoll instead")
+  static const ProcessSignal SIGPOLL = sigpoll;
+  @Deprecated("Use sigsys instead")
+  static const ProcessSignal SIGSYS = sigsys;
+
+  final int _signalNumber;
+  final String _name;
+
+  const ProcessSignal._(this._signalNumber, this._name);
+
+  String toString() => _name;
+
+  /**
+   * Watch for process signals.
+   *
+   * The following [ProcessSignal]s can be listened to:
+   *
+   *   * [ProcessSignal.sighup].
+   *   * [ProcessSignal.sigint]. Signal sent by e.g. CTRL-C.
+   *   * [ProcessSignal.sigterm]. Not available on Windows.
+   *   * [ProcessSignal.sigusr1]. Not available on Windows.
+   *   * [ProcessSignal.sigusr2]. Not available on Windows.
+   *   * [ProcessSignal.sigwinch]. Not available on Windows.
+   *
+   * Other signals are disallowed, as they may be used by the VM.
+   *
+   * A signal can be watched multiple times, from multiple isolates, where all
+   * callbacks are invoked when signaled, in no specific order.
+   */
+  Stream<ProcessSignal> watch() => _ProcessUtils._watchSignal(this);
+}
+
+class SignalException implements IOException {
+  final String message;
+  final osError;
+
+  const SignalException(this.message, [this.osError]);
+
+  String toString() {
+    var msg = "";
+    if (osError != null) {
+      msg = ", osError: $osError";
+    }
+    return "SignalException: $message$msg";
+  }
+}
+
+class ProcessException implements IOException {
+  /**
+   * Contains the executable provided for the process.
+   */
+  final String executable;
+
+  /**
+   * Contains the arguments provided for the process.
+   */
+  final List<String> arguments;
+
+  /**
+   * Contains the system message for the process exception if any.
+   */
+  final String message;
+
+  /**
+   * Contains the OS error code for the process exception if any.
+   */
+  final int errorCode;
+
+  const ProcessException(this.executable, this.arguments,
+      [this.message = "", this.errorCode = 0]);
+  String toString() {
+    var msg = (message == null) ? 'OS error code: $errorCode' : message;
+    var args = arguments.join(' ');
+    return "ProcessException: $msg\n  Command: $executable $args";
+  }
+}
diff --git a/sdk_nnbd/lib/io/secure_server_socket.dart b/sdk_nnbd/lib/io/secure_server_socket.dart
new file mode 100644
index 0000000..b4ca32e
--- /dev/null
+++ b/sdk_nnbd/lib/io/secure_server_socket.dart
@@ -0,0 +1,291 @@
+// Copyright (c) 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 dart.io;
+
+/**
+ * The [SecureServerSocket] is a server socket, providing a stream of high-level
+ * [Socket]s.
+ *
+ * See [SecureSocket] for more info.
+ */
+class SecureServerSocket extends Stream<SecureSocket> {
+  final RawSecureServerSocket _socket;
+
+  SecureServerSocket._(this._socket);
+
+  /**
+   * Returns a future for a [SecureServerSocket]. When the future
+   * completes the server socket is bound to the given [address] and
+   * [port] and has started listening on it.
+   *
+   * The [address] can either be a [String] or an
+   * [InternetAddress]. If [address] is a [String], [bind] will
+   * perform a [InternetAddress.lookup] and use the first value in the
+   * list. To listen on the loopback adapter, which will allow only
+   * incoming connections from the local host, use the value
+   * [InternetAddress.loopbackIPv4] or
+   * [InternetAddress.loopbackIPv6]. To allow for incoming
+   * connection from the network use either one of the values
+   * [InternetAddress.anyIPv4] or [InternetAddress.anyIPv6] to
+   * bind to all interfaces or the IP address of a specific interface.
+   *
+   * If [port] has the value [:0:] an ephemeral port will be chosen by
+   * the system. The actual port used can be retrieved using the
+   * [port] getter.
+   *
+   * The optional argument [backlog] can be used to specify the listen
+   * backlog for the underlying OS listen setup. If [backlog] has the
+   * value of [:0:] (the default) a reasonable value will be chosen by
+   * the system.
+   *
+   * Incoming client connections are promoted to secure connections, using
+   * the server certificate and key set in [context].
+   *
+   * [address] must be given as a numeric address, not a host name.
+   *
+   * To request or require that clients authenticate by providing an SSL (TLS)
+   * client certificate, set the optional parameter [requestClientCertificate]
+   * or [requireClientCertificate] to true.  Requiring a certificate implies
+   * requesting a certificate, so setting both is redundant.
+   * To check whether a client certificate was received, check
+   * SecureSocket.peerCertificate after connecting.  If no certificate
+   * was received, the result will be null.
+   *
+   * [supportedProtocols] is an optional list of protocols (in decreasing
+   * order of preference) to use during the ALPN protocol negogiation with
+   * clients.  Example values are "http/1.1" or "h2".  The selected protocol
+   * can be obtained via [SecureSocket.selectedProtocol].
+   *
+   * The optional argument [shared] specifies whether additional
+   * SecureServerSocket objects can bind to the same combination of `address`,
+   * `port` and `v6Only`.  If `shared` is `true` and more `SecureServerSocket`s
+   * from this isolate or other isolates are bound to the port, then the
+   * incoming connections will be distributed among all the bound
+   * `SecureServerSocket`s. Connections can be distributed over multiple
+   * isolates this way.
+   */
+  static Future<SecureServerSocket> bind(
+      address, int port, SecurityContext context,
+      {int backlog: 0,
+      bool v6Only: false,
+      bool requestClientCertificate: false,
+      bool requireClientCertificate: false,
+      List<String> supportedProtocols,
+      bool shared: false}) {
+    return RawSecureServerSocket
+        .bind(address, port, context,
+            backlog: backlog,
+            v6Only: v6Only,
+            requestClientCertificate: requestClientCertificate,
+            requireClientCertificate: requireClientCertificate,
+            supportedProtocols: supportedProtocols,
+            shared: shared)
+        .then((serverSocket) => new SecureServerSocket._(serverSocket));
+  }
+
+  StreamSubscription<SecureSocket> listen(void onData(SecureSocket socket),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    return _socket.map((rawSocket) => new SecureSocket._(rawSocket)).listen(
+        onData,
+        onError: onError,
+        onDone: onDone,
+        cancelOnError: cancelOnError);
+  }
+
+  /**
+   * Returns the port used by this socket.
+   */
+  int get port => _socket.port;
+
+  /**
+   * Returns the address used by this socket.
+   */
+  InternetAddress get address => _socket.address;
+
+  /**
+   * Closes the socket. The returned future completes when the socket
+   * is fully closed and is no longer bound.
+   */
+  Future<SecureServerSocket> close() => _socket.close().then((_) => this);
+
+  void set _owner(owner) {
+    _socket._owner = owner;
+  }
+}
+
+/**
+ * The RawSecureServerSocket is a server socket, providing a stream of low-level
+ * [RawSecureSocket]s.
+ *
+ * See [RawSecureSocket] for more info.
+ */
+class RawSecureServerSocket extends Stream<RawSecureSocket> {
+  final RawServerSocket _socket;
+  StreamController<RawSecureSocket> _controller;
+  StreamSubscription<RawSocket> _subscription;
+  final SecurityContext _context;
+  final bool requestClientCertificate;
+  final bool requireClientCertificate;
+  final List<String> supportedProtocols;
+  bool _closed = false;
+
+  RawSecureServerSocket._(
+      this._socket,
+      this._context,
+      this.requestClientCertificate,
+      this.requireClientCertificate,
+      this.supportedProtocols) {
+    _controller = new StreamController<RawSecureSocket>(
+        sync: true,
+        onListen: _onSubscriptionStateChange,
+        onPause: _onPauseStateChange,
+        onResume: _onPauseStateChange,
+        onCancel: _onSubscriptionStateChange);
+  }
+
+  /**
+   * Returns a future for a [RawSecureServerSocket]. When the future
+   * completes the server socket is bound to the given [address] and
+   * [port] and has started listening on it.
+   *
+   * The [address] can either be a [String] or an
+   * [InternetAddress]. If [address] is a [String], [bind] will
+   * perform a [InternetAddress.lookup] and use the first value in the
+   * list. To listen on the loopback adapter, which will allow only
+   * incoming connections from the local host, use the value
+   * [InternetAddress.loopbackIPv4] or
+   * [InternetAddress.loopbackIPv6]. To allow for incoming
+   * connection from the network use either one of the values
+   * [InternetAddress.anyIPv4] or [InternetAddress.anyIPv6] to
+   * bind to all interfaces or the IP address of a specific interface.
+   *
+   * If [port] has the value [:0:] an ephemeral port will be chosen by
+   * the system. The actual port used can be retrieved using the
+   * [port] getter.
+   *
+   * The optional argument [backlog] can be used to specify the listen
+   * backlog for the underlying OS listen setup. If [backlog] has the
+   * value of [:0:] (the default) a reasonable value will be chosen by
+   * the system.
+   *
+   * Incoming client connections are promoted to secure connections,
+   * using the server certificate and key set in [context].
+   *
+   * [address] must be given as a numeric address, not a host name.
+   *
+   * To request or require that clients authenticate by providing an SSL (TLS)
+   * client certificate, set the optional parameters requestClientCertificate or
+   * requireClientCertificate to true.  Require implies request, so one doesn't
+   * need to specify both.  To check whether a client certificate was received,
+   * check SecureSocket.peerCertificate after connecting.  If no certificate
+   * was received, the result will be null.
+   *
+   * [supportedProtocols] is an optional list of protocols (in decreasing
+   * order of preference) to use during the ALPN protocol negotiation with
+   * clients.  Example values are "http/1.1" or "h2".  The selected protocol
+   * can be obtained via [RawSecureSocket.selectedProtocol].
+   *
+   * The optional argument [shared] specifies whether additional
+   * RawSecureServerSocket objects can bind to the same combination of
+   * `address`, `port` and `v6Only`.  If `shared` is `true` and more
+   * `RawSecureServerSocket`s from this isolate or other isolates are bound to
+   * the port, then the incoming connections will be distributed among all the
+   * bound `RawSecureServerSocket`s. Connections can be distributed over
+   * multiple isolates this way.
+   */
+  static Future<RawSecureServerSocket> bind(
+      address, int port, SecurityContext context,
+      {int backlog: 0,
+      bool v6Only: false,
+      bool requestClientCertificate: false,
+      bool requireClientCertificate: false,
+      List<String> supportedProtocols,
+      bool shared: false}) {
+    return RawServerSocket
+        .bind(address, port, backlog: backlog, v6Only: v6Only, shared: shared)
+        .then((serverSocket) => new RawSecureServerSocket._(
+            serverSocket,
+            context,
+            requestClientCertificate,
+            requireClientCertificate,
+            supportedProtocols));
+  }
+
+  StreamSubscription<RawSecureSocket> listen(void onData(RawSecureSocket s),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    return _controller.stream.listen(onData,
+        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+  }
+
+  /**
+   * Returns the port used by this socket.
+   */
+  int get port => _socket.port;
+
+  /**
+   * Returns the address used by this socket.
+   */
+  InternetAddress get address => _socket.address;
+
+  /**
+   * Closes the socket. The returned future completes when the socket
+   * is fully closed and is no longer bound.
+   */
+  Future<RawSecureServerSocket> close() {
+    _closed = true;
+    return _socket.close().then((_) => this);
+  }
+
+  void _onData(RawSocket connection) {
+    var remotePort;
+    try {
+      remotePort = connection.remotePort;
+    } catch (e) {
+      // If connection is already closed, remotePort throws an exception.
+      // Do nothing - connection is closed.
+      return;
+    }
+    _RawSecureSocket
+        .connect(connection.address, remotePort,
+            context: _context,
+            is_server: true,
+            socket: connection,
+            requestClientCertificate: requestClientCertificate,
+            requireClientCertificate: requireClientCertificate,
+            supportedProtocols: supportedProtocols)
+        .then((RawSecureSocket secureConnection) {
+      if (_closed) {
+        secureConnection.close();
+      } else {
+        _controller.add(secureConnection);
+      }
+    }).catchError((e, s) {
+      if (!_closed) {
+        _controller.addError(e, s);
+      }
+    });
+  }
+
+  void _onPauseStateChange() {
+    if (_controller.isPaused) {
+      _subscription.pause();
+    } else {
+      _subscription.resume();
+    }
+  }
+
+  void _onSubscriptionStateChange() {
+    if (_controller.hasListener) {
+      _subscription = _socket.listen(_onData,
+          onError: _controller.addError, onDone: _controller.close);
+    } else {
+      close();
+    }
+  }
+
+  void set _owner(owner) {
+    (_socket as dynamic)._owner = owner;
+  }
+}
diff --git a/sdk_nnbd/lib/io/secure_socket.dart b/sdk_nnbd/lib/io/secure_socket.dart
new file mode 100644
index 0000000..a4751ef
--- /dev/null
+++ b/sdk_nnbd/lib/io/secure_socket.dart
@@ -0,0 +1,1319 @@
+// 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 dart.io;
+
+/**
+ * A high-level class for communicating securely over a TCP socket, using
+ * TLS and SSL. The [SecureSocket] exposes both a [Stream] and an
+ * [IOSink] interface, making it ideal for using together with
+ * other [Stream]s.
+ */
+abstract class SecureSocket implements Socket {
+  external factory SecureSocket._(RawSecureSocket rawSocket);
+
+  /**
+   * Constructs a new secure client socket and connects it to the given
+   * [host] on port [port]. The returned Future will complete with a
+   * [SecureSocket] that is connected and ready for subscription.
+   *
+   * The certificate provided by the server is checked
+   * using the trusted certificates set in the SecurityContext object.
+   * The default SecurityContext object contains a built-in set of trusted
+   * root certificates for well-known certificate authorities.
+   *
+   * [onBadCertificate] is an optional handler for unverifiable certificates.
+   * The handler receives the [X509Certificate], and can inspect it and
+   * decide (or let the user decide) whether to accept
+   * the connection or not.  The handler should return true
+   * to continue the [SecureSocket] connection.
+   *
+   * [supportedProtocols] is an optional list of protocols (in decreasing
+   * order of preference) to use during the ALPN protocol negotiation with the
+   * server.  Example values are "http/1.1" or "h2".  The selected protocol
+   * can be obtained via [SecureSocket.selectedProtocol].
+   *
+   * The argument [timeout] is used to specify the maximum allowed time to wait
+   * for a connection to be established. If [timeout] is longer than the system
+   * level timeout duration, a timeout may occur sooner than specified in
+   * [timeout]. On timeout, a [SocketException] is thrown and all ongoing
+   * connection attempts to [host] are cancelled.
+
+   */
+  static Future<SecureSocket> connect(host, int port,
+      {SecurityContext context,
+      bool onBadCertificate(X509Certificate certificate),
+      List<String> supportedProtocols,
+      Duration timeout}) {
+    return RawSecureSocket.connect(host, port,
+            context: context,
+            onBadCertificate: onBadCertificate,
+            supportedProtocols: supportedProtocols,
+            timeout: timeout)
+        .then((rawSocket) => new SecureSocket._(rawSocket));
+  }
+
+  /// Like [connect], but returns a [Future] that completes with a
+  /// [ConnectionTask] that can be cancelled if the [SecureSocket] is no
+  /// longer needed.
+  static Future<ConnectionTask<SecureSocket>> startConnect(host, int port,
+      {SecurityContext context,
+      bool onBadCertificate(X509Certificate certificate),
+      List<String> supportedProtocols}) {
+    return RawSecureSocket.startConnect(host, port,
+            context: context,
+            onBadCertificate: onBadCertificate,
+            supportedProtocols: supportedProtocols)
+        .then((rawState) {
+      Future<SecureSocket> socket =
+          rawState.socket.then((rawSocket) => new SecureSocket._(rawSocket));
+      return new ConnectionTask<SecureSocket>._(
+          socket: socket, onCancel: rawState._onCancel);
+    });
+  }
+
+  /**
+   * Takes an already connected [socket] and starts client side TLS
+   * handshake to make the communication secure. When the returned
+   * future completes the [SecureSocket] has completed the TLS
+   * handshake. Using this function requires that the other end of the
+   * connection is prepared for TLS handshake.
+   *
+   * 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
+   * the right thing to do.
+   *
+   * The given [socket] is closed and may not be used anymore.
+   *
+   * 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].
+   *
+   * [supportedProtocols] is an optional list of protocols (in decreasing
+   * order of preference) to use during the ALPN protocol negotiation with the
+   * server.  Example values are "http/1.1" or "h2".  The selected protocol
+   * can be obtained via [SecureSocket.selectedProtocol].
+   *
+   * 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.
+   *
+   */
+  static Future<SecureSocket> secure(Socket socket,
+      {host,
+      SecurityContext context,
+      bool onBadCertificate(X509Certificate certificate),
+      @Since("2.6") List<String> supportedProtocols}) {
+    return ((socket as dynamic /*_Socket*/)._detachRaw() as Future)
+        .then<RawSecureSocket>((detachedRaw) {
+      return RawSecureSocket.secure(detachedRaw[0] as RawSocket,
+          subscription: detachedRaw[1] as StreamSubscription<RawSocketEvent>,
+          host: host,
+          context: context,
+          onBadCertificate: onBadCertificate,
+          supportedProtocols: supportedProtocols);
+    }).then<SecureSocket>((raw) => new SecureSocket._(raw));
+  }
+
+  /**
+   * Takes an already connected [socket] and starts server side TLS
+   * handshake to make the communication secure. When the returned
+   * future completes the [SecureSocket] has completed the TLS
+   * handshake. Using this function requires that the other end of the
+   * connection is going to start the TLS handshake.
+   *
+   * 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
+   * the right thing to do.
+   *
+   * If some of the data of the TLS handshake has already been read
+   * from the socket this data can be passed in the [bufferedData]
+   * parameter. This data will be processed before any other data
+   * available on the socket.
+   *
+   * See [SecureServerSocket.bind] for more information on the
+   * arguments.
+   *
+   */
+  static Future<SecureSocket> secureServer(
+      Socket socket, SecurityContext context,
+      {List<int> bufferedData,
+      bool requestClientCertificate: false,
+      bool requireClientCertificate: false,
+      List<String> supportedProtocols}) {
+    return ((socket as dynamic /*_Socket*/)._detachRaw() as Future)
+        .then<RawSecureSocket>((detachedRaw) {
+      return RawSecureSocket.secureServer(detachedRaw[0] as RawSocket, context,
+          subscription: detachedRaw[1] as StreamSubscription<RawSocketEvent>,
+          bufferedData: bufferedData,
+          requestClientCertificate: requestClientCertificate,
+          requireClientCertificate: requireClientCertificate,
+          supportedProtocols: supportedProtocols);
+    }).then<SecureSocket>((raw) => new SecureSocket._(raw));
+  }
+
+  /**
+   * Get the peer certificate for a connected SecureSocket.  If this
+   * SecureSocket is the server end of a secure socket connection,
+   * [peerCertificate] will return the client certificate, or null, if no
+   * client certificate was received.  If it is the client end,
+   * [peerCertificate] will return the server's certificate.
+   */
+  X509Certificate get peerCertificate;
+
+  /**
+   * The protocol which was selected during ALPN protocol negotiation.
+   *
+   * Returns null if one of the peers does not have support for ALPN, did not
+   * specify a list of supported ALPN protocols or there was no common
+   * protocol between client and server.
+   */
+  String get selectedProtocol;
+
+  /**
+   * Renegotiate an existing secure connection, renewing the session keys
+   * and possibly changing the connection properties.
+   *
+   * This repeats the SSL or TLS handshake, with options that allow clearing
+   * the session cache and requesting a client certificate.
+   */
+  void renegotiate(
+      {bool useSessionCache: true,
+      bool requestClientCertificate: false,
+      bool requireClientCertificate: false});
+}
+
+/**
+ * RawSecureSocket provides a secure (SSL or TLS) network connection.
+ * Client connections to a server are provided by calling
+ * RawSecureSocket.connect.  A secure server, created with
+ * [RawSecureServerSocket], also returns RawSecureSocket objects representing
+ * the server end of a secure connection.
+ * The certificate provided by the server is checked
+ * using the trusted certificates set in the SecurityContext object.
+ * The default [SecurityContext] object contains a built-in set of trusted
+ * root certificates for well-known certificate authorities.
+ */
+abstract class RawSecureSocket implements RawSocket {
+  /**
+   * Constructs a new secure client socket and connect it to the given
+   * host on the given port. The returned [Future] is completed with the
+   * RawSecureSocket when it is connected and ready for subscription.
+   *
+   * The certificate provided by the server is checked using the trusted
+   * certificates set in the SecurityContext object If a certificate and key are
+   * set on the client, using [SecurityContext.useCertificateChain] and
+   * [SecurityContext.usePrivateKey], and the server asks for a client
+   * certificate, then that client certificate is sent to the server.
+   *
+   * [onBadCertificate] is an optional handler for unverifiable certificates.
+   * The handler receives the [X509Certificate], and can inspect it and
+   * decide (or let the user decide) whether to accept
+   * the connection or not.  The handler should return true
+   * to continue the [RawSecureSocket] connection.
+   *
+   * [supportedProtocols] is an optional list of protocols (in decreasing
+   * order of preference) to use during the ALPN protocol negotiation with the
+   * server.  Example values are "http/1.1" or "h2".  The selected protocol
+   * can be obtained via [RawSecureSocket.selectedProtocol].
+   */
+  static Future<RawSecureSocket> connect(host, int port,
+      {SecurityContext context,
+      bool onBadCertificate(X509Certificate certificate),
+      List<String> supportedProtocols,
+      Duration timeout}) {
+    _RawSecureSocket._verifyFields(
+        host, port, false, false, false, onBadCertificate);
+    return RawSocket.connect(host, port, timeout: timeout).then((socket) {
+      return secure(socket,
+          context: context,
+          onBadCertificate: onBadCertificate,
+          supportedProtocols: supportedProtocols);
+    });
+  }
+
+  /// Like [connect], but returns a [Future] that completes with a
+  /// [ConnectionTask] that can be cancelled if the [RawSecureSocket] is no
+  /// longer needed.
+  static Future<ConnectionTask<RawSecureSocket>> startConnect(host, int port,
+      {SecurityContext context,
+      bool onBadCertificate(X509Certificate certificate),
+      List<String> supportedProtocols}) {
+    return RawSocket.startConnect(host, port)
+        .then((ConnectionTask<RawSocket> rawState) {
+      Future<RawSecureSocket> socket = rawState.socket.then((rawSocket) {
+        return secure(rawSocket,
+            context: context,
+            onBadCertificate: onBadCertificate,
+            supportedProtocols: supportedProtocols);
+      });
+      return new ConnectionTask<RawSecureSocket>._(
+          socket: socket, onCancel: rawState._onCancel);
+    });
+  }
+
+  /**
+   * Takes an already connected [socket] and starts client side TLS
+   * handshake to make the communication secure. When the returned
+   * future completes the [RawSecureSocket] has completed the TLS
+   * handshake. Using this function requires that the other end of the
+   * connection is prepared for TLS handshake.
+   *
+   * If the [socket] already has a subscription, pass the existing
+   * subscription in the [subscription] parameter. The [secure]
+   * operation will take over the subscription by replacing the
+   * handlers with it own secure processing. The caller must not touch
+   * this subscription anymore. Passing a paused subscription is an
+   * error.
+   *
+   * 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].
+   *
+   * [supportedProtocols] is an optional list of protocols (in decreasing
+   * order of preference) to use during the ALPN protocol negotiation with the
+   * server.  Example values are "http/1.1" or "h2".  The selected protocol
+   * can be obtained via [SecureSocket.selectedProtocol].
+   *
+   * 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.
+   *
+   */
+  static Future<RawSecureSocket> secure(RawSocket socket,
+      {StreamSubscription<RawSocketEvent> subscription,
+      host,
+      SecurityContext context,
+      bool onBadCertificate(X509Certificate certificate),
+      List<String> supportedProtocols}) {
+    socket.readEventsEnabled = false;
+    socket.writeEventsEnabled = false;
+    return _RawSecureSocket.connect(
+        host != null ? host : socket.address.host, socket.port,
+        is_server: false,
+        socket: socket,
+        subscription: subscription,
+        context: context,
+        onBadCertificate: onBadCertificate,
+        supportedProtocols: supportedProtocols);
+  }
+
+  /**
+   * Takes an already connected [socket] and starts server side TLS
+   * handshake to make the communication secure. When the returned
+   * future completes the [RawSecureSocket] has completed the TLS
+   * handshake. Using this function requires that the other end of the
+   * connection is going to start the TLS handshake.
+   *
+   * If the [socket] already has a subscription, pass the existing
+   * subscription in the [subscription] parameter. The [secureServer]
+   * operation will take over the subscription by replacing the
+   * handlers with it own secure processing. The caller must not touch
+   * this subscription anymore. Passing a paused subscription is an
+   * error.
+   *
+   * If some of the data of the TLS handshake has already been read
+   * from the socket this data can be passed in the [bufferedData]
+   * parameter. This data will be processed before any other data
+   * available on the socket.
+   *
+   * See [RawSecureServerSocket.bind] for more information on the
+   * arguments.
+   *
+   */
+  static Future<RawSecureSocket> secureServer(
+      RawSocket socket, SecurityContext context,
+      {StreamSubscription<RawSocketEvent> subscription,
+      List<int> bufferedData,
+      bool requestClientCertificate: false,
+      bool requireClientCertificate: false,
+      List<String> supportedProtocols}) {
+    socket.readEventsEnabled = false;
+    socket.writeEventsEnabled = false;
+    return _RawSecureSocket.connect(socket.address, socket.remotePort,
+        context: context,
+        is_server: true,
+        socket: socket,
+        subscription: subscription,
+        bufferedData: bufferedData,
+        requestClientCertificate: requestClientCertificate,
+        requireClientCertificate: requireClientCertificate,
+        supportedProtocols: supportedProtocols);
+  }
+
+  /**
+   * Renegotiate an existing secure connection, renewing the session keys
+   * and possibly changing the connection properties.
+   *
+   * This repeats the SSL or TLS handshake, with options that allow clearing
+   * the session cache and requesting a client certificate.
+   */
+  void renegotiate(
+      {bool useSessionCache: true,
+      bool requestClientCertificate: false,
+      bool requireClientCertificate: false});
+
+  /**
+   * Get the peer certificate for a connected RawSecureSocket.  If this
+   * RawSecureSocket is the server end of a secure socket connection,
+   * [peerCertificate] will return the client certificate, or null, if no
+   * client certificate was received.  If it is the client end,
+   * [peerCertificate] will return the server's certificate.
+   */
+  X509Certificate get peerCertificate;
+
+  /**
+   * The protocol which was selected during protocol negotiation.
+   *
+   * Returns null if one of the peers does not have support for ALPN, did not
+   * specify a list of supported ALPN protocols or there was no common
+   * protocol between client and server.
+   */
+  String get selectedProtocol;
+}
+
+/**
+ * X509Certificate represents an SSL certificate, with accessors to
+ * get the fields of the certificate.
+ */
+@pragma("vm:entry-point")
+abstract class X509Certificate {
+  @pragma("vm:entry-point")
+  external factory X509Certificate._();
+
+  /// The DER encoded bytes of the certificate.
+  Uint8List get der;
+
+  /// The PEM encoded String of the certificate.
+  String get pem;
+
+  /// The SHA1 hash of the certificate.
+  Uint8List get sha1;
+
+  String get subject;
+  String get issuer;
+  DateTime get startValidity;
+  DateTime get endValidity;
+}
+
+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 const int handshakeStatus = 201;
+  static const int connectedStatus = 202;
+  static const int closedStatus = 203;
+
+  // Buffer identifiers.
+  // These must agree with those in the native C++ implementation.
+  static const int readPlaintextId = 0;
+  static const int writePlaintextId = 1;
+  static const int readEncryptedId = 2;
+  static const int writeEncryptedId = 3;
+  static const int bufferCount = 4;
+
+  // Is a buffer identifier for an encrypted buffer?
+  static bool _isBufferEncrypted(int identifier) =>
+      identifier >= readEncryptedId;
+
+  RawSocket _socket;
+  final Completer<_RawSecureSocket> _handshakeComplete =
+      new Completer<_RawSecureSocket>();
+  StreamController<RawSocketEvent> _controller;
+  Stream<RawSocketEvent> _stream;
+  StreamSubscription<RawSocketEvent> _socketSubscription;
+  List<int> _bufferedData;
+  int _bufferedDataIndex = 0;
+  final InternetAddress address;
+  final bool is_server;
+  SecurityContext context;
+  final bool requestClientCertificate;
+  final bool requireClientCertificate;
+  final Function onBadCertificate;
+
+  var _status = handshakeStatus;
+  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.
+  // The network socket is gone.
+  Completer<RawSecureSocket> _closeCompleter = new Completer<RawSecureSocket>();
+  _FilterStatus _filterStatus = new _FilterStatus();
+  bool _connectPending = true;
+  bool _filterPending = false;
+  bool _filterActive = false;
+
+  _SecureFilter _secureFilter = new _SecureFilter._();
+  String _selectedProtocol;
+
+  static Future<_RawSecureSocket> connect(
+      dynamic /*String|InternetAddress*/ host, int requestedPort,
+      {bool is_server,
+      SecurityContext context,
+      RawSocket socket,
+      StreamSubscription<RawSocketEvent> subscription,
+      List<int> bufferedData,
+      bool requestClientCertificate: false,
+      bool requireClientCertificate: false,
+      bool onBadCertificate(X509Certificate certificate),
+      List<String> supportedProtocols}) {
+    _verifyFields(host, requestedPort, is_server, requestClientCertificate,
+        requireClientCertificate, onBadCertificate);
+    if (host is InternetAddress) host = host.host;
+    InternetAddress address = socket.address;
+    if (host != null) {
+      address = InternetAddress._cloneWithNewHost(address, host);
+    }
+    return new _RawSecureSocket(
+            address,
+            requestedPort,
+            is_server,
+            context,
+            socket,
+            subscription,
+            bufferedData,
+            requestClientCertificate,
+            requireClientCertificate,
+            onBadCertificate,
+            supportedProtocols)
+        ._handshakeComplete
+        .future;
+  }
+
+  _RawSecureSocket(
+      this.address,
+      int requestedPort,
+      this.is_server,
+      this.context,
+      this._socket,
+      this._socketSubscription,
+      this._bufferedData,
+      this.requestClientCertificate,
+      this.requireClientCertificate,
+      this.onBadCertificate,
+      List<String> supportedProtocols) {
+    context ??= SecurityContext.defaultContext;
+    _controller = new StreamController<RawSocketEvent>(
+        sync: true,
+        onListen: _onSubscriptionStateChange,
+        onPause: _onPauseStateChange,
+        onResume: _onPauseStateChange,
+        onCancel: _onSubscriptionStateChange);
+    _stream = _controller.stream;
+    // Throw an ArgumentError if any field is invalid.  After this, all
+    // errors will be reported through the future or the stream.
+    _secureFilter.init();
+    _secureFilter
+        .registerHandshakeCompleteCallback(_secureHandshakeCompleteHandler);
+    if (onBadCertificate != null) {
+      _secureFilter.registerBadCertificateCallback(_onBadCertificateWrapper);
+    }
+    _socket.readEventsEnabled = true;
+    _socket.writeEventsEnabled = false;
+    if (_socketSubscription == null) {
+      // If a current subscription is provided use this otherwise
+      // create a new one.
+      _socketSubscription = _socket.listen(_eventDispatcher,
+          onError: _reportError, onDone: _doneHandler);
+    } else {
+      if (_socketSubscription.isPaused) {
+        _socket.close();
+        throw new ArgumentError("Subscription passed to TLS upgrade is paused");
+      }
+      // If we are upgrading a socket that is already closed for read,
+      // report an error as if we received readClosed during the handshake.
+      dynamic s = _socket; // Cast to dynamic to avoid warning.
+      if (s._socket.closedReadEventSent) {
+        _eventDispatcher(RawSocketEvent.readClosed);
+      }
+      _socketSubscription
+        ..onData(_eventDispatcher)
+        ..onError(_reportError)
+        ..onDone(_doneHandler);
+    }
+    try {
+      var encodedProtocols =
+          SecurityContext._protocolsToLengthEncoding(supportedProtocols);
+      _secureFilter.connect(
+          address.host,
+          context,
+          is_server,
+          requestClientCertificate || requireClientCertificate,
+          requireClientCertificate,
+          encodedProtocols);
+      _secureHandshake();
+    } catch (e, s) {
+      _reportError(e, s);
+    }
+  }
+
+  StreamSubscription<RawSocketEvent> listen(void onData(RawSocketEvent data),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    _sendWriteEvent();
+    return _stream.listen(onData,
+        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+  }
+
+  static void _verifyFields(
+      host,
+      int requestedPort,
+      bool is_server,
+      bool requestClientCertificate,
+      bool requireClientCertificate,
+      Function onBadCertificate) {
+    if (host is! String && host is! InternetAddress) {
+      throw new ArgumentError("host is not a String or an InternetAddress");
+    }
+    ArgumentError.checkNotNull(requestedPort, "requestedPort");
+    if (requestedPort < 0 || requestedPort > 65535) {
+      throw ArgumentError("requestedPort is not in the range 0..65535");
+    }
+    ArgumentError.checkNotNull(
+        requestClientCertificate, "requestClientCertificate");
+    ArgumentError.checkNotNull(
+        requireClientCertificate, "requireClientCertificate");
+  }
+
+  int get port => _socket.port;
+
+  InternetAddress get remoteAddress => _socket.remoteAddress;
+
+  int get remotePort => _socket.remotePort;
+
+  void set _owner(owner) {
+    (_socket as dynamic)._owner = owner;
+  }
+
+  int available() {
+    return _status != connectedStatus
+        ? 0
+        : _secureFilter.buffers[readPlaintextId].length;
+  }
+
+  Future<RawSecureSocket> close() {
+    shutdown(SocketDirection.both);
+    return _closeCompleter.future;
+  }
+
+  void _completeCloseCompleter([RawSocket dummy]) {
+    if (!_closeCompleter.isCompleted) _closeCompleter.complete(this);
+  }
+
+  void _close() {
+    _closedWrite = true;
+    _closedRead = true;
+    if (_socket != null) {
+      _socket.close().then(_completeCloseCompleter);
+    } else {
+      _completeCloseCompleter();
+    }
+    _socketClosedWrite = true;
+    _socketClosedRead = true;
+    if (!_filterActive && _secureFilter != null) {
+      _secureFilter.destroy();
+      _secureFilter = null;
+    }
+    if (_socketSubscription != null) {
+      _socketSubscription.cancel();
+    }
+    _controller.close();
+    _status = closedStatus;
+  }
+
+  void shutdown(SocketDirection direction) {
+    if (direction == SocketDirection.send ||
+        direction == SocketDirection.both) {
+      _closedWrite = true;
+      if (_filterStatus.writeEmpty) {
+        _socket.shutdown(SocketDirection.send);
+        _socketClosedWrite = true;
+        if (_closedRead) {
+          _close();
+        }
+      }
+    }
+    if (direction == SocketDirection.receive ||
+        direction == SocketDirection.both) {
+      _closedRead = true;
+      _socketClosedRead = true;
+      _socket.shutdown(SocketDirection.receive);
+      if (_socketClosedWrite) {
+        _close();
+      }
+    }
+  }
+
+  bool get writeEventsEnabled => _writeEventsEnabled;
+
+  void set writeEventsEnabled(bool value) {
+    _writeEventsEnabled = value;
+    if (value) {
+      Timer.run(() => _sendWriteEvent());
+    }
+  }
+
+  bool get readEventsEnabled => _readEventsEnabled;
+
+  void set readEventsEnabled(bool value) {
+    _readEventsEnabled = value;
+    _scheduleReadEvent();
+  }
+
+  Uint8List 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 != connectedStatus) {
+      return null;
+    }
+    var result = _secureFilter.buffers[readPlaintextId].read(length);
+    _scheduleFilter();
+    return result;
+  }
+
+  // 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 != connectedStatus) return 0;
+    offset ??= 0;
+    bytes ??= data.length - offset;
+
+    int written =
+        _secureFilter.buffers[writePlaintextId].write(data, offset, bytes);
+    if (written > 0) {
+      _filterStatus.writeEmpty = false;
+    }
+    _scheduleFilter();
+    return written;
+  }
+
+  X509Certificate get peerCertificate => _secureFilter.peerCertificate;
+
+  String get selectedProtocol => _selectedProtocol;
+
+  bool _onBadCertificateWrapper(X509Certificate certificate) {
+    if (onBadCertificate == null) return false;
+    var result = onBadCertificate(certificate);
+    if (result is bool) return result;
+    throw new HandshakeException(
+        "onBadCertificate callback returned non-boolean $result");
+  }
+
+  bool setOption(SocketOption option, bool enabled) {
+    if (_socket == null) return false;
+    return _socket.setOption(option, enabled);
+  }
+
+  Uint8List getRawOption(RawSocketOption option) {
+    return _socket?.getRawOption(option);
+  }
+
+  void setRawOption(RawSocketOption option) {
+    _socket?.setRawOption(option);
+  }
+
+  void _eventDispatcher(RawSocketEvent event) {
+    try {
+      if (event == RawSocketEvent.read) {
+        _readHandler();
+      } else if (event == RawSocketEvent.write) {
+        _writeHandler();
+      } else if (event == RawSocketEvent.readClosed) {
+        _closeHandler();
+      }
+    } catch (e, stackTrace) {
+      _reportError(e, stackTrace);
+    }
+  }
+
+  void _readHandler() {
+    _readSocket();
+    _scheduleFilter();
+  }
+
+  void _writeHandler() {
+    _writeSocket();
+    _scheduleFilter();
+  }
+
+  void _doneHandler() {
+    if (_filterStatus.readEmpty) {
+      _close();
+    }
+  }
+
+  void _reportError(e, [StackTrace stackTrace]) {
+    if (_status == closedStatus) {
+      return;
+    } else if (_connectPending) {
+      // _connectPending is true until the handshake has completed, and the
+      // _handshakeComplete future returned from SecureSocket.connect has
+      // completed.  Before this point, we must complete it with an error.
+      _handshakeComplete.completeError(e, stackTrace);
+    } else {
+      _controller.addError(e, stackTrace);
+    }
+    _close();
+  }
+
+  void _closeHandler() {
+    if (_status == connectedStatus) {
+      if (_closedRead) return;
+      _socketClosedRead = true;
+      if (_filterStatus.readEmpty) {
+        _closedRead = true;
+        _controller.add(RawSocketEvent.readClosed);
+        if (_socketClosedWrite) {
+          _close();
+        }
+      } else {
+        _scheduleFilter();
+      }
+    } else if (_status == handshakeStatus) {
+      _socketClosedRead = true;
+      if (_filterStatus.readEmpty) {
+        _reportError(
+            new HandshakeException('Connection terminated during handshake'),
+            null);
+      } else {
+        _secureHandshake();
+      }
+    }
+  }
+
+  void _secureHandshake() {
+    try {
+      _secureFilter.handshake();
+      _filterStatus.writeEmpty = false;
+      _readSocket();
+      _writeSocket();
+      _scheduleFilter();
+    } catch (e, stackTrace) {
+      _reportError(e, stackTrace);
+    }
+  }
+
+  void renegotiate(
+      {bool useSessionCache: true,
+      bool requestClientCertificate: false,
+      bool requireClientCertificate: false}) {
+    if (_status != connectedStatus) {
+      throw new HandshakeException(
+          "Called renegotiate on a non-connected socket");
+    }
+    _secureFilter.renegotiate(
+        useSessionCache, requestClientCertificate, requireClientCertificate);
+    _status = handshakeStatus;
+    _filterStatus.writeEmpty = false;
+    _scheduleFilter();
+  }
+
+  void _secureHandshakeCompleteHandler() {
+    _status = connectedStatus;
+    if (_connectPending) {
+      _connectPending = false;
+      try {
+        _selectedProtocol = _secureFilter.selectedProtocol();
+        // We don't want user code to run synchronously in this callback.
+        Timer.run(() => _handshakeComplete.complete(this));
+      } catch (error, stack) {
+        _handshakeComplete.completeError(error, stack);
+      }
+    }
+  }
+
+  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();
+      } else {
+        _socketSubscription.resume();
+      }
+    }
+  }
+
+  void _onSubscriptionStateChange() {
+    if (_controller.hasListener) {
+      // TODO(ajohnsen): Do something here?
+    }
+  }
+
+  void _scheduleFilter() {
+    _filterPending = true;
+    _tryFilter();
+  }
+
+  void _tryFilter() {
+    if (_status == closedStatus) {
+      return;
+    }
+    if (_filterPending && !_filterActive) {
+      _filterActive = true;
+      _filterPending = false;
+      _pushAllFilterStages().then((status) {
+        _filterStatus = status;
+        _filterActive = false;
+        if (_status == closedStatus) {
+          _secureFilter.destroy();
+          _secureFilter = null;
+          return;
+        }
+        _socket.readEventsEnabled = true;
+        if (_filterStatus.writeEmpty && _closedWrite && !_socketClosedWrite) {
+          // Checks for and handles all cases of partially closed sockets.
+          shutdown(SocketDirection.send);
+          if (_status == closedStatus) {
+            return;
+          }
+        }
+        if (_filterStatus.readEmpty && _socketClosedRead && !_closedRead) {
+          if (_status == handshakeStatus) {
+            _secureFilter.handshake();
+            if (_status == handshakeStatus) {
+              throw new HandshakeException(
+                  'Connection terminated during handshake');
+            }
+          }
+          _closeHandler();
+        }
+        if (_status == closedStatus) {
+          return;
+        }
+        if (_filterStatus.progress) {
+          _filterPending = true;
+          if (_filterStatus.writeEncryptedNoLongerEmpty) {
+            _writeSocket();
+          }
+          if (_filterStatus.writePlaintextNoLongerFull) {
+            _sendWriteEvent();
+          }
+          if (_filterStatus.readEncryptedNoLongerFull) {
+            _readSocket();
+          }
+          if (_filterStatus.readPlaintextNoLongerEmpty) {
+            _scheduleReadEvent();
+          }
+          if (_status == handshakeStatus) {
+            _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 == closedStatus) return;
+    var buffer = _secureFilter.buffers[readEncryptedId];
+    if (buffer.writeFromSource(_readSocketOrBufferedData) > 0) {
+      _filterStatus.readEmpty = false;
+    } else {
+      _socket.readEventsEnabled = false;
+    }
+  }
+
+  void _writeSocket() {
+    if (_socketClosedWrite) return;
+    var buffer = _secureFilter.buffers[writeEncryptedId];
+    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[readPlaintextId].isEmpty) {
+      _pendingReadEvent = true;
+      Timer.run(_sendReadEvent);
+    }
+  }
+
+  _sendReadEvent() {
+    _pendingReadEvent = false;
+    if (_status != closedStatus &&
+        _readEventsEnabled &&
+        _pauseCount == 0 &&
+        _secureFilter != null &&
+        !_secureFilter.buffers[readPlaintextId].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[writePlaintextId].free > 0) {
+      _writeEventsEnabled = false;
+      _controller.add(RawSocketEvent.write);
+    }
+  }
+
+  Future<_FilterStatus> _pushAllFilterStages() {
+    bool wasInHandshake = _status != connectedStatus;
+    List args = new List(2 + bufferCount * 2);
+    args[0] = _secureFilter._pointer();
+    args[1] = wasInHandshake;
+    var bufs = _secureFilter.buffers;
+    for (var i = 0; i < bufferCount; ++i) {
+      args[2 * i + 2] = bufs[i].start;
+      args[2 * i + 3] = bufs[i].end;
+    }
+
+    return _IOService._dispatch(_IOService.sslProcessFilter, args)
+        .then((response) {
+      if (response.length == 2) {
+        if (wasInHandshake) {
+          // If we're in handshake, throw a handshake error.
+          _reportError(
+              new HandshakeException('${response[1]} error ${response[0]}'),
+              null);
+        } else {
+          // If we're connected, throw a TLS error.
+          _reportError(
+              new TlsException('${response[1]} error ${response[0]}'), null);
+        }
+      }
+      int start(int index) => response[2 * index];
+      int end(int index) => response[2 * index + 1];
+
+      _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[writePlaintextId].isEmpty &&
+          start(writeEncryptedId) == end(writeEncryptedId);
+      // 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[readEncryptedId].isEmpty &&
+          start(readPlaintextId) == end(readPlaintextId);
+
+      _ExternalBuffer buffer = bufs[writePlaintextId];
+      int new_start = start(writePlaintextId);
+      if (new_start != buffer.start) {
+        status.progress = true;
+        if (buffer.free == 0) {
+          status.writePlaintextNoLongerFull = true;
+        }
+        buffer.start = new_start;
+      }
+      buffer = bufs[readEncryptedId];
+      new_start = start(readEncryptedId);
+      if (new_start != buffer.start) {
+        status.progress = true;
+        if (buffer.free == 0) {
+          status.readEncryptedNoLongerFull = true;
+        }
+        buffer.start = new_start;
+      }
+      buffer = bufs[writeEncryptedId];
+      int new_end = end(writeEncryptedId);
+      if (new_end != buffer.end) {
+        status.progress = true;
+        if (buffer.length == 0) {
+          status.writeEncryptedNoLongerEmpty = true;
+        }
+        buffer.end = new_end;
+      }
+      buffer = bufs[readPlaintextId];
+      new_end = end(readPlaintextId);
+      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 {
+  // This will be an ExternalByteArray, backed by C allocated data.
+  @pragma("vm:entry-point", "set")
+  List<int> data;
+
+  @pragma("vm:entry-point")
+  int start;
+
+  @pragma("vm:entry-point")
+  int end;
+
+  final size;
+
+  _ExternalBuffer(this.size) {
+    start = end = size ~/ 2;
+  }
+
+  void advanceStart(int bytes) {
+    assert(start > end || start + bytes <= end);
+    start += bytes;
+    if (start >= size) {
+      start -= size;
+      assert(start <= end);
+      assert(start < size);
+    }
+  }
+
+  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 => start > end ? size + end - start : end - start;
+
+  int get linearLength => start > end ? size - start : end - start;
+
+  int get free => start > end ? start - end - 1 : size + start - end - 1;
+
+  int get linearFree {
+    if (start > end) return start - end - 1;
+    if (start == 0) return size - end - 1;
+    return size - end;
+  }
+
+  Uint8List read(int bytes) {
+    if (bytes == null) {
+      bytes = length;
+    } else {
+      bytes = min(bytes, length);
+    }
+    if (bytes == 0) return null;
+    Uint8List result = new Uint8List(bytes);
+    int bytesRead = 0;
+    // Loop over zero, one, or two linear data ranges.
+    while (bytesRead < bytes) {
+      int toRead = min(bytes - bytesRead, 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 || inputData.length == 0) 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;
+      }
+    }
+  }
+}
+
+abstract class _SecureFilter {
+  external factory _SecureFilter._();
+
+  void connect(
+      String hostName,
+      SecurityContext context,
+      bool is_server,
+      bool requestClientCertificate,
+      bool requireClientCertificate,
+      Uint8List protocols);
+  void destroy();
+  void handshake();
+  String selectedProtocol();
+  void rehandshake();
+  void renegotiate(bool useSessionCache, bool requestClientCertificate,
+      bool requireClientCertificate);
+  void init();
+  X509Certificate get peerCertificate;
+  int processBuffer(int bufferIndex);
+  void registerBadCertificateCallback(Function callback);
+  void registerHandshakeCompleteCallback(Function handshakeCompleteHandler);
+
+  // This call may cause a reference counted pointer in the native
+  // implementation to be retained. It should only be called when the resulting
+  // value is passed to the IO service through a call to dispatch().
+  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;
+
+  @pragma("vm:entry-point")
+  const TlsException([String message = "", OSError osError])
+      : this._("TlsException", message, osError);
+
+  const TlsException._(this.type, this.message, this.osError);
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write(type);
+    if (message.isNotEmpty) {
+      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.
+ */
+@pragma("vm:entry-point")
+class HandshakeException extends TlsException {
+  @pragma("vm:entry-point")
+  const HandshakeException([String message = "", OSError osError])
+      : 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 {
+  @pragma("vm:entry-point")
+  const CertificateException([String message = "", OSError osError])
+      : super._("CertificateException", message, osError);
+}
diff --git a/sdk_nnbd/lib/io/security_context.dart b/sdk_nnbd/lib/io/security_context.dart
new file mode 100644
index 0000000..96da93b
--- /dev/null
+++ b/sdk_nnbd/lib/io/security_context.dart
@@ -0,0 +1,283 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.io;
+
+/**
+ * The object containing the certificates to trust when making
+ * a secure client connection, and the certificate chain and
+ * private key to serve from a secure server.
+ *
+ * The [SecureSocket]  and [SecureServerSocket] classes take a SecurityContext
+ * as an argument to their connect and bind methods.
+ *
+ * Certificates and keys can be added to a SecurityContext from either PEM
+ * or PKCS12 containers.
+ *
+ * iOS note: Some methods to add, remove, and inspect certificates are not yet
+ * implemented. However, the platform's built-in trusted certificates can
+ * be used, by way of [SecurityContext.defaultContext].
+ */
+abstract class SecurityContext {
+  /**
+   * Creates a new [SecurityContext].
+   *
+   * By default, the created [SecurityContext] contains no keys or certificates.
+   * These can be added by calling the methods of this class.
+   *
+   * If `withTrustedRoots` is passed as `true`, the [SecurityContext] will be
+   * seeded by the trusted root certificates provided as explained below. To
+   * obtain a [SecurityContext] containing trusted root certificates,
+   * [SecurityContext.defaultContext] is usually sufficient, and should
+   * be used instead. However, if the [SecurityContext] containing the trusted
+   * root certificates must be modified per-connection, then `withTrustedRoots`
+   * should be used.
+   */
+  external factory SecurityContext({bool withTrustedRoots: false});
+
+  /**
+   * Secure networking classes with an optional `context` parameter
+   * use the [defaultContext] object if the parameter is omitted.
+   * This object can also be accessed, and modified, directly.
+   * Each isolate has a different [defaultContext] object.
+   * The [defaultContext] object uses a list of well-known trusted
+   * certificate authorities as its trusted roots. On Linux and Windows, this
+   * list is taken from Mozilla, who maintains it as part of Firefox. On,
+   * MacOS, iOS, and Android, this list comes from the trusted certificates
+   * stores built in to the platforms.
+   */
+  external static SecurityContext get defaultContext;
+
+  /**
+   * Sets the private key for a server certificate or client certificate.
+   *
+   * A secure connection using this SecurityContext will use this key with
+   * the server or client certificate to sign and decrypt messages.
+   * [file] is the path to a PEM or PKCS12 file containing an encrypted
+   * private key, encrypted with [password]. Assuming it is well-formatted, all
+   * other contents of [file] are ignored. An unencrypted file can be used,
+   * but this is not usual.
+   *
+   * NB: This function calls [File.readAsBytesSync], and will block on file IO.
+   * Prefer using [usePrivateKeyBytes].
+   *
+   * iOS note: Only PKCS12 data is supported. It should contain both the private
+   * key and the certificate chain. On iOS one call to [usePrivateKey] with this
+   * data is used instead of two calls to [useCertificateChain] and
+   * [usePrivateKey].
+   */
+  void usePrivateKey(String file, {String password});
+
+  /**
+   * Sets the private key for a server certificate or client certificate.
+   *
+   * Like [usePrivateKey], but takes the contents of the file as a list
+   * of bytes.
+   */
+  void usePrivateKeyBytes(List<int> keyBytes, {String password});
+
+  /**
+   * Sets the set of trusted X509 certificates used by [SecureSocket]
+   * client connections, when connecting to a secure server.
+   *
+   * [file] is the path to a PEM or PKCS12 file containing X509 certificates,
+   * usually root certificates from certificate authorities. For PKCS12 files,
+   * [password] is the password for the file. For PEM files, [password] is
+   * ignored. Assuming it is well-formatted, all other contents of [file] are
+   * ignored.
+   *
+   * NB: This function calls [File.readAsBytesSync], and will block on file IO.
+   * Prefer using [setTrustedCertificatesBytes].
+   *
+   * iOS note: On iOS, this call takes only the bytes for a single DER
+   * encoded X509 certificate. It may be called multiple times to add
+   * multiple trusted certificates to the context. A DER encoded certificate
+   * can be obtained from a PEM encoded certificate by using the openssl tool:
+   *
+   *   $ openssl x509 -outform der -in cert.pem -out cert.der
+   */
+  void setTrustedCertificates(String file, {String password});
+
+  /**
+   * Sets the set of trusted X509 certificates used by [SecureSocket]
+   * client connections, when connecting to a secure server.
+   *
+   * Like [setTrustedCertificates] but takes the contents of the file.
+   */
+  void setTrustedCertificatesBytes(List<int> certBytes, {String password});
+
+  /**
+   * Sets the chain of X509 certificates served by [SecureServerSocket]
+   * when making secure connections, including the server certificate.
+   *
+   * [file] is a PEM or PKCS12 file containing X509 certificates, starting with
+   * the root authority and intermediate authorities forming the signed
+   * chain to the server certificate, and ending with the server certificate.
+   * The private key for the server certificate is set by [usePrivateKey]. For
+   * PKCS12 files, [password] is the password for the file. For PEM files,
+   * [password] is ignored. Assuming it is well-formatted, all
+   * other contents of [file] are ignored.
+   *
+   * NB: This function calls [File.readAsBytesSync], and will block on file IO.
+   * Prefer using [useCertificateChainBytes].
+   *
+   * iOS note: As noted above, [usePrivateKey] does the job of both
+   * that call and this one. On iOS, this call is a no-op.
+   */
+  void useCertificateChain(String file, {String password});
+
+  /**
+   * Sets the chain of X509 certificates served by [SecureServerSocket]
+   * when making secure connections, including the server certificate.
+   *
+   * Like [useCertificateChain] but takes the contents of the file.
+   */
+  void useCertificateChainBytes(List<int> chainBytes, {String password});
+
+  /**
+   * Sets the list of authority names that a [SecureServerSocket] will advertise
+   * as accepted when requesting a client certificate from a connecting
+   * client.
+   *
+   * [file] is a PEM or PKCS12 file containing the accepted signing
+   * authority certificates - the authority names are extracted from the
+   * certificates. For PKCS12 files, [password] is the password for the file.
+   * For PEM files, [password] is ignored. Assuming it is well-formatted, all
+   * other contents of [file] are ignored.
+   *
+   * NB: This function calls [File.readAsBytesSync], and will block on file IO.
+   * Prefer using [setClientAuthoritiesBytes].
+   *
+   * iOS note: This call is not supported.
+   */
+  void setClientAuthorities(String file, {String password});
+
+  /**
+   * Sets the list of authority names that a [SecureServerSocket] will advertise
+   * as accepted, when requesting a client certificate from a connecting
+   * client.
+   *
+   * Like [setClientAuthorities] but takes the contents of the file.
+   */
+  void setClientAuthoritiesBytes(List<int> authCertBytes, {String password});
+
+  /**
+   * Whether the platform supports ALPN. This always returns true and will be
+   * removed in a future release.
+   */
+  @deprecated
+  external static bool get alpnSupported;
+
+  /**
+   * Sets the list of application-level protocols supported by a client
+   * connection or server connection. The ALPN (application level protocol
+   * negotiation) extension to TLS allows a client to send a list of
+   * protocols in the TLS client hello message, and the server to pick
+   * one and send the selected one back in its server hello message.
+   *
+   * Separate lists of protocols can be sent for client connections and
+   * for server connections, using the same SecurityContext.  The [isServer]
+   * boolean argument specifies whether to set the list for server connections
+   * or client connections.
+   */
+  void setAlpnProtocols(List<String> protocols, bool isServer);
+
+  /// Encodes a set of supported protocols for ALPN/NPN usage.
+  ///
+  /// The `protocols` list is expected to contain protocols in descending order
+  /// of preference.
+  ///
+  /// See RFC 7301 (https://tools.ietf.org/html/rfc7301) for the encoding of
+  /// `List<String> protocols`:
+  ///     opaque ProtocolName<1..2^8-1>;
+  ///
+  ///     struct {
+  ///         ProtocolName protocol_name_list<2..2^16-1>
+  ///     } ProtocolNameList;
+  ///
+  /// The encoding of the opaque `ProtocolName<lower..upper>` vector is
+  /// described in RFC 2246: 4.3 Vectors.
+  ///
+  /// Note: Even though this encoding scheme would allow a total
+  /// `ProtocolNameList` length of 65535, this limit cannot be reached. Testing
+  /// showed that more than ~ 2^14  bytes will fail to negotiate a protocol.
+  /// We will be conservative and support only messages up to (1<<13)-1 bytes.
+  static Uint8List _protocolsToLengthEncoding(List<String> protocols) {
+    if (protocols == null || protocols.length == 0) {
+      return new Uint8List(0);
+    }
+    int protocolsLength = protocols.length;
+
+    // Calculate the number of bytes we will need if it is ASCII.
+    int expectedLength = protocolsLength;
+    for (int i = 0; i < protocolsLength; i++) {
+      int length = protocols[i].length;
+      if (length > 0 && length <= 255) {
+        expectedLength += length;
+      } else {
+        throw new ArgumentError(
+            'Length of protocol must be between 1 and 255 (was: $length).');
+      }
+    }
+
+    if (expectedLength >= (1 << 13)) {
+      throw new ArgumentError(
+          'The maximum message length supported is 2^13-1.');
+    }
+
+    // Try encoding the `List<String> protocols` array using fast ASCII path.
+    var bytes = new Uint8List(expectedLength);
+    int bytesOffset = 0;
+    for (int i = 0; i < protocolsLength; i++) {
+      String proto = protocols[i];
+
+      // Add length byte.
+      bytes[bytesOffset++] = proto.length;
+      int bits = 0;
+
+      // Add protocol bytes.
+      for (int j = 0; j < proto.length; j++) {
+        var char = proto.codeUnitAt(j);
+        bits |= char;
+        bytes[bytesOffset++] = char & 0xff;
+      }
+
+      // Go slow case if we have encountered anything non-ascii.
+      if (bits > 0x7f) {
+        return _protocolsToLengthEncodingNonAsciiBailout(protocols);
+      }
+    }
+    return bytes;
+  }
+
+  static Uint8List _protocolsToLengthEncodingNonAsciiBailout(
+      List<String> protocols) {
+    void addProtocol(List<int> outBytes, String protocol) {
+      var protocolBytes = utf8.encode(protocol);
+      var len = protocolBytes.length;
+
+      if (len > 255) {
+        throw new ArgumentError(
+            'Length of protocol must be between 1 and 255 (was: $len)');
+      }
+      // Add length byte.
+      outBytes.add(len);
+
+      // Add protocol bytes.
+      outBytes.addAll(protocolBytes);
+    }
+
+    List<int> bytes = [];
+    for (var i = 0; i < protocols.length; i++) {
+      addProtocol(bytes, protocols[i]);
+    }
+
+    if (bytes.length >= (1 << 13)) {
+      throw new ArgumentError(
+          'The maximum message length supported is 2^13-1.');
+    }
+
+    return new Uint8List.fromList(bytes);
+  }
+}
diff --git a/sdk_nnbd/lib/io/service_object.dart b/sdk_nnbd/lib/io/service_object.dart
new file mode 100644
index 0000000..e6b1851
--- /dev/null
+++ b/sdk_nnbd/lib/io/service_object.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.io;
+
+int _nextServiceId = 1;
+
+// TODO(ajohnsen): Use other way of getting a unique id.
+abstract class _ServiceObject {
+  int __serviceId = 0;
+  int get _serviceId {
+    if (__serviceId == 0) __serviceId = _nextServiceId++;
+    return __serviceId;
+  }
+
+  Map _toJSON(bool ref);
+
+  String get _servicePath => "$_serviceTypePath/$_serviceId";
+
+  String get _serviceTypePath;
+
+  String get _serviceTypeName;
+
+  String _serviceType(bool ref) {
+    if (ref) return "@$_serviceTypeName";
+    return _serviceTypeName;
+  }
+}
diff --git a/sdk_nnbd/lib/io/socket.dart b/sdk_nnbd/lib/io/socket.dart
new file mode 100644
index 0000000..df60490
--- /dev/null
+++ b/sdk_nnbd/lib/io/socket.dart
@@ -0,0 +1,1013 @@
+// 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 dart.io;
+
+/**
+ * [InternetAddressType] is the type an [InternetAddress]. Currently,
+ * IP version 4 (IPv4) and IP version 6 (IPv6) are supported.
+ */
+class InternetAddressType {
+  static const InternetAddressType IPv4 = const InternetAddressType._(0);
+  static const InternetAddressType IPv6 = const InternetAddressType._(1);
+  static const InternetAddressType any = const InternetAddressType._(-1);
+
+  @Deprecated("Use IPv4 instead")
+  static const InternetAddressType IP_V4 = IPv4;
+  @Deprecated("Use IPv6 instead")
+  static const InternetAddressType IP_V6 = IPv6;
+  @Deprecated("Use any instead")
+  static const InternetAddressType ANY = any;
+
+  final int _value;
+
+  const InternetAddressType._(this._value);
+
+  factory InternetAddressType._from(int value) {
+    if (value == 0) return IPv4;
+    if (value == 1) return IPv6;
+    throw new ArgumentError("Invalid type: $value");
+  }
+
+  /**
+   * Get the name of the type, e.g. "IPv4" or "IPv6".
+   */
+  String get name {
+    switch (_value) {
+      case -1:
+        return "ANY";
+      case 0:
+        return "IPv4";
+      case 1:
+        return "IPv6";
+      default:
+        throw new ArgumentError("Invalid InternetAddress");
+    }
+  }
+
+  String toString() => "InternetAddressType: $name";
+}
+
+/**
+ * An internet address.
+ *
+ * This object holds an internet address. If this internet address
+ * is the result of a DNS lookup, the address also holds the hostname
+ * used to make the lookup.
+ * An Internet address combined with a port number represents an
+ * endpoint to which a socket can connect or a listening socket can
+ * bind.
+ */
+abstract class InternetAddress {
+  /**
+   * IP version 4 loopback address. Use this address when listening on
+   * or connecting to the loopback adapter using IP version 4 (IPv4).
+   */
+  static InternetAddress get loopbackIPv4 => LOOPBACK_IP_V4;
+  @Deprecated("Use loopbackIPv4 instead")
+  external static InternetAddress get LOOPBACK_IP_V4;
+
+  /**
+   * IP version 6 loopback address. Use this address when listening on
+   * or connecting to the loopback adapter using IP version 6 (IPv6).
+   */
+  static InternetAddress get loopbackIPv6 => LOOPBACK_IP_V6;
+  @Deprecated("Use loopbackIPv6 instead")
+  external static InternetAddress get LOOPBACK_IP_V6;
+
+  /**
+   * IP version 4 any address. Use this address when listening on
+   * all adapters IP addresses using IP version 4 (IPv4).
+   */
+  static InternetAddress get anyIPv4 => ANY_IP_V4;
+  @Deprecated("Use anyIPv4 instead")
+  external static InternetAddress get ANY_IP_V4;
+
+  /**
+   * IP version 6 any address. Use this address when listening on
+   * all adapters IP addresses using IP version 6 (IPv6).
+   */
+  static InternetAddress get anyIPv6 => ANY_IP_V6;
+  @Deprecated("Use anyIPv6 instead")
+  external static InternetAddress get ANY_IP_V6;
+
+  /**
+   * The [type] of the [InternetAddress] specified what IP protocol.
+   */
+  InternetAddressType get type;
+
+  /**
+   * The numeric address of the host. For IPv4 addresses this is using
+   * the dotted-decimal notation. For IPv6 it is using the
+   * hexadecimal representation.
+   */
+  String get address;
+
+  /**
+   * The host used to lookup the address. If there is no host
+   * associated with the address this returns the numeric address.
+   */
+  String get host;
+
+  /**
+   * Get the raw address of this [InternetAddress]. The result is either a
+   * 4 or 16 byte long list. The returned list is a copy, making it possible
+   * to change the list without modifying the [InternetAddress].
+   */
+  Uint8List get rawAddress;
+
+  /**
+   * 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;
+
+  /**
+   * Returns true if the [InternetAddress]s scope is multicast.
+   */
+  bool get isMulticast;
+
+  /**
+   * Creates a new [InternetAddress] from a numeric address.
+   *
+   * If the address in [address] is not a numeric IPv4
+   * (dotted-decimal notation) or IPv6 (hexadecimal representation).
+   * address [ArgumentError] is thrown.
+   */
+  external factory InternetAddress(String address);
+
+  /**
+   * 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)
+   * addresses. If [type] is either [InternetAddressType.IPv4] or
+   * [InternetAddressType.IPv6] it will only lookup addresses of the
+   * specified type. The order of the list can, and most likely will,
+   * change over time.
+   */
+  external static Future<List<InternetAddress>> lookup(String host,
+      {InternetAddressType type: InternetAddressType.any});
+
+  /**
+   * Clones the given [address] with the new [host].
+   *
+   * The [address] must be an [InternetAddress] that was created with one
+   * of the static methods of this class.
+   */
+  external static InternetAddress _cloneWithNewHost(
+      InternetAddress address, String host);
+}
+
+/**
+ * A [NetworkInterface] represents an active network interface on the current
+ * system. It contains a list of [InternetAddress]es that are bound to the
+ * interface.
+ */
+abstract class NetworkInterface {
+  /**
+   * Get the name of the [NetworkInterface].
+   */
+  String get name;
+
+  /**
+   * Get the index of the [NetworkInterface].
+   */
+  int get index;
+
+  /**
+   * Get a list of [InternetAddress]es currently bound to this
+   * [NetworkInterface].
+   */
+  List<InternetAddress> get addresses;
+
+  /**
+   * Whether [list] is supported.
+   *
+   * [list] is currently unsupported on Android.
+   */
+  external static bool get listSupported;
+
+  /**
+   * 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.IPv4] or
+   * [InternetAddressType.IPv6] 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
+ * made to the listening socket.
+ *
+ * See [RawSocket] for more info.
+ */
+abstract class RawServerSocket implements Stream<RawSocket> {
+  /**
+   * Returns a future for a [:RawServerSocket:]. When the future
+   * completes the server socket is bound to the given [address] and
+   * [port] and has started listening on it.
+   *
+   * The [address] can either be a [String] or an
+   * [InternetAddress]. If [address] is a [String], [bind] will
+   * perform a [InternetAddress.lookup] and use the first value in the
+   * list. To listen on the loopback adapter, which will allow only
+   * incoming connections from the local host, use the value
+   * [InternetAddress.loopbackIPv4] or
+   * [InternetAddress.loopbackIPv6]. To allow for incoming
+   * connection from the network use either one of the values
+   * [InternetAddress.anyIPv4] or [InternetAddress.anyIPv6] to
+   * bind to all interfaces or the IP address of a specific interface.
+   *
+   * If an IP version 6 (IPv6) address is used, both IP version 6
+   * (IPv6) and version 4 (IPv4) connections will be accepted. To
+   * restrict this to version 6 (IPv6) only, use [v6Only] to set
+   * version 6 only.
+   *
+   * If [port] has the value [:0:] an ephemeral port will
+   * be chosen by the system. The actual port used can be retrieved
+   * using the [:port:] getter.
+   *
+   * The optional argument [backlog] can be used to specify the listen
+   * backlog for the underlying OS listen setup. If [backlog] has the
+   * value of [:0:] (the default) a reasonable value will be chosen by
+   * the system.
+   *
+   * The optional argument [shared] specifies whether additional RawServerSocket
+   * objects can bind to the same combination of `address`, `port` and `v6Only`.
+   * If `shared` is `true` and more `RawServerSocket`s from this isolate or
+   * other isolates are bound to the port, then the incoming connections will be
+   * distributed among all the bound `RawServerSocket`s. Connections can be
+   * distributed over multiple isolates this way.
+   */
+  external static Future<RawServerSocket> bind(address, int port,
+      {int backlog: 0, bool v6Only: false, bool shared: false});
+
+  /**
+   * Returns the port used by this socket.
+   */
+  int get port;
+
+  /**
+   * Returns the address used by this socket.
+   */
+  InternetAddress get address;
+
+  /**
+   * Closes the socket. The returned future completes when the socket
+   * is fully closed and is no longer bound.
+   */
+  Future<RawServerSocket> close();
+}
+
+/**
+ * A [ServerSocket] represents a listening socket, and provides a
+ * stream of [Socket] objects, one for each connection made to the
+ * listening socket.
+ *
+ * See [Socket] for more info.
+ */
+abstract class ServerSocket implements Stream<Socket> {
+  /**
+   * Returns a future for a [:ServerSocket:]. When the future
+   * completes the server socket is bound to the given [address] and
+   * [port] and has started listening on it.
+   *
+   * The [address] can either be a [String] or an
+   * [InternetAddress]. If [address] is a [String], [bind] will
+   * perform a [InternetAddress.lookup] and use the first value in the
+   * list. To listen on the loopback adapter, which will allow only
+   * incoming connections from the local host, use the value
+   * [InternetAddress.loopbackIPv4] or
+   * [InternetAddress.loopbackIPv6]. To allow for incoming
+   * connection from the network use either one of the values
+   * [InternetAddress.anyIPv4] or [InternetAddress.anyIPv6] to
+   * bind to all interfaces or the IP address of a specific interface.
+   *
+   * If an IP version 6 (IPv6) address is used, both IP version 6
+   * (IPv6) and version 4 (IPv4) connections will be accepted. To
+   * restrict this to version 6 (IPv6) only, use [v6Only] to set
+   * version 6 only.
+   *
+   * If [port] has the value [:0:] an ephemeral port will be chosen by
+   * the system. The actual port used can be retrieved using the
+   * [port] getter.
+   *
+   * The optional argument [backlog] can be used to specify the listen
+   * backlog for the underlying OS listen setup. If [backlog] has the
+   * value of [:0:] (the default) a reasonable value will be chosen by
+   * the system.
+   *
+   * The optional argument [shared] specifies whether additional ServerSocket
+   * objects can bind to the same combination of `address`, `port` and `v6Only`.
+   * If `shared` is `true` and more `ServerSocket`s from this isolate or other
+   * isolates are bound to the port, then the incoming connections will be
+   * distributed among all the bound `ServerSocket`s. Connections can be
+   * distributed over multiple isolates this way.
+   */
+  external static Future<ServerSocket> bind(address, int port,
+      {int backlog: 0, bool v6Only: false, bool shared: false});
+
+  /**
+   * Returns the port used by this socket.
+   */
+  int get port;
+
+  /**
+   * Returns the address used by this socket.
+   */
+  InternetAddress get address;
+
+  /**
+   * Closes the socket. The returned future completes when the socket
+   * is fully closed and is no longer bound.
+   */
+  Future<ServerSocket> close();
+}
+
+/**
+ * The [SocketDirection] is used as a parameter to [Socket.close] and
+ * [RawSocket.close] to close a socket in the specified direction(s).
+ */
+class SocketDirection {
+  static const SocketDirection receive = const SocketDirection._(0);
+  static const SocketDirection send = const SocketDirection._(1);
+  static const SocketDirection both = const SocketDirection._(2);
+
+  @Deprecated("Use receive instead")
+  static const SocketDirection RECEIVE = receive;
+  @Deprecated("Use send instead")
+  static const SocketDirection SEND = send;
+  @Deprecated("Use both instead")
+  static const SocketDirection BOTH = both;
+
+  final _value;
+
+  const SocketDirection._(this._value);
+}
+
+/**
+ * The [SocketOption] is used as a parameter to [Socket.setOption] and
+ * [RawSocket.setOption] to set customize the behaviour of the underlying
+ * socket.
+ */
+class SocketOption {
+  /**
+   * Enable or disable no-delay on the socket. If tcpNoDelay is enabled, the
+   * socket will not buffer data internally, but instead write each data chunk
+   * as an individual TCP packet.
+   *
+   * tcpNoDelay is disabled by default.
+   */
+  static const SocketOption tcpNoDelay = const SocketOption._(0);
+  @Deprecated("Use tcpNoDelay instead")
+  static const SocketOption TCP_NODELAY = tcpNoDelay;
+
+  static const SocketOption _ipMulticastLoop = const SocketOption._(1);
+  static const SocketOption _ipMulticastHops = const SocketOption._(2);
+  static const SocketOption _ipMulticastIf = const SocketOption._(3);
+  static const SocketOption _ipBroadcast = const SocketOption._(4);
+
+  final _value;
+
+  const SocketOption._(this._value);
+}
+
+// Must be kept in sync with enum in socket.cc
+enum _RawSocketOptions {
+  SOL_SOCKET, // 0
+  IPPROTO_IP, // 1
+  IP_MULTICAST_IF, // 2
+  IPPROTO_IPV6, // 3
+  IPV6_MULTICAST_IF, // 4
+  IPPROTO_TCP, // 5
+  IPPROTO_UDP, // 6
+}
+
+/// The [RawSocketOption] is used as a parameter to [Socket.setRawOption] and
+/// [RawSocket.setRawOption] to set customize the behaviour of the underlying
+/// socket.
+///
+/// It allows for fine grained control of the socket options, and its values will
+/// be passed to the underlying platform's implementation of setsockopt and
+/// getsockopt.
+@Since("2.2")
+class RawSocketOption {
+  /// Creates a RawSocketOption for getRawOption andSetRawOption.
+  ///
+  /// All arguments are required and must not be null.
+  ///
+  /// The level and option arguments correspond to level and optname arguments
+  /// on the get/setsockopt native calls.
+  ///
+  /// The value argument and its length correspond to the optval and length
+  /// arguments on the native call.
+  ///
+  /// For a [getRawOption] call, the value parameter will be updated after a
+  /// successful call (although its length will not be changed).
+  ///
+  /// For a [setRawOption] call, the value parameter will be used set the
+  /// option.
+  const RawSocketOption(this.level, this.option, this.value);
+
+  /// Convenience constructor for creating an int based RawSocketOption.
+  factory RawSocketOption.fromInt(int level, int option, int value) {
+    if (value == null) {
+      value = 0;
+    }
+    final Uint8List list = Uint8List(4);
+    final buffer = ByteData.view(list.buffer);
+    buffer.setInt32(0, value);
+    return RawSocketOption(level, option, list);
+  }
+
+  /// Convenience constructor for creating a bool based RawSocketOption.
+  factory RawSocketOption.fromBool(int level, int option, bool value) =>
+      RawSocketOption.fromInt(level, option, value == true ? 1 : 0);
+
+  /// The level for the option to set or get.
+  ///
+  /// See also:
+  ///   * [RawSocketOption.levelSocket]
+  ///   * [RawSocketOption.levelIPv4]
+  ///   * [RawSocketOption.levelIPv6]
+  ///   * [RawSocketOption.levelTcp]
+  ///   * [RawSocketOption.levelUdp]
+  final int level;
+
+  /// The option to set or get.
+  final int option;
+
+  /// The raw data to set, or the array to write the current option value into.
+  ///
+  /// This list must be the correct length for the expected option. For most
+  /// options that take int or bool values, the length should be 4. For options
+  /// that expect a struct (such as an in_addr_t), the length should be the
+  /// correct length for that struct.
+  final Uint8List value;
+
+  /// Socket level option for SOL_SOCKET.
+  static int get levelSocket =>
+      _getOptionValue(_RawSocketOptions.SOL_SOCKET.index);
+
+  /// Socket level option for IPPROTO_IP.
+  static int get levelIPv4 =>
+      _getOptionValue(_RawSocketOptions.IPPROTO_IP.index);
+
+  /// Socket option for IP_MULTICAST_IF.
+  static int get IPv4MulticastInterface =>
+      _getOptionValue(_RawSocketOptions.IP_MULTICAST_IF.index);
+
+  /// Socket level option for IPPROTO_IPV6.
+  static int get levelIPv6 =>
+      _getOptionValue(_RawSocketOptions.IPPROTO_IPV6.index);
+
+  /// Socket option for IPV6_MULTICAST_IF.
+  static int get IPv6MulticastInterface =>
+      _getOptionValue(_RawSocketOptions.IPV6_MULTICAST_IF.index);
+
+  /// Socket level option for IPPROTO_TCP.
+  static int get levelTcp =>
+      _getOptionValue(_RawSocketOptions.IPPROTO_TCP.index);
+
+  /// Socket level option for IPPROTO_UDP.
+  static int get levelUdp =>
+      _getOptionValue(_RawSocketOptions.IPPROTO_UDP.index);
+
+  external static int _getOptionValue(int key);
+}
+
+/**
+ * Events for the [RawSocket].
+ */
+class RawSocketEvent {
+  static const RawSocketEvent read = const RawSocketEvent._(0);
+  static const RawSocketEvent write = const RawSocketEvent._(1);
+  static const RawSocketEvent readClosed = const RawSocketEvent._(2);
+  static const RawSocketEvent closed = const RawSocketEvent._(3);
+
+  @Deprecated("Use read instead")
+  static const RawSocketEvent READ = read;
+  @Deprecated("Use write instead")
+  static const RawSocketEvent WRITE = write;
+  @Deprecated("Use readClosed instead")
+  static const RawSocketEvent READ_CLOSED = readClosed;
+  @Deprecated("Use closed instead")
+  static const RawSocketEvent CLOSED = closed;
+
+  final int _value;
+
+  const RawSocketEvent._(this._value);
+  String toString() {
+    return const [
+      'RawSocketEvent.read',
+      'RawSocketEvent.write',
+      'RawSocketEvent.readClosed',
+      'RawSocketEvent.closed'
+    ][_value];
+  }
+}
+
+/// Returned by the `startConnect` methods on client-side socket types `S`,
+/// `ConnectionTask<S>` allows cancelling an attempt to connect to a host.
+class ConnectionTask<S> {
+  /// A `Future` that completes with value that `S.connect()` would return
+  /// unless [cancel] is called on this [ConnectionTask].
+  ///
+  /// If [cancel] is called, the `Future` completes with a [SocketException]
+  /// error whose message indicates that the connection attempt was cancelled.
+  final Future<S> socket;
+  final void Function() _onCancel;
+
+  ConnectionTask._({Future<S> socket, void Function() onCancel})
+      : assert(socket != null),
+        assert(onCancel != null),
+        this.socket = socket,
+        this._onCancel = onCancel;
+
+  /// Cancels the connection attempt.
+  ///
+  /// This also causes the [socket] `Future` to complete with a
+  /// [SocketException] error.
+  void cancel() {
+    _onCancel();
+  }
+}
+
+/**
+ * A [RawSocket] is an unbuffered interface to a TCP socket.
+ *
+ * The raw socket delivers the data stream in the same chunks as the underlying
+ * operating system.
+ *
+ * It is not the same as a
+ * [POSIX raw socket](http://man7.org/linux/man-pages/man7/raw.7.html).
+ */
+abstract class RawSocket implements Stream<RawSocketEvent> {
+  /**
+   * Set or get, if the [RawSocket] should listen for [RawSocketEvent.read]
+   * events. Default is [:true:].
+   */
+  bool readEventsEnabled;
+
+  /**
+   * Set or get, if the [RawSocket] should listen for [RawSocketEvent.write]
+   * events. Default is [:true:].
+   * This is a one-shot listener, and writeEventsEnabled must be set
+   * to true again to receive another write event.
+   */
+  bool writeEventsEnabled;
+
+  /**
+   * Creates a new socket connection to the host and port and returns a [Future]
+   * that will complete with either a [RawSocket] once connected or an error
+   * if the host-lookup or connection failed.
+   *
+   * [host] can either be a [String] or an [InternetAddress]. If [host] is a
+   * [String], [connect] will perform a [InternetAddress.lookup] and try
+   * all returned [InternetAddress]es, until connected. Unless a
+   * connection was established, the error from the first failing connection is
+   * returned.
+   *
+   * The argument [sourceAddress] can be used to specify the local
+   * address to bind when making the connection. `sourceAddress` can either
+   * be a `String` or an `InternetAddress`. If a `String` is passed it must
+   * hold a numeric IP address.
+   *
+   * The argument [timeout] is used to specify the maximum allowed time to wait
+   * for a connection to be established. If [timeout] is longer than the system
+   * level timeout duration, a timeout may occur sooner than specified in
+   * [timeout]. On timeout, a [SocketException] is thrown and all ongoing
+   * connection attempts to [host] are cancelled.
+   */
+  external static Future<RawSocket> connect(host, int port,
+      {sourceAddress, Duration timeout});
+
+  /// Like [connect], but returns a [Future] that completes with a
+  /// [ConnectionTask] that can be cancelled if the [RawSocket] is no
+  /// longer needed.
+  external static Future<ConnectionTask<RawSocket>> startConnect(host, int port,
+      {sourceAddress});
+
+  /**
+   * Returns the number of received and non-read bytes in the socket that
+   * can be read.
+   */
+  int available();
+
+  /**
+   * Read up to [len] bytes from the socket. This function is
+   * non-blocking and will only return data if data is available. The
+   * number of bytes read can be less then [len] if fewer bytes are
+   * available for immediate reading. If no data is available [:null:]
+   * is returned.
+   */
+  Uint8List read([int len]);
+
+  /**
+   * Writes up to [count] bytes of the buffer from [offset] buffer offset to
+   * the socket. The number of successfully written bytes is returned. This
+   * function is non-blocking and will only write data if buffer space is
+   * available in the socket.
+   *
+   * The default value for [offset] is 0, and the default value for [count] is
+   * [:buffer.length - offset:].
+   */
+  int write(List<int> buffer, [int offset, int count]);
+
+  /**
+   * Returns the port used by this socket.
+   */
+  int get port;
+
+  /**
+   * Returns the remote port connected to by this socket.
+   */
+  int get remotePort;
+
+  /**
+   * Returns the [InternetAddress] used to connect this socket.
+   */
+  InternetAddress get address;
+
+  /**
+   * Returns the remote [InternetAddress] connected to by this socket.
+   */
+  InternetAddress get remoteAddress;
+
+  /**
+   * Closes the socket. Returns a Future that completes with [this] when the
+   * underlying connection is completely destroyed.
+   *
+   * Calling [close] will never throw an exception
+   * and calling it several times is supported. Calling [close] can result in
+   * a [RawSocketEvent.readClosed] event.
+   */
+  Future<RawSocket> close();
+
+  /**
+   * Shutdown the socket in the [direction]. Calling [shutdown] will never
+   * throw an exception and calling it several times is supported. Calling
+   * shutdown with either [SocketDirection.both] or [SocketDirection.receive]
+   * can result in a [RawSocketEvent.readClosed] event.
+   */
+  void shutdown(SocketDirection direction);
+
+  /**
+   * Use [setOption] to customize the [RawSocket]. See [SocketOption] for
+   * available options.
+   *
+   * Returns [:true:] if the option was set successfully, false otherwise.
+   */
+  bool setOption(SocketOption option, bool enabled);
+
+  /**
+   * Use [getRawOption] to get low level information about the [RawSocket]. See
+   * [RawSocketOption] for available options.
+   *
+   * Returns the [RawSocketOption.value] on success.
+   *
+   * Throws an [OSError] on failure.
+   */
+  @Since("2.2")
+  Uint8List getRawOption(RawSocketOption option);
+
+  /**
+   * Use [setRawOption] to customize the [RawSocket]. See [RawSocketOption] for
+   * available options.
+   *
+   * Throws an [OSError] on failure.
+   */
+  @Since("2.2")
+  void setRawOption(RawSocketOption option);
+}
+
+/**
+ * A high-level class for communicating over a TCP socket.
+ *
+ * The [Socket] exposes both a [Stream] and a [IOSink] interface, making it
+ * ideal for using together with other [Stream]s.
+ */
+abstract class Socket implements Stream<Uint8List>, IOSink {
+  /**
+   * Creates a new socket connection to the host and port and returns a [Future]
+   * that will complete with either a [Socket] once connected or an error
+   * if the host-lookup or connection failed.
+   *
+   * [host] can either be a [String] or an [InternetAddress]. If [host] is a
+   * [String], [connect] will perform a [InternetAddress.lookup] and try
+   * all returned [InternetAddress]es, until connected. Unless a
+   * connection was established, the error from the first failing connection is
+   * returned.
+   *
+   * The argument [sourceAddress] can be used to specify the local
+   * address to bind when making the connection. `sourceAddress` can either
+   * be a `String` or an `InternetAddress`. If a `String` is passed it must
+   * hold a numeric IP address.
+   *
+   * The argument [timeout] is used to specify the maximum allowed time to wait
+   * for a connection to be established. If [timeout] is longer than the system
+   * level timeout duration, a timeout may occur sooner than specified in
+   * [timeout]. On timeout, a [SocketException] is thrown and all ongoing
+   * connection attempts to [host] are cancelled.
+   */
+  static Future<Socket> connect(host, int port,
+      {sourceAddress, Duration timeout}) {
+    final IOOverrides overrides = IOOverrides.current;
+    if (overrides == null) {
+      return Socket._connect(host, port,
+          sourceAddress: sourceAddress, timeout: timeout);
+    }
+    return overrides.socketConnect(host, port,
+        sourceAddress: sourceAddress, timeout: timeout);
+  }
+
+  /// Like [connect], but returns a [Future] that completes with a
+  /// [ConnectionTask] that can be cancelled if the [Socket] is no
+  /// longer needed.
+  static Future<ConnectionTask<Socket>> startConnect(host, int port,
+      {sourceAddress}) {
+    final IOOverrides overrides = IOOverrides.current;
+    if (overrides == null) {
+      return Socket._startConnect(host, port, sourceAddress: sourceAddress);
+    }
+    return overrides.socketStartConnect(host, port,
+        sourceAddress: sourceAddress);
+  }
+
+  external static Future<Socket> _connect(host, int port,
+      {sourceAddress, Duration timeout});
+
+  external static Future<ConnectionTask<Socket>> _startConnect(host, int port,
+      {sourceAddress});
+
+  /**
+   * Destroy the socket in both directions. Calling [destroy] will make the
+   * send a close event on the stream and will no longer react on data being
+   * piped to it.
+   *
+   * Call [close](inherited from [IOSink]) to only close the [Socket]
+   * for sending data.
+   */
+  void destroy();
+
+  /**
+   * Use [setOption] to customize the [RawSocket]. See [SocketOption] for
+   * available options.
+   *
+   * Returns [:true:] if the option was set successfully, false otherwise.
+   */
+  bool setOption(SocketOption option, bool enabled);
+
+  /**
+   * Use [getRawOption] to get low level information about the [RawSocket]. See
+   * [RawSocketOption] for available options.
+   *
+   * Returns the [RawSocketOption.value] on success.
+   *
+   * Throws an [OSError] on failure.
+   */
+  Uint8List getRawOption(RawSocketOption option);
+
+  /**
+   * Use [setRawOption] to customize the [RawSocket]. See [RawSocketOption] for
+   * available options.
+   *
+   * Throws an [OSError] on failure.
+   */
+  void setRawOption(RawSocketOption option);
+
+  /**
+   * Returns the port used by this socket.
+   */
+  int get port;
+
+  /**
+   * Returns the remote port connected to by this socket.
+   */
+  int get remotePort;
+
+  /**
+   * Returns the [InternetAddress] used to connect this socket.
+   */
+  InternetAddress get address;
+
+  /**
+   * Returns the remote [InternetAddress] connected to by this socket.
+   */
+  InternetAddress get remoteAddress;
+
+  Future close();
+
+  Future get done;
+}
+
+/**
+ * Datagram package. Data sent to and received from datagram sockets
+ * contains the internet address and port of the destination or source
+ * togeter with the data.
+ */
+class Datagram {
+  Uint8List data;
+  InternetAddress address;
+  int port;
+
+  Datagram(this.data, this.address, this.port);
+}
+
+/**
+ * A [RawDatagramSocket] is an unbuffered interface to a UDP socket.
+ *
+ * The raw datagram socket delivers the datagrams in the same chunks as the
+ * underlying operating system. It's a [Stream] of [RawSocketEvent]s.
+ *
+ * Note that the event [RawSocketEvent.readClosed] will never be
+ * received as an UDP socket cannot be closed by a remote peer.
+ *
+ * It is not the same as a
+ * [POSIX raw socket](http://man7.org/linux/man-pages/man7/raw.7.html).
+ */
+abstract class RawDatagramSocket extends Stream<RawSocketEvent> {
+  /**
+   * Set or get, if the [RawDatagramSocket] should listen for
+   * [RawSocketEvent.read] events. Default is [:true:].
+   */
+  bool readEventsEnabled;
+
+  /**
+   * Set or get, if the [RawDatagramSocket] should listen for
+   * [RawSocketEvent.write] events. Default is [:true:].  This is a
+   * one-shot listener, and writeEventsEnabled must be set to true
+   * again to receive another write event.
+   */
+  bool writeEventsEnabled;
+
+  /**
+   * Set or get, whether multicast traffic is looped back to the host.
+   *
+   * By default multicast loopback is enabled.
+   */
+  bool multicastLoopback;
+
+  /**
+   * Set or get, the maximum network hops for multicast packages
+   * originating from this socket.
+   *
+   * For IPv4 this is referred to as TTL (time to live).
+   *
+   * By default this value is 1 causing multicast traffic to stay on
+   * the local network.
+   */
+  int multicastHops;
+
+  /**
+   * Set or get, the network interface used for outgoing multicast packages.
+   *
+   * A value of `null`indicate that the system chooses the network
+   * interface to use.
+   *
+   * By default this value is `null`
+   */
+  @Deprecated("This property is not implemented. Use getRawOption and "
+      "setRawOption instead.")
+  NetworkInterface multicastInterface;
+
+  /**
+   * Set or get, whether IPv4 broadcast is enabled.
+   *
+   * IPv4 broadcast needs to be enabled by the sender for sending IPv4
+   * broadcast packages. By default IPv4 broadcast is disabled.
+   *
+   * For IPv6 there is no general broadcast mechanism. Use multicast
+   * instead.
+   */
+  bool broadcastEnabled;
+
+  /**
+   * Creates a new raw datagram socket binding it to an address and
+   * port.
+   */
+  external static Future<RawDatagramSocket> bind(host, int port,
+      {bool reuseAddress: true, bool reusePort: false, int ttl: 1});
+
+  /**
+   * Returns the port used by this socket.
+   */
+  int get port;
+
+  /**
+   * Returns the address used by this socket.
+   */
+  InternetAddress get address;
+
+  /**
+   * Close the datagram socket.
+   */
+  void close();
+
+  /**
+   * Send a datagram.
+   *
+   * Returns the number of bytes written. This will always be either
+   * the size of [buffer] or `0`.
+   */
+  int send(List<int> buffer, InternetAddress address, int port);
+
+  /**
+   * Receive a datagram. If there are no datagrams available `null` is
+   * returned.
+   *
+   * The maximum length of the datagram that can be received is 65503 bytes.
+   */
+  Datagram receive();
+
+  /**
+   * Join a multicast group.
+   *
+   * If an error occur when trying to join the multicast group an
+   * exception is thrown.
+   */
+  void joinMulticast(InternetAddress group, [NetworkInterface interface]);
+
+  /**
+   * Leave a multicast group.
+   *
+   * If an error occur when trying to join the multicase group an
+   * exception is thrown.
+   */
+  void leaveMulticast(InternetAddress group, [NetworkInterface interface]);
+
+  /**
+   * Use [getRawOption] to get low level information about the [RawSocket]. See
+   * [RawSocketOption] for available options.
+   *
+   * Returns [RawSocketOption.value] on success.
+   *
+   * Throws an [OSError] on failure.
+   */
+  Uint8List getRawOption(RawSocketOption option);
+
+  /**
+   * Use [setRawOption] to customize the [RawSocket]. See [RawSocketOption] for
+   * available options.
+   *
+   * Throws an [OSError] on failure.
+   */
+  void setRawOption(RawSocketOption option);
+}
+
+class SocketException implements IOException {
+  final String message;
+  final OSError osError;
+  final InternetAddress address;
+  final int port;
+
+  const SocketException(this.message, {this.osError, this.address, this.port});
+  const SocketException.closed()
+      : message = 'Socket has been closed',
+        osError = null,
+        address = null,
+        port = null;
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write("SocketException");
+    if (message.isNotEmpty) {
+      sb.write(": $message");
+      if (osError != null) {
+        sb.write(" ($osError)");
+      }
+    } else if (osError != null) {
+      sb.write(": $osError");
+    }
+    if (address != null) {
+      sb.write(", address = ${address.host}");
+    }
+    if (port != null) {
+      sb.write(", port = $port");
+    }
+    return sb.toString();
+  }
+}
diff --git a/sdk_nnbd/lib/io/stdio.dart b/sdk_nnbd/lib/io/stdio.dart
new file mode 100644
index 0000000..4086f08
--- /dev/null
+++ b/sdk_nnbd/lib/io/stdio.dart
@@ -0,0 +1,480 @@
+// 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 dart.io;
+
+const int _stdioHandleTypeTerminal = 0;
+const int _stdioHandleTypePipe = 1;
+const int _stdioHandleTypeFile = 2;
+const int _stdioHandleTypeSocket = 3;
+const int _stdioHandleTypeOther = 4;
+
+class _StdStream extends Stream<List<int>> {
+  final Stream<List<int>> _stream;
+
+  _StdStream(this._stream);
+
+  StreamSubscription<List<int>> listen(void onData(List<int> event),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    return _stream.listen(onData,
+        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+  }
+}
+
+/**
+ * [Stdin] allows both synchronous and asynchronous reads from the standard
+ * input stream.
+ *
+ * Mixing synchronous and asynchronous reads is undefined.
+ */
+class Stdin extends _StdStream implements Stream<List<int>> {
+  int _fd;
+
+  Stdin._(Stream<List<int>> stream, this._fd) : super(stream);
+
+  /**
+   * Read a line from stdin.
+   *
+   * Blocks until a full line is available.
+   *
+   * Lines my be terminated by either `<CR><LF>` or `<LF>`. On Windows in cases
+   * where the [stdioType] of stdin is [StdioType.termimal] the terminator may
+   * also be a single `<CR>`.
+   *
+   * Input bytes are converted to a string by [encoding].
+   * If [encoding] is omitted, it defaults to [systemEncoding].
+   *
+   * If [retainNewlines] is `false`, the returned String will not include the
+   * final line terminator. If `true`, the returned String will include the line
+   * terminator. Default is `false`.
+   *
+   * If end-of-file is reached after any bytes have been read from stdin,
+   * that data is returned without a line terminator.
+   * Returns `null` if no bytes preceded the end of input.
+   */
+  String readLineSync(
+      {Encoding encoding: systemEncoding, bool retainNewlines: false}) {
+    const CR = 13;
+    const LF = 10;
+    final List<int> line = <int>[];
+    // On Windows, if lineMode is disabled, only CR is received.
+    bool crIsNewline = Platform.isWindows &&
+        (stdioType(stdin) == StdioType.terminal) &&
+        !lineMode;
+    if (retainNewlines) {
+      int byte;
+      do {
+        byte = readByteSync();
+        if (byte < 0) {
+          break;
+        }
+        line.add(byte);
+      } while (byte != LF && !(byte == CR && crIsNewline));
+      if (line.isEmpty) {
+        return null;
+      }
+    } else if (crIsNewline) {
+      // CR and LF are both line terminators, neither is retained.
+      while (true) {
+        int byte = readByteSync();
+        if (byte < 0) {
+          if (line.isEmpty) return null;
+          break;
+        }
+        if (byte == LF || byte == CR) break;
+        line.add(byte);
+      }
+    } else {
+      // Case having to handle CR LF as a single unretained line terminator.
+      outer:
+      while (true) {
+        int byte = readByteSync();
+        if (byte == LF) break;
+        if (byte == CR) {
+          do {
+            byte = readByteSync();
+            if (byte == LF) break outer;
+
+            line.add(CR);
+          } while (byte == CR);
+          // Fall through and handle non-CR character.
+        }
+        if (byte < 0) {
+          if (line.isEmpty) return null;
+          break;
+        }
+        line.add(byte);
+      }
+    }
+    return encoding.decode(line);
+  }
+
+  /**
+   * Check if echo mode is enabled on [stdin].
+   */
+  external bool get echoMode;
+
+  /**
+   * Enable or disable echo mode on [stdin].
+   *
+   * If disabled, input from to console will not be echoed.
+   *
+   * Default depends on the parent process, but usually enabled.
+   *
+   * On Windows this mode can only be enabled if [lineMode] is enabled as well.
+   */
+  external void set echoMode(bool enabled);
+
+  /**
+   * Check if line mode is enabled on [stdin].
+   */
+  external bool get lineMode;
+
+  /**
+   * Enable or disable line mode on [stdin].
+   *
+   * If enabled, characters are delayed until a new-line character is entered.
+   * If disabled, characters will be available as typed.
+   *
+   * Default depends on the parent process, but usually enabled.
+   *
+   * On Windows this mode can only be disabled if [echoMode] is disabled as well.
+   */
+  external void set lineMode(bool enabled);
+
+  /**
+    * Whether connected to a terminal that supports ANSI escape sequences.
+    *
+    * Not all terminals are recognized, and not all recognized terminals can
+    * report whether they support ANSI escape sequences, so this value is a
+    * best-effort attempt at detecting the support.
+    *
+    * The actual escape sequence support may differ between terminals,
+    * with some terminals supporting more escape sequences than others,
+    * and some terminals even differing in behavior for the same escape
+    * sequence.
+    *
+    * The ANSI color selection is generally supported.
+    *
+    * Currently, a `TERM` environment variable containing the string `xterm`
+    * will be taken as evidence that ANSI escape sequences are supported.
+    * On Windows, only versions of Windows 10 after v.1511
+    * ("TH2", OS build 10586) will be detected as supporting the output of
+    * ANSI escape sequences, and only versions after v.1607 ("Anniversary
+    * Update", OS build 14393) will be detected as supporting the input of
+    * ANSI escape sequences.
+    */
+  external bool get supportsAnsiEscapes;
+
+  /**
+   * Synchronously read a byte from stdin. This call will block until a byte is
+   * available.
+   *
+   * If at end of file, -1 is returned.
+   */
+  external int readByteSync();
+
+  /**
+   * Returns true if there is a terminal attached to stdin.
+   */
+  bool get hasTerminal {
+    try {
+      return stdioType(this) == StdioType.terminal;
+    } on FileSystemException catch (_) {
+      // If stdioType throws a FileSystemException, then it is not hooked up to
+      // a terminal, probably because it is closed, but let other exception
+      // types bubble up.
+      return false;
+    }
+  }
+}
+
+/**
+ * [Stdout] represents the [IOSink] for either `stdout` or `stderr`.
+ *
+ * It provides a *blocking* `IOSink`, so using this to write will block until
+ * the output is written.
+ *
+ * In some situations this blocking behavior is undesirable as it does not
+ * provide the same non-blocking behavior as dart:io in general exposes.
+ * Use the property [nonBlocking] to get an `IOSink` which has the non-blocking
+ * behavior.
+ *
+ * This class can also be used to check whether `stdout` or `stderr` is
+ * connected to a terminal and query some terminal properties.
+ *
+ * The [addError] API is inherited from  [StreamSink] and calling it will result
+ * in an unhandled asynchronous error unless there is an error handler on
+ * [done].
+ */
+class Stdout extends _StdSink implements IOSink {
+  final int _fd;
+  IOSink _nonBlocking;
+
+  Stdout._(IOSink sink, this._fd) : super(sink);
+
+  /**
+   * Returns true if there is a terminal attached to stdout.
+   */
+  bool get hasTerminal => _hasTerminal(_fd);
+
+  /**
+   * Get the number of columns of the terminal.
+   *
+   * If no terminal is attached to stdout, a [StdoutException] is thrown. See
+   * [hasTerminal] for more info.
+   */
+  int get terminalColumns => _terminalColumns(_fd);
+
+  /**
+   * Get the number of lines of the terminal.
+   *
+   * If no terminal is attached to stdout, a [StdoutException] is thrown. See
+   * [hasTerminal] for more info.
+   */
+  int get terminalLines => _terminalLines(_fd);
+
+  /**
+    * Whether connected to a terminal that supports ANSI escape sequences.
+    *
+    * Not all terminals are recognized, and not all recognized terminals can
+    * report whether they support ANSI escape sequences, so this value is a
+    * best-effort attempt at detecting the support.
+    *
+    * The actual escape sequence support may differ between terminals,
+    * with some terminals supporting more escape sequences than others,
+    * and some terminals even differing in behavior for the same escape
+    * sequence.
+    *
+    * The ANSI color selection is generally supported.
+    *
+    * Currently, a `TERM` environment variable containing the string `xterm`
+    * will be taken as evidence that ANSI escape sequences are supported.
+    * On Windows, only versions of Windows 10 after v.1511
+    * ("TH2", OS build 10586) will be detected as supporting the output of
+    * ANSI escape sequences, and only versions after v.1607 ("Anniversary
+    * Update", OS build 14393) will be detected as supporting the input of
+    * ANSI escape sequences.
+    */
+  bool get supportsAnsiEscapes => _supportsAnsiEscapes(_fd);
+
+  external bool _hasTerminal(int fd);
+  external int _terminalColumns(int fd);
+  external int _terminalLines(int fd);
+  external static bool _supportsAnsiEscapes(int fd);
+
+  /**
+   * Get a non-blocking `IOSink`.
+   */
+  IOSink get nonBlocking {
+    _nonBlocking ??= new IOSink(new _FileStreamConsumer.fromStdio(_fd));
+    return _nonBlocking;
+  }
+}
+
+class StdoutException implements IOException {
+  final String message;
+  final OSError osError;
+
+  const StdoutException(this.message, [this.osError]);
+
+  String toString() {
+    return "StdoutException: $message${osError == null ? "" : ", $osError"}";
+  }
+}
+
+class StdinException implements IOException {
+  final String message;
+  final OSError osError;
+
+  const StdinException(this.message, [this.osError]);
+
+  String toString() {
+    return "StdinException: $message${osError == null ? "" : ", $osError"}";
+  }
+}
+
+class _StdConsumer implements StreamConsumer<List<int>> {
+  final _file;
+
+  _StdConsumer(int fd) : _file = _File._openStdioSync(fd);
+
+  Future addStream(Stream<List<int>> stream) {
+    var completer = new Completer();
+    var sub;
+    sub = stream.listen((data) {
+      try {
+        _file.writeFromSync(data);
+      } catch (e, s) {
+        sub.cancel();
+        completer.completeError(e, s);
+      }
+    },
+        onError: completer.completeError,
+        onDone: completer.complete,
+        cancelOnError: true);
+    return completer.future;
+  }
+
+  Future close() {
+    _file.closeSync();
+    return new Future.value();
+  }
+}
+
+class _StdSink implements IOSink {
+  final IOSink _sink;
+
+  _StdSink(this._sink);
+
+  Encoding get encoding => _sink.encoding;
+  void set encoding(Encoding encoding) {
+    _sink.encoding = encoding;
+  }
+
+  void write(object) {
+    _sink.write(object);
+  }
+
+  void writeln([object = ""]) {
+    _sink.writeln(object);
+  }
+
+  void writeAll(objects, [sep = ""]) {
+    _sink.writeAll(objects, sep);
+  }
+
+  void add(List<int> data) {
+    _sink.add(data);
+  }
+
+  void addError(error, [StackTrace stackTrace]) {
+    _sink.addError(error, stackTrace);
+  }
+
+  void writeCharCode(int charCode) {
+    _sink.writeCharCode(charCode);
+  }
+
+  Future addStream(Stream<List<int>> stream) => _sink.addStream(stream);
+  Future flush() => _sink.flush();
+  Future close() => _sink.close();
+  Future get done => _sink.done;
+}
+
+/// The type of object a standard IO stream is attached to.
+class StdioType {
+  static const StdioType terminal = const StdioType._("terminal");
+  static const StdioType pipe = const StdioType._("pipe");
+  static const StdioType file = const StdioType._("file");
+  static const StdioType other = const StdioType._("other");
+
+  @Deprecated("Use terminal instead")
+  static const StdioType TERMINAL = terminal;
+  @Deprecated("Use pipe instead")
+  static const StdioType PIPE = pipe;
+  @Deprecated("Use file instead")
+  static const StdioType FILE = file;
+  @Deprecated("Use other instead")
+  static const StdioType OTHER = other;
+
+  final String name;
+  const StdioType._(this.name);
+  String toString() => "StdioType: $name";
+}
+
+Stdin _stdin;
+Stdout _stdout;
+Stdout _stderr;
+
+// These may be set to different values by the embedder by calling
+// _setStdioFDs when initializing dart:io.
+int _stdinFD = 0;
+int _stdoutFD = 1;
+int _stderrFD = 2;
+
+@pragma('vm:entry-point', 'call')
+void _setStdioFDs(int stdin, int stdout, int stderr) {
+  _stdinFD = stdin;
+  _stdoutFD = stdout;
+  _stderrFD = stderr;
+}
+
+/// The standard input stream of data read by this program.
+Stdin get stdin {
+  _stdin ??= _StdIOUtils._getStdioInputStream(_stdinFD);
+  return _stdin;
+}
+
+/// The standard output stream of data written by this program.
+///
+/// The `addError` API is inherited from  `StreamSink` and calling it will
+/// result in an unhandled asynchronous error unless there is an error handler
+/// on `done`.
+Stdout get stdout {
+  _stdout ??= _StdIOUtils._getStdioOutputStream(_stdoutFD);
+  return _stdout;
+}
+
+/// The standard output stream of errors written by this program.
+///
+/// The `addError` API is inherited from  `StreamSink` and calling it will
+/// result in an unhandled asynchronous error unless there is an error handler
+/// on `done`.
+Stdout get stderr {
+  _stderr ??= _StdIOUtils._getStdioOutputStream(_stderrFD);
+  return _stderr;
+}
+
+/// For a stream, returns whether it is attached to a file, pipe, terminal, or
+/// something else.
+StdioType stdioType(object) {
+  if (object is _StdStream) {
+    object = object._stream;
+  } else if (object == stdout || object == stderr) {
+    int stdiofd = object == stdout ? _stdoutFD : _stderrFD;
+    switch (_StdIOUtils._getStdioHandleType(stdiofd)) {
+      case _stdioHandleTypeTerminal:
+        return StdioType.terminal;
+      case _stdioHandleTypePipe:
+        return StdioType.pipe;
+      case _stdioHandleTypeFile:
+        return StdioType.file;
+    }
+  }
+  if (object is _FileStream) {
+    return StdioType.file;
+  }
+  if (object is Socket) {
+    int socketType = _StdIOUtils._socketType(object);
+    if (socketType == null) return StdioType.other;
+    switch (socketType) {
+      case _stdioHandleTypeTerminal:
+        return StdioType.terminal;
+      case _stdioHandleTypePipe:
+        return StdioType.pipe;
+      case _stdioHandleTypeFile:
+        return StdioType.file;
+    }
+  }
+  if (object is _IOSinkImpl) {
+    try {
+      if (object._target is _FileStreamConsumer) {
+        return StdioType.file;
+      }
+    } catch (e) {
+      // Only the interface implemented, _sink not available.
+    }
+  }
+  return StdioType.other;
+}
+
+class _StdIOUtils {
+  external static _getStdioOutputStream(int fd);
+  external static Stdin _getStdioInputStream(int fd);
+
+  /// Returns the socket type or `null` if [socket] is not a builtin socket.
+  external static int _socketType(Socket socket);
+  external static _getStdioHandleType(int fd);
+}
diff --git a/sdk_nnbd/lib/io/string_transformer.dart b/sdk_nnbd/lib/io/string_transformer.dart
new file mode 100644
index 0000000..f31c41e
--- /dev/null
+++ b/sdk_nnbd/lib/io/string_transformer.dart
@@ -0,0 +1,130 @@
+// 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 dart.io;
+
+/// The current system encoding.
+///
+/// This is used for converting from bytes to and from Strings when
+/// communicating on stdin, stdout and stderr.
+///
+/// On Windows this will use the currently active code page for the conversion.
+/// On all other systems it will always use UTF-8.
+const SystemEncoding systemEncoding = const SystemEncoding();
+@Deprecated("Use systemEncoding instead")
+const SystemEncoding SYSTEM_ENCODING = const SystemEncoding();
+
+/// The system encoding is the current code page on Windows and UTF-8 on Linux
+/// and Mac.
+class SystemEncoding extends Encoding {
+  /// Creates a const SystemEncoding.
+  ///
+  /// Users should use the top-level constant, [systemEncoding].
+  const SystemEncoding();
+
+  String get name => 'system';
+
+  List<int> encode(String input) => encoder.convert(input);
+  String decode(List<int> encoded) => decoder.convert(encoded);
+
+  Converter<String, List<int>> get encoder {
+    if (Platform.operatingSystem == "windows") {
+      return const _WindowsCodePageEncoder();
+    } else {
+      return const Utf8Encoder();
+    }
+  }
+
+  Converter<List<int>, String> get decoder {
+    if (Platform.operatingSystem == "windows") {
+      return const _WindowsCodePageDecoder();
+    } else {
+      return const Utf8Decoder();
+    }
+  }
+}
+
+class _WindowsCodePageEncoder extends Converter<String, List<int>> {
+  const _WindowsCodePageEncoder();
+
+  List<int> convert(String input) {
+    List<int> encoded = _encodeString(input);
+    if (encoded == null) {
+      throw new FormatException("Invalid character for encoding");
+    }
+    return encoded;
+  }
+
+  /**
+   * Starts a chunked conversion.
+   */
+  StringConversionSink startChunkedConversion(Sink<List<int>> sink) {
+    return new _WindowsCodePageEncoderSink(sink);
+  }
+
+  external static List<int> _encodeString(String string);
+}
+
+class _WindowsCodePageEncoderSink extends StringConversionSinkBase {
+  // TODO(floitsch): provide more efficient conversions when the input is
+  // not a String.
+
+  final Sink<List<int>> _sink;
+
+  _WindowsCodePageEncoderSink(this._sink);
+
+  void close() {
+    _sink.close();
+  }
+
+  void add(String string) {
+    List<int> encoded = _WindowsCodePageEncoder._encodeString(string);
+    if (encoded == null) {
+      throw new FormatException("Invalid character for encoding");
+    }
+    _sink.add(encoded);
+  }
+
+  void addSlice(String source, int start, int end, bool isLast) {
+    if (start != 0 || end != source.length) {
+      source = source.substring(start, end);
+    }
+    add(source);
+    if (isLast) close();
+  }
+}
+
+class _WindowsCodePageDecoder extends Converter<List<int>, String> {
+  const _WindowsCodePageDecoder();
+
+  String convert(List<int> input) {
+    return _decodeBytes(input);
+  }
+
+  /**
+   * Starts a chunked conversion.
+   */
+  ByteConversionSink startChunkedConversion(Sink<String> sink) {
+    return new _WindowsCodePageDecoderSink(sink);
+  }
+
+  external static String _decodeBytes(List<int> bytes);
+}
+
+class _WindowsCodePageDecoderSink extends ByteConversionSinkBase {
+  // TODO(floitsch): provide more efficient conversions when the input is
+  // a slice.
+
+  final Sink<String> _sink;
+
+  _WindowsCodePageDecoderSink(this._sink);
+
+  void close() {
+    _sink.close();
+  }
+
+  void add(List<int> bytes) {
+    _sink.add(_WindowsCodePageDecoder._decodeBytes(bytes));
+  }
+}
diff --git a/sdk_nnbd/lib/io/sync_socket.dart b/sdk_nnbd/lib/io/sync_socket.dart
new file mode 100644
index 0000000..fee259d
--- /dev/null
+++ b/sdk_nnbd/lib/io/sync_socket.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.io;
+
+/**
+ * A low-level class for communicating synchronously over a TCP socket.
+ *
+ * Warning: [RawSynchronousSocket] should probably only be used to connect to
+ * 'localhost'. The operations below will block the calling thread to wait for
+ * a response from the network. The thread can process no other events while
+ * waiting for these operations to complete. [RawSynchronousSocket] is not
+ * suitable for applications that require high performance or asynchronous I/O
+ * such as a server. Instead such applications should use the non-blocking
+ * sockets and asynchronous operations in the Socket or RawSocket classes.
+ */
+abstract class RawSynchronousSocket {
+  /**
+   * Creates a new socket connection and returns a [RawSynchronousSocket].
+   *
+   * [host] can either be a [String] or an [InternetAddress]. If [host] is a
+   * [String], [connectSync] will perform a [InternetAddress.lookup] and try
+   * all returned [InternetAddress]es, until connected. Unless a
+   * connection was established, the error from the first failing connection is
+   * returned.
+   */
+  external static RawSynchronousSocket connectSync(host, int port);
+
+  /**
+   * Returns the number of received and unread bytes in the socket that can be
+   * read.
+   */
+  int available();
+
+  /**
+   * Closes the [RawSynchronousSocket].
+   *
+   * Once [closeSync] has been called, attempting to call [readSync],
+   * [readIntoSync], [writeFromSync], [remoteAddress], and [remotePort] will
+   * cause a [SocketException] to be thrown.
+   */
+  void closeSync();
+
+  /**
+   * Reads into an existing [List<int>] from the socket into the range:
+   * [[start],[end]).
+   *
+   * Reads into an existing [List<int>] from the socket. If [start] is present,
+   * the bytes will be filled into [buffer] from index [start], otherwise index
+   * 0. If [end] is present, [end] - [start] bytes will be read into [buffer],
+   * otherwise up to [buffer.length]. If [end] == [start], no bytes are read.
+   * Returns the number of bytes read.
+   */
+  int readIntoSync(List<int> buffer, [int start = 0, int end]);
+
+  /**
+   * Reads up to [bytes] bytes from the socket.
+   *
+   * Blocks and waits for a response of up to a specified number of bytes
+   * sent by the socket. [bytes] specifies the maximum number of bytes to
+   * be read. Returns the list of bytes read, which could be less than the
+   * value specified by [bytes].
+   */
+  List<int> readSync(int bytes);
+
+  /**
+   * Shutdown a socket in the provided direction.
+   *
+   * Calling shutdown will never throw an exception and calling it several times
+   * is supported. If both [SocketDirection.RECEIVE] and [SocketDirection.SEND]
+   * directions are closed, the socket is closed completely, the same as if
+   * [closeSync] has been called.
+   */
+  void shutdown(SocketDirection direction);
+
+  /**
+   * Writes data from a specified range in a [List<int>] to the socket.
+   *
+   * Writes into the socket from a [List<int>]. If [start] is present, the bytes
+   * will be written to the socket starting from index [start]. If [start] is
+   * not present, the bytes will be written starting from index 0. If [end] is
+   * present, the [end] - [start] bytes will be written into the socket starting
+   * at index [start]. If [end] is not provided, [buffer.length] elements will
+   * be written to the socket starting from index [start]. If [end] == [start],
+   * nothing happens.
+   */
+  void writeFromSync(List<int> buffer, [int start = 0, int end]);
+
+  /**
+   * The port used by this socket.
+   */
+  int get port;
+
+  /**
+   * The remote port connected to by this socket.
+   */
+  int get remotePort;
+
+  /**
+   * The [InternetAddress] used to connect this socket.
+   */
+  InternetAddress get address;
+
+  /**
+   * The remote [InternetAddress] connected to by this socket.
+   */
+  InternetAddress get remoteAddress;
+}
diff --git a/sdk_nnbd/lib/isolate/capability.dart b/sdk_nnbd/lib/isolate/capability.dart
new file mode 100644
index 0000000..a51eec2
--- /dev/null
+++ b/sdk_nnbd/lib/isolate/capability.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.isolate;
+
+/**
+ * An unforgeable object that comes back as equal when passed through other
+ * isolates.
+ *
+ * Sending a capability object to another isolate, and getting it back,
+ * will produce an object that is equal to the original.
+ * There is no other way to create objects equal to a capability object.
+ *
+ * Capabilities can be used as access guards: A remote isolate can send
+ * a request for an operation, but it is only allowed if the request contains
+ * the correct capability object.
+ *
+ * This allows exposing the same interface to multiple clients,
+ * but restricting some operations to only those clients
+ * that have also been given the corresponding capability.
+ *
+ * Capabilities can be used inside a single isolate,
+ * but they have no advantage over
+ * just using `new Object` to create a unique object,
+ * and it offers no real security against other code
+ * running in the same isolate.
+ */
+class Capability {
+  /**
+   * Create a new unforgeable capability object.
+   */
+  external factory Capability();
+}
diff --git a/sdk_nnbd/lib/isolate/isolate.dart b/sdk_nnbd/lib/isolate/isolate.dart
new file mode 100644
index 0000000..a697db4
--- /dev/null
+++ b/sdk_nnbd/lib/isolate/isolate.dart
@@ -0,0 +1,789 @@
+// Copyright (c) 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.
+
+/**
+ * Concurrent programming using _isolates_:
+ * independent workers that are similar to threads
+ * but don't share memory,
+ * communicating only via messages.
+ *
+ * To use this library in your code:
+ *
+ *     import 'dart:isolate';
+ *
+ * {@category VM}
+ */
+library dart.isolate;
+
+import "dart:async";
+import "dart:_internal" show Since;
+import "dart:typed_data" show ByteBuffer, TypedData, Uint8List;
+
+part "capability.dart";
+
+/**
+ * Thrown when an isolate cannot be created.
+ */
+class IsolateSpawnException implements Exception {
+  /** Error message reported by the spawn operation. */
+  final String message;
+  @pragma("vm:entry-point")
+  IsolateSpawnException(this.message);
+  String toString() => "IsolateSpawnException: $message";
+}
+
+/**
+ * An isolated Dart execution context.
+ *
+ * All Dart code runs in an isolate, and code can access classes and values
+ * only from the same isolate. Different isolates can communicate by sending
+ * values through ports (see [ReceivePort], [SendPort]).
+ *
+ * An `Isolate` object is a reference to an isolate, usually different from
+ * the current isolate.
+ * It represents, and can be used to control, the other isolate.
+ *
+ * When spawning a new isolate, the spawning isolate receives an `Isolate`
+ * object representing the new isolate when the spawn operation succeeds.
+ *
+ * Isolates run code in its own event loop, and each event may run smaller tasks
+ * in a nested microtask queue.
+ *
+ * An `Isolate` object allows other isolates to control the event loop
+ * of the isolate that it represents, and to inspect the isolate,
+ * for example by pausing the isolate or by getting events when the isolate
+ * has an uncaught error.
+ *
+ * The [controlPort] identifies and gives access to controlling the isolate,
+ * and the [pauseCapability] and [terminateCapability] guard access
+ * to some control operations.
+ * For example, calling [pause] on an `Isolate` object created without a
+ * [pauseCapability], has no effect.
+ *
+ * The `Isolate` object provided by a spawn operation will have the
+ * control port and capabilities needed to control the isolate.
+ * New isolate objects can be created without some of these capabilities
+ * if necessary, using the [Isolate.Isolate] constructor.
+ *
+ * An `Isolate` object cannot be sent over a `SendPort`, but the control port
+ * and capabilities can be sent, and can be used to create a new functioning
+ * `Isolate` object in the receiving port's isolate.
+ */
+class Isolate {
+  /** Argument to `ping` and `kill`: Ask for immediate action. */
+  static const int immediate = 0;
+  /** Argument to `ping` and `kill`: Ask for action before the next event. */
+  static const int beforeNextEvent = 1;
+
+  /**
+   * Control port used to send control messages to the isolate.
+   *
+   * The control port identifies the isolate.
+   *
+   * An `Isolate` object allows sending control messages
+   * through the control port.
+   *
+   * Some control messages require a specific capability to be passed along
+   * with the message (see [pauseCapability] and [terminateCapability]),
+   * otherwise the message is ignored by the isolate.
+   */
+  final SendPort controlPort;
+
+  /**
+   * Capability granting the ability to pause the isolate.
+   *
+   * This capability is required by [pause].
+   * If the capability is `null`, or if it is not the correct pause capability
+   * of the isolate identified by [controlPort],
+   * then calls to [pause] will have no effect.
+   *
+   * If the isolate is spawned in a paused state, use this capability as
+   * argument to the [resume] method in order to resume the paused isolate.
+   */
+  final Capability pauseCapability;
+
+  /**
+   * Capability granting the ability to terminate the isolate.
+   *
+   * This capability is required by [kill] and [setErrorsFatal].
+   * If the capability is `null`, or if it is not the correct termination
+   * capability of the isolate identified by [controlPort],
+   * then calls to those methods will have no effect.
+   */
+  final Capability terminateCapability;
+
+  /**
+   * The name of the [Isolate] displayed for debug purposes.
+   *
+   * This can be set using the `debugName` parameter in [spawn] and [spawnUri].
+   *
+   * This name does not uniquely identify an isolate. Multiple isolates in the
+   * same process may have the same `debugName`.
+   *
+   * For a given isolate, this value will be the same as the values returned by
+   * `Dart_DebugName` in the C embedding API and the `debugName` property in
+   * [IsolateMirror].
+   */
+  @Since("2.3")
+  external String get debugName;
+
+  /**
+   * Create a new [Isolate] object with a restricted set of capabilities.
+   *
+   * The port should be a control port for an isolate, as taken from
+   * another `Isolate` object.
+   *
+   * The capabilities should be the subset of the capabilities that are
+   * available to the original isolate.
+   * Capabilities of an isolate are locked to that isolate, and have no effect
+   * anywhere else, so the capabilities should come from the same isolate as
+   * the control port.
+   *
+   * Can also be used to create an [Isolate] object from a control port, and
+   * any available capabilities, that have been sent through a [SendPort].
+   *
+   * Example:
+   * ```dart
+   * Isolate isolate = findSomeIsolate();
+   * Isolate restrictedIsolate = new Isolate(isolate.controlPort);
+   * untrustedCode(restrictedIsolate);
+   * ```
+   * This example creates a new `Isolate` object that cannot be used to
+   * pause or terminate the isolate. All the untrusted code can do is to
+   * inspect the isolate and see uncaught errors or when it terminates.
+   */
+  Isolate(this.controlPort, {this.pauseCapability, this.terminateCapability});
+
+  /**
+   * Return an [Isolate] object representing the current isolate.
+   *
+   * The current isolate for code using [current]
+   * is the isolate running the code.
+   *
+   * The isolate object provides the capabilities required to inspect,
+   * pause or kill the isolate, and allows granting these capabilities
+   * to others.
+   *
+   * It is possible to pause the current isolate, but doing so *without*
+   * first passing the ability to resume it again to another isolate,
+   * is a sure way to hang your program.
+   */
+  external static Isolate get current;
+
+  /**
+   * The location of the package configuration of the current isolate, if any.
+   *
+   * This getter returns `null`, as the `packages/` directory is not supported
+   * in Dart 2.
+   */
+  @Deprecated('packages/ directory resolution is not supported in Dart 2.')
+  external static Future<Uri> get packageRoot;
+
+  /**
+   * The package root of the current isolate, if any.
+   *
+   * If the isolate is using a [packageRoot] or the isolate has not been
+   * setup for package resolution, this getter returns `null`, otherwise it
+   * returns the package config URI.
+   */
+  external static Future<Uri> get packageConfig;
+
+  /**
+   * Maps a package: URI to a non-package Uri.
+   *
+   * If there is no valid mapping from the package: URI in the current
+   * isolate, then this call returns `null`. Non-package: URIs are
+   * returned unmodified.
+   */
+  external static Future<Uri> resolvePackageUri(Uri packageUri);
+
+  /**
+   * Creates and spawns an isolate that shares the same code as the current
+   * isolate.
+   *
+   * The argument [entryPoint] specifies the initial function to call
+   * in the spawned isolate.
+   * The entry-point function is invoked in the new isolate with [message]
+   * as the only argument.
+   *
+   * The function must be a top-level function or a static method
+   * that can be called with a single argument,
+   * that is, a compile-time constant function value
+   * which accepts at least one positional parameter
+   * and has at most one required positional parameter.
+   * The function may accept any number of optional parameters,
+   * as long as it *can* be called with just a single argument.
+   * The function must not be the value of a function expression
+   * or an instance method tear-off.
+   *
+   * Usually the initial [message] contains a [SendPort] so
+   * that the spawner and spawnee can communicate with each other.
+   *
+   * If the [paused] parameter is set to `true`,
+   * the isolate will start up in a paused state,
+   * just before calling the [entryPoint] function with the [message],
+   * as if by an initial call of `isolate.pause(isolate.pauseCapability)`.
+   * To resume the isolate, call `isolate.resume(isolate.pauseCapability)`.
+   *
+   * If the [errorsAreFatal], [onExit] and/or [onError] parameters are provided,
+   * the isolate will act as if, respectively, [setErrorsFatal],
+   * [addOnExitListener] and [addErrorListener] were called with the
+   * corresponding parameter and was processed before the isolate starts
+   * running.
+   *
+   * If [debugName] is provided, the spawned [Isolate] will be identifiable by
+   * this name in debuggers and logging.
+   *
+   * If [errorsAreFatal] is omitted, the platform may choose a default behavior
+   * or inherit the current isolate's behavior.
+   *
+   * You can also call the [setErrorsFatal], [addOnExitListener] and
+   * [addErrorListener] methods on the returned isolate, but unless the
+   * isolate was started as [paused], it may already have terminated
+   * before those methods can complete.
+   *
+   * Returns a future which will complete with an [Isolate] instance if the
+   * spawning succeeded. It will complete with an error otherwise.
+   */
+  external static Future<Isolate> spawn<T>(
+      void entryPoint(T message), T message,
+      {bool paused: false,
+      bool errorsAreFatal,
+      SendPort onExit,
+      SendPort onError,
+      @Since("2.3") String debugName});
+
+  /**
+   * Creates and spawns an isolate that runs the code from the library with
+   * the specified URI.
+   *
+   * The isolate starts executing the top-level `main` function of the library
+   * with the given URI.
+   *
+   * The target `main` must be callable with zero, one or two arguments.
+   * Examples:
+   *
+   * * `main()`
+   * * `main(args)`
+   * * `main(args, message)`
+   *
+   * When present, the parameter `args` is set to the provided [args] list.
+   * When present, the parameter `message` is set to the initial [message].
+   *
+   * If the [paused] parameter is set to `true`,
+   * the isolate will start up in a paused state,
+   * as if by an initial call of `isolate.pause(isolate.pauseCapability)`.
+   * To resume the isolate, call `isolate.resume(isolate.pauseCapability)`.
+   *
+   * If the [errorsAreFatal], [onExit] and/or [onError] parameters are provided,
+   * the isolate will act as if, respectively, [setErrorsFatal],
+   * [addOnExitListener] and [addErrorListener] were called with the
+   * corresponding parameter and was processed before the isolate starts
+   * running.
+   *
+   * You can also call the [setErrorsFatal], [addOnExitListener] and
+   * [addErrorListener] methods on the returned isolate, but unless the
+   * isolate was started as [paused], it may already have terminated
+   * before those methods can complete.
+   *
+   * If the [checked] parameter is set to `true` or `false`,
+   * the new isolate will run code in checked mode (enabling asserts and type
+   * checks), respectively in production mode (disabling asserts and type
+   * checks), if possible. If the parameter is omitted, the new isolate will
+   * inherit the value from the current isolate.
+   *
+   * In Dart2 strong mode, the `checked` parameter only controls asserts, but
+   * not type checks.
+   *
+   * It may not always be possible to honor the `checked` parameter.
+   * If the isolate code was pre-compiled, it may not be possible to change
+   * the checked mode setting dynamically.
+   * In that case, the `checked` parameter is ignored.
+   *
+   * WARNING: The [checked] parameter is not implemented on all platforms yet.
+   *
+   * If the [packageConfig] parameter is provided, then it is used to find the
+   * location of a package resolution configuration file for the spawned
+   * isolate.
+   *
+   * If the [automaticPackageResolution] parameter is provided, then the
+   * location of the package sources in the spawned isolate is automatically
+   * determined.
+   *
+   * The [environment] is a mapping from strings to strings which the
+   * spawned isolate uses when looking up [String.fromEnvironment] values.
+   * The system may add its own entries to environment as well.
+   * If `environment` is omitted, the spawned isolate has the same environment
+   * declarations as the spawning isolate.
+   *
+   * WARNING: The [environment] parameter is not implemented on all
+   * platforms yet.
+   *
+   * If [debugName] is provided, the spawned [Isolate] will be identifiable by
+   * this name in debuggers and logging.
+   *
+   * Returns a future that will complete with an [Isolate] instance if the
+   * spawning succeeded. It will complete with an error otherwise.
+   */
+  external static Future<Isolate> spawnUri(
+      Uri uri,
+      List<String> args,
+      var message,
+      {bool paused: false,
+      SendPort onExit,
+      SendPort onError,
+      bool errorsAreFatal,
+      bool checked,
+      Map<String, String> environment,
+      @Deprecated('The packages/ dir is not supported in Dart 2')
+          Uri packageRoot,
+      Uri packageConfig,
+      bool automaticPackageResolution: false,
+      @Since("2.3")
+          String debugName});
+
+  /**
+   * Requests the isolate to pause.
+   *
+   * When the isolate receives the pause command, it stops
+   * processing events from the event loop queue.
+   * It may still add new events to the queue in response to, e.g., timers
+   * or receive-port messages. When the isolate is resumed,
+   * it starts handling the already enqueued events.
+   *
+   * The pause request is sent through the isolate's command port,
+   * which bypasses the receiving isolate's event loop.
+   * The pause takes effect when it is received, pausing the event loop
+   * as it is at that time.
+   *
+   * The [resumeCapability] is used to identity the pause,
+   * and must be used again to end the pause using [resume].
+   * If [resumeCapability] is omitted, a new capability object is created
+   * and used instead.
+   *
+   * If an isolate is paused more than once using the same capability,
+   * only one resume with that capability is needed to end the pause.
+   *
+   * If an isolate is paused using more than one capability,
+   * each pause must be individually ended before the isolate resumes.
+   *
+   * Returns the capability that must be used to end the pause.
+   * This is either [resumeCapability], or a new capability when
+   * [resumeCapability] is omitted.
+   *
+   * If [pauseCapability] is `null`, or it's not the pause capability
+   * of the isolate identified by [controlPort],
+   * the pause request is ignored by the receiving isolate.
+   */
+  Capability pause([Capability resumeCapability]) {
+    resumeCapability ??= new Capability();
+    _pause(resumeCapability);
+    return resumeCapability;
+  }
+
+  /** Internal implementation of [pause]. */
+  external void _pause(Capability resumeCapability);
+
+  /**
+   * Resumes a paused isolate.
+   *
+   * Sends a message to an isolate requesting that it ends a pause
+   * that was previously requested.
+   *
+   * When all active pause requests have been cancelled, the isolate
+   * will continue processing events and handling normal messages.
+   *
+   * If the [resumeCapability] is not one that has previously been used
+   * to pause the isolate, or it has already been used to resume from
+   * that pause, the resume call has no effect.
+   */
+  external void resume(Capability resumeCapability);
+
+  /**
+   * Requests an exit message on [responsePort] when the isolate terminates.
+   *
+   * The isolate will send [response] as a message on [responsePort] as the last
+   * thing before it terminates. It will run no further code after the message
+   * has been sent.
+   *
+   * Adding the same port more than once will only cause it to receive one exit
+   * message, using the last response value that was added,
+   * and it only needs to be removed once using [removeOnExitListener].
+   *
+   * If the isolate has terminated before it can receive this request,
+   * no exit message will be sent.
+   *
+   * The [response] object must follow the same restrictions as enforced by
+   * [SendPort.send].
+   * It is recommended to only use simple values that can be sent to all
+   * isolates, like `null`, booleans, numbers or strings.
+   *
+   * Since isolates run concurrently, it's possible for it to exit before the
+   * exit listener is established, and in that case no response will be
+   * sent on [responsePort].
+   * To avoid this, either use the corresponding parameter to the spawn
+   * function, or start the isolate paused, add the listener and
+   * then resume the isolate.
+   */
+  /* TODO(lrn): Can we do better? Can the system recognize this message and
+   * send a reply if the receiving isolate is dead?
+   */
+  external void addOnExitListener(SendPort responsePort, {Object response});
+
+  /**
+   * Stops listening for exit messages from the isolate.
+   *
+   * Requests for the isolate to not send exit messages on [responsePort].
+   * If the isolate isn't expecting to send exit messages on [responsePort],
+   * because the port hasn't been added using [addOnExitListener],
+   * or because it has already been removed, the request is ignored.
+   *
+   * If the same port has been passed via [addOnExitListener] more than once,
+   * only one call to `removeOnExitListener` is needed to stop it from receiving
+   * exit messages.
+   *
+   * Closing the receive port that is associated with the [responsePort] does
+   * not stop the isolate from sending uncaught errors, they are just going to
+   * be lost.
+   *
+   * An exit message may still be sent if the isolate terminates
+   * before this request is received and processed.
+   */
+  external void removeOnExitListener(SendPort responsePort);
+
+  /**
+   * Sets whether uncaught errors will terminate the isolate.
+   *
+   * If errors are fatal, any uncaught error will terminate the isolate
+   * event loop and shut down the isolate.
+   *
+   * This call requires the [terminateCapability] for the isolate.
+   * If the capability is absent or incorrect, no change is made.
+   *
+   * Since isolates run concurrently, it's possible for the receiving isolate
+   * to exit due to an error, before a request, using this method, has been
+   * received and processed.
+   * To avoid this, either use the corresponding parameter to the spawn
+   * function, or start the isolate paused, set errors non-fatal and
+   * then resume the isolate.
+   */
+  external void setErrorsFatal(bool errorsAreFatal);
+
+  /**
+   * Requests the isolate to shut down.
+   *
+   * The isolate is requested to terminate itself.
+   * The [priority] argument specifies when this must happen.
+   *
+   * The [priority], when provided, must be one of [immediate] or
+   * [beforeNextEvent] (the default).
+   * The shutdown is performed at different times depending on the priority:
+   *
+   * * `immediate`: The isolate shuts down as soon as possible.
+   *     Control messages are handled in order, so all previously sent control
+   *     events from this isolate will all have been processed.
+   *     The shutdown should happen no later than if sent with
+   *     `beforeNextEvent`.
+   *     It may happen earlier if the system has a way to shut down cleanly
+   *     at an earlier time, even during the execution of another event.
+   * * `beforeNextEvent`: The shutdown is scheduled for the next time
+   *     control returns to the event loop of the receiving isolate,
+   *     after the current event, and any already scheduled control events,
+   *     are completed.
+   *
+   * If [terminateCapability] is `null`, or it's not the terminate capability
+   * of the isolate identified by [controlPort],
+   * the kill request is ignored by the receiving isolate.
+   */
+  external void kill({int priority: beforeNextEvent});
+
+  /**
+   * Requests that the isolate send [response] on the [responsePort].
+   *
+   * The [response] object must follow the same restrictions as enforced by
+   * [SendPort.send].
+   * It is recommended to only use simple values that can be sent to all
+   * isolates, like `null`, booleans, numbers or strings.
+   *
+   * If the isolate is alive, it will eventually send `response`
+   * (defaulting to `null`) on the response port.
+   *
+   * The [priority] must be one of [immediate] or [beforeNextEvent].
+   * The response is sent at different times depending on the ping type:
+   *
+   * * `immediate`: The isolate responds as soon as it receives the
+   *     control message. This is after any previous control message
+   *     from the same isolate has been received and processed,
+   *     but may be during execution of another event.
+   * * `beforeNextEvent`: The response is scheduled for the next time
+   *     control returns to the event loop of the receiving isolate,
+   *     after the current event, and any already scheduled control events,
+   *     are completed.
+   */
+  external void ping(SendPort responsePort,
+      {Object response, int priority: immediate});
+
+  /**
+   * Requests that uncaught errors of the isolate are sent back to [port].
+   *
+   * The errors are sent back as two elements lists.
+   * The first element is a `String` representation of the error, usually
+   * created by calling `toString` on the error.
+   * The second element is a `String` representation of an accompanying
+   * stack trace, or `null` if no stack trace was provided.
+   * To convert this back to a [StackTrace] object, use [StackTrace.fromString].
+   *
+   * Listening using the same port more than once does nothing.
+   * A port will only receive each error once,
+   * and will only need to be removed once using [removeErrorListener].
+
+   * Closing the receive port that is associated with the port does not stop
+   * the isolate from sending uncaught errors, they are just going to be lost.
+   * Instead use [removeErrorListener] to stop receiving errors on [port].
+   *
+   * Since isolates run concurrently, it's possible for it to exit before the
+   * error listener is established. To avoid this, start the isolate paused,
+   * add the listener and then resume the isolate.
+   */
+  external void addErrorListener(SendPort port);
+
+  /**
+   * Stops listening for uncaught errors from the isolate.
+   *
+   * Requests for the isolate to not send uncaught errors on [port].
+   * If the isolate isn't expecting to send uncaught errors on [port],
+   * because the port hasn't been added using [addErrorListener],
+   * or because it has already been removed, the request is ignored.
+   *
+   * If the same port has been passed via [addErrorListener] more than once,
+   * only one call to `removeErrorListener` is needed to stop it from receiving
+   * uncaught errors.
+   *
+   * Uncaught errors message may still be sent by the isolate
+   * until this request is received and processed.
+   */
+  external void removeErrorListener(SendPort port);
+
+  /**
+   * Returns a broadcast stream of uncaught errors from the isolate.
+   *
+   * Each error is provided as an error event on the stream.
+   *
+   * The actual error object and stackTraces will not necessarily
+   * be the same object types as in the actual isolate, but they will
+   * always have the same [Object.toString] result.
+   *
+   * This stream is based on [addErrorListener] and [removeErrorListener].
+   */
+  Stream get errors {
+    StreamController controller;
+    RawReceivePort port;
+    void handleError(message) {
+      List listMessage = message;
+      String errorDescription = listMessage[0];
+      String stackDescription = listMessage[1];
+      var error = new RemoteError(errorDescription, stackDescription);
+      controller.addError(error, error.stackTrace);
+    }
+
+    controller = new StreamController.broadcast(
+        sync: true,
+        onListen: () {
+          port = new RawReceivePort(handleError);
+          this.addErrorListener(port.sendPort);
+        },
+        onCancel: () {
+          this.removeErrorListener(port.sendPort);
+          port.close();
+          port = null;
+        });
+    return controller.stream;
+  }
+}
+
+/**
+ * Sends messages to its [ReceivePort]s.
+ *
+ * [SendPort]s are created from [ReceivePort]s. Any message sent through
+ * a [SendPort] is delivered to its corresponding [ReceivePort]. There might be
+ * many [SendPort]s for the same [ReceivePort].
+ *
+ * [SendPort]s can be transmitted to other isolates, and they preserve equality
+ * when sent.
+ */
+abstract class SendPort implements Capability {
+  /**
+   * Sends an asynchronous [message] through this send port, to its
+   * corresponding `ReceivePort`.
+   *
+   * The content of [message] can be: primitive values (null, num, bool, double,
+   * String), instances of [SendPort], and lists and maps whose elements are any
+   * of these. List and maps are also allowed to be cyclic.
+   *
+   * In the special circumstances when two isolates share the same code and are
+   * running in the same process (e.g. isolates created via [Isolate.spawn]), it
+   * is also possible to send object instances (which would be copied in the
+   * process). This is currently only supported by the dartvm.  For now, the
+   * dart2js compiler only supports the restricted messages described above.
+   *
+   * The send happens immediately and doesn't block.  The corresponding receive
+   * port can receive the message as soon as its isolate's event loop is ready
+   * to deliver it, independently of what the sending isolate is doing.
+   */
+  void send(var message);
+
+  /**
+   * Tests whether [other] is a [SendPort] pointing to the same
+   * [ReceivePort] as this one.
+   */
+  bool operator ==(var other);
+
+  /**
+   * Returns an immutable hash code for this send port that is
+   * consistent with the == operator.
+   */
+  int get hashCode;
+}
+
+/**
+ * Together with [SendPort], the only means of communication between isolates.
+ *
+ * [ReceivePort]s have a `sendPort` getter which returns a [SendPort].
+ * Any message that is sent through this [SendPort]
+ * is delivered to the [ReceivePort] it has been created from. There, the
+ * message is dispatched to the `ReceivePort`'s listener.
+ *
+ * A [ReceivePort] is a non-broadcast stream. This means that it buffers
+ * incoming messages until a listener is registered. Only one listener can
+ * receive messages. See [Stream.asBroadcastStream] for transforming the port
+ * to a broadcast stream.
+ *
+ * A [ReceivePort] may have many [SendPort]s.
+ */
+abstract class ReceivePort implements Stream {
+  /**
+   * Opens a long-lived port for receiving messages.
+   *
+   * A [ReceivePort] is a non-broadcast stream. This means that it buffers
+   * incoming messages until a listener is registered. Only one listener can
+   * receive messages. See [Stream.asBroadcastStream] for transforming the port
+   * to a broadcast stream.
+   *
+   * A receive port is closed by canceling its subscription.
+   */
+  external factory ReceivePort();
+
+  /**
+   * Creates a [ReceivePort] from a [RawReceivePort].
+   *
+   * The handler of the given [rawPort] is overwritten during the construction
+   * of the result.
+   */
+  external factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort);
+
+  /**
+   * Inherited from [Stream].
+   *
+   * Note that [onError] and [cancelOnError] are ignored since a ReceivePort
+   * will never receive an error.
+   *
+   * The [onDone] handler will be called when the stream closes.
+   * The stream closes when [close] is called.
+   */
+  StreamSubscription listen(void onData(var message),
+      {Function onError, void onDone(), bool cancelOnError});
+
+  /**
+   * Closes `this`.
+   *
+   * If the stream has not been canceled yet, adds a close-event to the event
+   * queue and discards any further incoming messages.
+   *
+   * If the stream has already been canceled this method has no effect.
+   */
+  void close();
+
+  /**
+   * Returns a [SendPort] that sends to this receive port.
+   */
+  SendPort get sendPort;
+}
+
+abstract class RawReceivePort {
+  /**
+   * Opens a long-lived port for receiving messages.
+   *
+   * A [RawReceivePort] is low level and does not work with [Zone]s. It
+   * can not be paused. The data-handler must be set before the first
+   * event is received.
+   */
+  external factory RawReceivePort([Function handler]);
+
+  /**
+   * Sets the handler that is invoked for every incoming message.
+   *
+   * The handler is invoked in the root-zone ([Zone.root]).
+   */
+  void set handler(Function newHandler);
+
+  /**
+   * Closes the port.
+   *
+   * After a call to this method any incoming message is silently dropped.
+   */
+  void close();
+
+  /**
+   * Returns a [SendPort] that sends to this raw receive port.
+   */
+  SendPort get sendPort;
+}
+
+/**
+ * Description of an error from another isolate.
+ *
+ * This error has the same `toString()` and `stackTrace.toString()` behavior
+ * as the original error, but has no other features of the original error.
+ */
+class RemoteError implements Error {
+  final String _description;
+  final StackTrace stackTrace;
+  RemoteError(String description, String stackDescription)
+      : _description = description,
+        stackTrace = new StackTrace.fromString(stackDescription);
+  String toString() => _description;
+}
+
+/**
+ * An efficiently transferable sequence of byte values.
+ *
+ * A [TransferableTypedData] is created from a number of bytes.
+ * This will take time proportional to the number of bytes.
+ *
+ * The [TransferableTypedData] can be moved between isolates, so
+ * sending it through a send port will only take constant time.
+ *
+ * When sent this way, the local transferable can no longer be materialized,
+ * and the received object is now the only way to materialize the data.
+ */
+@Since("2.3.2")
+abstract class TransferableTypedData {
+  /**
+   * Creates a new [TransferableTypedData] containing the bytes of [list].
+   *
+   * It must be possible to create a single [Uint8List] containing the
+   * bytes, so if there are more bytes than what the platform allows in
+   * a single [Uint8List], then creation fails.
+   */
+  external factory TransferableTypedData.fromList(List<TypedData> list);
+
+  /**
+   * Creates a new [ByteBuffer] containing the bytes stored in this [TransferableTypedData].
+   *
+   * The [TransferableTypedData] is a cross-isolate single-use resource.
+   * This method must not be called more than once on the same underlying
+   * transferable bytes, even if the calls occur in different isolates.
+   */
+  ByteBuffer materialize();
+}
diff --git a/sdk_nnbd/lib/isolate/isolate_sources.gni b/sdk_nnbd/lib/isolate/isolate_sources.gni
new file mode 100644
index 0000000..8af8ba1
--- /dev/null
+++ b/sdk_nnbd/lib/isolate/isolate_sources.gni
@@ -0,0 +1,10 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+isolate_sdk_sources = [
+  "isolate.dart",
+
+  # The above file needs to be first as it lists the parts below.
+  "capability.dart",
+]
diff --git a/sdk_nnbd/lib/js/_js.dart b/sdk_nnbd/lib/js/_js.dart
new file mode 100644
index 0000000..aef7ef9
--- /dev/null
+++ b/sdk_nnbd/lib/js/_js.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Helper library used by `dart:js`.
+///
+/// This library hides any logic that is specific to the web, and allows us to
+/// support `dart:js` for compiling to javascript on the server (e.g. to target
+/// nodejs).
+library dart._js;
+
+/// Whether `o` is a browser object such as `Blob`, `Event`, `KeyRange`,
+/// `ImageData`, `Node`, and `Window`.
+///
+/// On non-web targets, this function always returns false.
+external bool isBrowserObject(dynamic o);
+
+/// Convert a browser object to it's Dart counterpart. None of these types are
+/// wrapped, but this function is needed to inform dart2js about the possible
+/// types that are used and that therefore cannot be tree-shaken.
+external Object convertFromBrowserObject(dynamic o);
diff --git a/sdk_nnbd/lib/js/_js_client.dart b/sdk_nnbd/lib/js/_js_client.dart
new file mode 100644
index 0000000..de25540
--- /dev/null
+++ b/sdk_nnbd/lib/js/_js_client.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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:html' show Blob, Event, ImageData, Node, Window, WorkerGlobalScope;
+import 'dart:indexed_db' show KeyRange;
+import 'dart:_js_helper' show patch;
+import 'dart:_foreign_helper' show JS;
+
+@patch
+bool isBrowserObject(dynamic o) =>
+    o is Blob ||
+    o is Event ||
+    o is KeyRange ||
+    o is ImageData ||
+    o is Node ||
+    o is Window ||
+    o is WorkerGlobalScope;
+
+@patch
+Object convertFromBrowserObject(dynamic o) =>
+    JS('Blob|Event|KeyRange|ImageData|Node|Window|WorkerGlobalScope', '#', o);
diff --git a/sdk_nnbd/lib/js/_js_server.dart b/sdk_nnbd/lib/js/_js_server.dart
new file mode 100644
index 0000000..b941d77
--- /dev/null
+++ b/sdk_nnbd/lib/js/_js_server.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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:_js_helper' show patch;
+
+@patch
+bool isBrowserObject(dynamic o) => false;
+
+@patch
+Object convertFromBrowserObject(dynamic o) => o;
diff --git a/sdk_nnbd/lib/js/dart2js/js_dart2js.dart b/sdk_nnbd/lib/js/dart2js/js_dart2js.dart
new file mode 100644
index 0000000..535227b
--- /dev/null
+++ b/sdk_nnbd/lib/js/dart2js/js_dart2js.dart
@@ -0,0 +1,719 @@
+// 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.
+
+/**
+ * Support for interoperating with JavaScript.
+ *
+ * This library provides access to JavaScript objects from Dart, allowing
+ * Dart code to get and set properties, and call methods of JavaScript objects
+ * and invoke JavaScript functions. The library takes care of converting
+ * between Dart and JavaScript objects where possible, or providing proxies if
+ * conversion isn't possible.
+ *
+ * This library does not yet make Dart objects usable from JavaScript, their
+ * methods and proeprties are not accessible, though it does allow Dart
+ * functions to be passed into and called from JavaScript.
+ *
+ * [JsObject] is the core type and represents a proxy of a JavaScript object.
+ * JsObject gives access to the underlying JavaScript objects properties and
+ * methods. `JsObject`s can be acquired by calls to JavaScript, or they can be
+ * created from proxies to JavaScript constructors.
+ *
+ * The top-level getter [context] provides a [JsObject] that represents the
+ * global object in JavaScript, usually `window`.
+ *
+ * The following example shows an alert dialog via a JavaScript call to the
+ * global function `alert()`:
+ *
+ *     import 'dart:js';
+ *
+ *     main() => context.callMethod('alert', ['Hello from Dart!']);
+ *
+ * This example shows how to create a [JsObject] from a JavaScript constructor
+ * and access its properties:
+ *
+ *     import 'dart:js';
+ *
+ *     main() {
+ *       var object = new JsObject(context['Object']);
+ *       object['greeting'] = 'Hello';
+ *       object['greet'] = (name) => "${object['greeting']} $name";
+ *       var message = object.callMethod('greet', ['JavaScript']);
+ *       context['console'].callMethod('log', [message]);
+ *     }
+ *
+ * ## Proxying and automatic conversion
+ *
+ * When setting properties on a JsObject or passing arguments to a Javascript
+ * method or function, Dart objects are automatically converted or proxied to
+ * JavaScript objects. When accessing JavaScript properties, or when a Dart
+ * closure is invoked from JavaScript, the JavaScript objects are also
+ * converted to Dart.
+ *
+ * Functions and closures are proxied in such a way that they are callable. A
+ * Dart closure assigned to a JavaScript property is proxied by a function in
+ * JavaScript. A JavaScript function accessed from Dart is proxied by a
+ * [JsFunction], which has a [apply] method to invoke it.
+ *
+ * The following types are transferred directly and not proxied:
+ *
+ *   * Basic types: `null`, `bool`, `num`, `String`, `DateTime`
+ *   * `TypedData`, including its subclasses like `Int32List`, but _not_
+ *     `ByteBuffer`
+ *   * When compiling for the web, also: `Blob`, `Event`, `ImageData`,
+ *     `KeyRange`, `Node`, and `Window`.
+ *
+ * ## Converting collections with JsObject.jsify()
+ *
+ * To create a JavaScript collection from a Dart collection use the
+ * [JsObject.jsify] constructor, which converts Dart [Map]s and [Iterable]s
+ * into JavaScript Objects and Arrays.
+ *
+ * The following expression creates a new JavaScript object with the properties
+ * `a` and `b` defined:
+ *
+ *     var jsMap = new JsObject.jsify({'a': 1, 'b': 2});
+ *
+ * This expression creates a JavaScript array:
+ *
+ *     var jsArray = new JsObject.jsify([1, 2, 3]);
+ *
+ * {@category Web}
+ */
+library dart.js;
+
+import 'dart:collection' show HashMap, ListMixin;
+import 'dart:typed_data' show TypedData;
+
+import 'dart:_foreign_helper' show JS, JS_CONST, DART_CLOSURE_TO_JS;
+import 'dart:_interceptors'
+    show
+        JavaScriptFunction,
+        JavaScriptObject,
+        UnknownJavaScriptObject,
+        DART_CLOSURE_PROPERTY_NAME;
+import 'dart:_js_helper'
+    show Primitives, convertDartClosureToJS, getIsolateAffinityTag;
+import 'dart:_js' show isBrowserObject, convertFromBrowserObject;
+
+export 'dart:_interceptors' show JavaScriptObject;
+
+final JsObject context = _wrapToDart(JS('', 'self'));
+
+_convertDartFunction(Function f, {bool captureThis: false}) {
+  return JS(
+      'JavaScriptFunction',
+      '''
+        function(_call, f, captureThis) {
+          return function() {
+            return _call(f, captureThis, this,
+                Array.prototype.slice.apply(arguments));
+          }
+        }(#, #, #)
+      ''',
+      DART_CLOSURE_TO_JS(_callDartFunction),
+      f,
+      captureThis);
+}
+
+_callDartFunction(callback, bool captureThis, self, List arguments) {
+  if (captureThis) {
+    arguments = [self]..addAll(arguments);
+  }
+  var dartArgs = new List.from(arguments.map(_convertToDart));
+  return _convertToJS(Function.apply(callback, dartArgs));
+}
+
+/**
+ * Proxies a JavaScript object to Dart.
+ *
+ * The properties of the JavaScript object are accessible via the `[]` and
+ * `[]=` operators. Methods are callable via [callMethod].
+ */
+class JsObject {
+  // The wrapped JS object.
+  final dynamic _jsObject;
+
+  // This shoud only be called from _wrapToDart
+  JsObject._fromJs(this._jsObject) {
+    assert(_jsObject != null);
+  }
+
+  /**
+   * Constructs a new JavaScript object from [constructor] and returns a proxy
+   * to it.
+   */
+  factory JsObject(JsFunction constructor, [List arguments]) {
+    var constr = _convertToJS(constructor);
+    if (arguments == null) {
+      return _wrapToDart(JS('', 'new #()', constr));
+    }
+
+    if (JS('bool', '# instanceof Array', arguments)) {
+      int argumentCount = JS('int', '#.length', arguments);
+      switch (argumentCount) {
+        case 0:
+          return _wrapToDart(JS('', 'new #()', constr));
+
+        case 1:
+          var arg0 = _convertToJS(JS('', '#[0]', arguments));
+          return _wrapToDart(JS('', 'new #(#)', constr, arg0));
+
+        case 2:
+          var arg0 = _convertToJS(JS('', '#[0]', arguments));
+          var arg1 = _convertToJS(JS('', '#[1]', arguments));
+          return _wrapToDart(JS('', 'new #(#, #)', constr, arg0, arg1));
+
+        case 3:
+          var arg0 = _convertToJS(JS('', '#[0]', arguments));
+          var arg1 = _convertToJS(JS('', '#[1]', arguments));
+          var arg2 = _convertToJS(JS('', '#[2]', arguments));
+          return _wrapToDart(
+              JS('', 'new #(#, #, #)', constr, arg0, arg1, arg2));
+
+        case 4:
+          var arg0 = _convertToJS(JS('', '#[0]', arguments));
+          var arg1 = _convertToJS(JS('', '#[1]', arguments));
+          var arg2 = _convertToJS(JS('', '#[2]', arguments));
+          var arg3 = _convertToJS(JS('', '#[3]', arguments));
+          return _wrapToDart(
+              JS('', 'new #(#, #, #, #)', constr, arg0, arg1, arg2, arg3));
+      }
+    }
+
+    // The following code solves the problem of invoking a JavaScript
+    // constructor with an unknown number arguments.
+    // First bind the constructor to the argument list using bind.apply().
+    // The first argument to bind() is the binding of 'this', so add 'null' to
+    // the arguments list passed to apply().
+    // After that, use the JavaScript 'new' operator which overrides any binding
+    // of 'this' with the new instance.
+    var args = <dynamic>[null]..addAll(arguments.map(_convertToJS));
+    var factoryFunction = JS('', '#.bind.apply(#, #)', constr, constr, args);
+    // Without this line, calling factoryFunction as a constructor throws
+    JS('String', 'String(#)', factoryFunction);
+    // This could return an UnknownJavaScriptObject, or a native
+    // object for which there is an interceptor
+    var jsObj = JS('', 'new #()', factoryFunction);
+
+    return _wrapToDart(jsObj);
+
+    // TODO(sra): Investigate:
+    //
+    //     var jsObj = JS('', 'Object.create(#.prototype)', constr);
+    //     JS('', '#.apply(#, #)', constr, jsObj,
+    //         []..addAll(arguments.map(_convertToJS)));
+    //     return _wrapToDart(jsObj);
+  }
+
+  /**
+   * Constructs a [JsObject] that proxies a native Dart object; _for expert use
+   * only_.
+   *
+   * Use this constructor only if you wish to get access to JavaScript
+   * properties attached to a browser host object, such as a Node or Blob, that
+   * is normally automatically converted into a native Dart object.
+   *
+   * An exception will be thrown if [object] either is `null` or has the type
+   * `bool`, `num`, or `String`.
+   */
+  factory JsObject.fromBrowserObject(object) {
+    if (object is num || object is String || object is bool || object == null) {
+      throw new ArgumentError("object cannot be a num, string, bool, or null");
+    }
+    return _wrapToDart(_convertToJS(object));
+  }
+
+  /**
+   * Recursively converts a JSON-like collection of Dart objects to a
+   * collection of JavaScript objects and returns a [JsObject] proxy to it.
+   *
+   * [object] must be a [Map] or [Iterable], the contents of which are also
+   * converted. Maps and Iterables are copied to a new JavaScript object.
+   * Primitives and other transferrable values are directly converted to their
+   * JavaScript type, and all other objects are proxied.
+   */
+  factory JsObject.jsify(object) {
+    if ((object is! Map) && (object is! Iterable)) {
+      throw new ArgumentError("object must be a Map or Iterable");
+    }
+    return _wrapToDart(_convertDataTree(object));
+  }
+
+  static _convertDataTree(data) {
+    var _convertedObjects = new HashMap.identity();
+
+    _convert(o) {
+      if (_convertedObjects.containsKey(o)) {
+        return _convertedObjects[o];
+      }
+      if (o is Map) {
+        final convertedMap = JS('=Object', '{}');
+        _convertedObjects[o] = convertedMap;
+        for (var key in o.keys) {
+          JS('=Object', '#[#]=#', convertedMap, key, _convert(o[key]));
+        }
+        return convertedMap;
+      } else if (o is Iterable) {
+        var convertedList = [];
+        _convertedObjects[o] = convertedList;
+        convertedList.addAll(o.map(_convert));
+        return convertedList;
+      } else {
+        return _convertToJS(o);
+      }
+    }
+
+    return _convert(data);
+  }
+
+  /**
+   * Returns the value associated with [property] from the proxied JavaScript
+   * object.
+   *
+   * The type of [property] must be either [String] or [num].
+   */
+  dynamic operator [](property) {
+    if (property is! String && property is! num) {
+      throw new ArgumentError("property is not a String or num");
+    }
+    return _convertToDart(JS('', '#[#]', _jsObject, property));
+  }
+
+  /**
+   * Sets the value associated with [property] on the proxied JavaScript
+   * object.
+   *
+   * The type of [property] must be either [String] or [num].
+   */
+  operator []=(property, value) {
+    if (property is! String && property is! num) {
+      throw new ArgumentError("property is not a String or num");
+    }
+    JS('', '#[#]=#', _jsObject, property, _convertToJS(value));
+  }
+
+  int get hashCode => 0;
+
+  bool operator ==(other) =>
+      other is JsObject && JS('bool', '# === #', _jsObject, other._jsObject);
+
+  /**
+   * Returns `true` if the JavaScript object contains the specified property
+   * either directly or though its prototype chain.
+   *
+   * This is the equivalent of the `in` operator in JavaScript.
+   */
+  bool hasProperty(property) {
+    if (property is! String && property is! num) {
+      throw new ArgumentError("property is not a String or num");
+    }
+    return JS('bool', '# in #', property, _jsObject);
+  }
+
+  /**
+   * Removes [property] from the JavaScript object.
+   *
+   * This is the equivalent of the `delete` operator in JavaScript.
+   */
+  void deleteProperty(property) {
+    if (property is! String && property is! num) {
+      throw new ArgumentError("property is not a String or num");
+    }
+    JS('bool', 'delete #[#]', _jsObject, property);
+  }
+
+  /**
+   * Returns `true` if the JavaScript object has [type] in its prototype chain.
+   *
+   * This is the equivalent of the `instanceof` operator in JavaScript.
+   */
+  bool instanceof(JsFunction type) {
+    return JS('bool', '# instanceof #', _jsObject, _convertToJS(type));
+  }
+
+  /**
+   * Returns the result of the JavaScript objects `toString` method.
+   */
+  String toString() {
+    try {
+      return JS('String', 'String(#)', _jsObject);
+    } catch (e) {
+      return super.toString();
+    }
+  }
+
+  /**
+   * Calls [method] on the JavaScript object with the arguments [args] and
+   * returns the result.
+   *
+   * The type of [method] must be either [String] or [num].
+   */
+  dynamic callMethod(method, [List args]) {
+    if (method is! String && method is! num) {
+      throw new ArgumentError("method is not a String or num");
+    }
+    return _convertToDart(JS(
+        '',
+        '#[#].apply(#, #)',
+        _jsObject,
+        method,
+        _jsObject,
+        args == null ? null : new List.from(args.map(_convertToJS))));
+  }
+}
+
+/**
+ * Proxies a JavaScript Function object.
+ */
+class JsFunction extends JsObject {
+  /**
+   * Returns a [JsFunction] that captures its 'this' binding and calls [f]
+   * with the value of this passed as the first argument.
+   */
+  factory JsFunction.withThis(Function f) {
+    var jsFunc = _convertDartFunction(f, captureThis: true);
+    return new JsFunction._fromJs(jsFunc);
+  }
+
+  JsFunction._fromJs(jsObject) : super._fromJs(jsObject);
+
+  /**
+   * Invokes the JavaScript function with arguments [args]. If [thisArg] is
+   * supplied it is the value of `this` for the invocation.
+   */
+  dynamic apply(List args, {thisArg}) => _convertToDart(JS(
+      '',
+      '#.apply(#, #)',
+      _jsObject,
+      _convertToJS(thisArg),
+      args == null ? null : new List.from(args.map(_convertToJS))));
+}
+
+/**
+ * A [List] that proxies a JavaScript array.
+ */
+class JsArray<E> extends JsObject with ListMixin<E> {
+  /**
+   * Creates a new JavaScript array.
+   */
+  JsArray() : super._fromJs([]);
+
+  /**
+   * Creates a new JavaScript array and initializes it to the contents of
+   * [other].
+   */
+  JsArray.from(Iterable<E> other)
+      : super._fromJs([]..addAll(other.map(_convertToJS)));
+
+  JsArray._fromJs(jsObject) : super._fromJs(jsObject);
+
+  _checkIndex(int index) {
+    if (index is int && (index < 0 || index >= length)) {
+      throw new RangeError.range(index, 0, length);
+    }
+  }
+
+  _checkInsertIndex(int index) {
+    if (index is int && (index < 0 || index >= length + 1)) {
+      throw new RangeError.range(index, 0, length);
+    }
+  }
+
+  static _checkRange(int start, int end, int length) {
+    if (start < 0 || start > length) {
+      throw new RangeError.range(start, 0, length);
+    }
+    if (end < start || end > length) {
+      throw new RangeError.range(end, start, length);
+    }
+  }
+
+  // Methods required by ListMixin
+
+  E operator [](dynamic index) {
+    // TODO(justinfagnani): fix the semantics for non-ints
+    // dartbug.com/14605
+    if (index is num && index == index.toInt()) {
+      _checkIndex(index);
+    }
+    return super[index];
+  }
+
+  void operator []=(dynamic index, E value) {
+    // TODO(justinfagnani): fix the semantics for non-ints
+    // dartbug.com/14605
+    if (index is num && index == index.toInt()) {
+      _checkIndex(index);
+    }
+    super[index] = value;
+  }
+
+  int get length {
+    // Check the length honours the List contract.
+    var len = JS('', '#.length', _jsObject);
+    // JavaScript arrays have lengths which are unsigned 32-bit integers.
+    if (JS('bool', 'typeof # === "number" && (# >>> 0) === #', len, len, len)) {
+      return JS('int', '#', len);
+    }
+    throw new StateError('Bad JsArray length');
+  }
+
+  void set length(int length) {
+    super['length'] = length;
+  }
+
+  // Methods overridden for better performance
+
+  void add(E value) {
+    callMethod('push', [value]);
+  }
+
+  void addAll(Iterable<E> iterable) {
+    var list = (JS('bool', '# instanceof Array', iterable))
+        ? iterable
+        : new List.from(iterable);
+    callMethod('push', list);
+  }
+
+  void insert(int index, E element) {
+    _checkInsertIndex(index);
+    callMethod('splice', [index, 0, element]);
+  }
+
+  E removeAt(int index) {
+    _checkIndex(index);
+    return callMethod('splice', [index, 1])[0];
+  }
+
+  E removeLast() {
+    if (length == 0) throw new RangeError(-1);
+    return callMethod('pop');
+  }
+
+  void removeRange(int start, int end) {
+    _checkRange(start, end, length);
+    callMethod('splice', [start, end - start]);
+  }
+
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+    _checkRange(start, end, this.length);
+    int length = end - start;
+    if (length == 0) return;
+    if (skipCount < 0) throw new ArgumentError(skipCount);
+    var args = <dynamic>[start, length]
+      ..addAll(iterable.skip(skipCount).take(length));
+    callMethod('splice', args);
+  }
+
+  void sort([int compare(E a, E b)]) {
+    // Note: arr.sort(null) is a type error in FF
+    callMethod('sort', compare == null ? [] : [compare]);
+  }
+}
+
+// property added to a Dart object referencing its JS-side DartObject proxy
+final String _DART_OBJECT_PROPERTY_NAME =
+    getIsolateAffinityTag(r'_$dart_dartObject');
+
+// property added to a JS object referencing its Dart-side JsObject proxy
+const _JS_OBJECT_PROPERTY_NAME = r'_$dart_jsObject';
+const _JS_FUNCTION_PROPERTY_NAME = r'$dart_jsFunction';
+const _JS_FUNCTION_PROPERTY_NAME_CAPTURE_THIS = r'_$dart_jsFunctionCaptureThis';
+
+bool _defineProperty(o, String name, value) {
+  try {
+    if (_isExtensible(o) &&
+        // TODO(ahe): Calling _hasOwnProperty to work around
+        // https://code.google.com/p/dart/issues/detail?id=21331.
+        !_hasOwnProperty(o, name)) {
+      JS('void', 'Object.defineProperty(#, #, { value: #})', o, name, value);
+      return true;
+    }
+  } catch (e) {
+    // object is native and lies about being extensible
+    // see https://bugzilla.mozilla.org/show_bug.cgi?id=775185
+    // Or, isExtensible throws for this object.
+  }
+  return false;
+}
+
+bool _hasOwnProperty(o, String name) {
+  return JS('bool', 'Object.prototype.hasOwnProperty.call(#, #)', o, name);
+}
+
+bool _isExtensible(o) => JS('bool', 'Object.isExtensible(#)', o);
+
+Object _getOwnProperty(o, String name) {
+  if (_hasOwnProperty(o, name)) {
+    return JS('', '#[#]', o, name);
+  }
+  return null;
+}
+
+bool _isLocalObject(o) => JS('bool', '# instanceof Object', o);
+
+// The shared constructor function for proxies to Dart objects in JavaScript.
+final _dartProxyCtor = JS('', 'function DartObject(o) { this.o = o; }');
+
+dynamic _convertToJS(dynamic o) {
+  // Note: we don't write `if (o == null) return null;` to make sure dart2js
+  // doesn't convert `return null;` into `return;` (which would make `null` be
+  // `undefined` in Javascprit). See dartbug.com/20305 for details.
+  if (o == null || o is String || o is num || o is bool) {
+    return o;
+  }
+  if (o is JsObject) {
+    return o._jsObject;
+  }
+  if (isBrowserObject(o)) {
+    return o;
+  }
+  if (o is TypedData) {
+    return o;
+  }
+  if (o is DateTime) {
+    return Primitives.lazyAsJsDate(o);
+  }
+  if (o is Function) {
+    return _getJsProxy(o, _JS_FUNCTION_PROPERTY_NAME, (o) {
+      var jsFunction = _convertDartFunction(o);
+      // set a property on the JS closure referencing the Dart closure
+      _defineProperty(jsFunction, DART_CLOSURE_PROPERTY_NAME, o);
+      return jsFunction;
+    });
+  }
+  var ctor = _dartProxyCtor;
+  return _getJsProxy(
+      o, _JS_OBJECT_PROPERTY_NAME, (o) => JS('', 'new #(#)', ctor, o));
+}
+
+Object _getJsProxy(o, String propertyName, createProxy(o)) {
+  var jsProxy = _getOwnProperty(o, propertyName);
+  if (jsProxy == null) {
+    jsProxy = createProxy(o);
+    _defineProperty(o, propertyName, jsProxy);
+  }
+  return jsProxy;
+}
+
+// converts a Dart object to a reference to a native JS object
+// which might be a DartObject JS->Dart proxy
+Object _convertToDart(o) {
+  if (JS('bool', '# == null', o) ||
+      JS('bool', 'typeof # == "string"', o) ||
+      JS('bool', 'typeof # == "number"', o) ||
+      JS('bool', 'typeof # == "boolean"', o)) {
+    return o;
+  } else if (_isLocalObject(o) && isBrowserObject(o)) {
+    return convertFromBrowserObject(o);
+  } else if (_isLocalObject(o) && o is TypedData) {
+    return JS('TypedData', '#', o);
+  } else if (JS('bool', '# instanceof Date', o)) {
+    var ms = JS('num', '#.getTime()', o);
+    return new DateTime.fromMillisecondsSinceEpoch(ms);
+  } else if (JS('bool', '#.constructor === #', o, _dartProxyCtor)) {
+    return JS('', '#.o', o);
+  } else {
+    return _wrapToDart(o);
+  }
+}
+
+Object _wrapToDart(o) {
+  if (JS('bool', 'typeof # == "function"', o)) {
+    return _getDartProxy(
+        o, DART_CLOSURE_PROPERTY_NAME, (o) => new JsFunction._fromJs(o));
+  }
+  if (JS('bool', '# instanceof Array', o)) {
+    return _getDartProxy(
+        o, _DART_OBJECT_PROPERTY_NAME, (o) => new JsArray._fromJs(o));
+  }
+  return _getDartProxy(
+      o, _DART_OBJECT_PROPERTY_NAME, (o) => new JsObject._fromJs(o));
+}
+
+Object _getDartProxy(o, String propertyName, createProxy(o)) {
+  var dartProxy = _getOwnProperty(o, propertyName);
+  // Temporary fix for dartbug.com/15193
+  // In some cases it's possible to see a JavaScript object that
+  // came from a different context and was previously proxied to
+  // Dart in that context. The JS object will have a cached proxy
+  // but it won't be a valid Dart object in this context.
+  // For now we throw away the cached proxy, but we should be able
+  // to cache proxies from multiple JS contexts and Dart isolates.
+  if (dartProxy == null || !_isLocalObject(o)) {
+    dartProxy = createProxy(o);
+    _defineProperty(o, propertyName, dartProxy);
+  }
+  return dartProxy;
+}
+
+// ---------------------------------------------------------------------------
+// Start of methods for new style Dart-JS interop.
+
+_convertDartFunctionFast(Function f) {
+  var existing = JS('', '#.#', f, _JS_FUNCTION_PROPERTY_NAME);
+  if (existing != null) return existing;
+  var ret = JS(
+      'JavaScriptFunction',
+      '''
+        function(_call, f) {
+          return function() {
+            return _call(f, Array.prototype.slice.apply(arguments));
+          }
+        }(#, #)
+      ''',
+      DART_CLOSURE_TO_JS(_callDartFunctionFast),
+      f);
+  JS('', '#.# = #', ret, DART_CLOSURE_PROPERTY_NAME, f);
+  JS('', '#.# = #', f, _JS_FUNCTION_PROPERTY_NAME, ret);
+  return ret;
+}
+
+_convertDartFunctionFastCaptureThis(Function f) {
+  var existing = JS('', '#.#', f, _JS_FUNCTION_PROPERTY_NAME_CAPTURE_THIS);
+  if (existing != null) return existing;
+  var ret = JS(
+      'JavaScriptFunction',
+      '''
+        function(_call, f) {
+          return function() {
+            return _call(f, this,Array.prototype.slice.apply(arguments));
+          }
+        }(#, #)
+      ''',
+      DART_CLOSURE_TO_JS(_callDartFunctionFastCaptureThis),
+      f);
+  JS('', '#.# = #', ret, DART_CLOSURE_PROPERTY_NAME, f);
+  JS('', '#.# = #', f, _JS_FUNCTION_PROPERTY_NAME_CAPTURE_THIS, ret);
+  return ret;
+}
+
+_callDartFunctionFast(callback, List arguments) {
+  return Function.apply(callback, arguments);
+}
+
+_callDartFunctionFastCaptureThis(callback, self, List arguments) {
+  return Function.apply(callback, [self]..addAll(arguments));
+}
+
+F allowInterop<F extends Function>(F f) {
+  if (JS('bool', 'typeof(#) == "function"', f)) {
+    // Already supports interop, just use the existing function.
+    return f;
+  } else {
+    return _convertDartFunctionFast(f);
+  }
+}
+
+Function allowInteropCaptureThis(Function f) {
+  if (JS('bool', 'typeof(#) == "function"', f)) {
+    // Behavior when the function is already a JS function is unspecified.
+    throw new ArgumentError(
+        "Function is already a JS function so cannot capture this.");
+    return f;
+  } else {
+    return _convertDartFunctionFastCaptureThis(f);
+  }
+}
diff --git a/sdk_nnbd/lib/js_util/dart2js/js_util_dart2js.dart b/sdk_nnbd/lib/js_util/dart2js/js_util_dart2js.dart
new file mode 100644
index 0000000..6b605fb
--- /dev/null
+++ b/sdk_nnbd/lib/js_util/dart2js/js_util_dart2js.dart
@@ -0,0 +1,128 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Utility methods to efficiently manipulate typed JSInterop objects in cases
+/// where the name to call is not known at runtime. You should only use these
+/// methods when the same effect cannot be achieved with @JS annotations.
+/// These methods would be extension methods on JSObject if Dart supported
+/// extension methods.
+///
+/// {@category Web}
+library dart.js_util;
+
+import 'dart:_foreign_helper' show JS;
+import 'dart:collection' show HashMap;
+
+/// WARNING: performance of this method is much worse than other util
+/// methods in this library. Only use this method as a last resort.
+///
+/// Recursively converts a JSON-like collection of Dart objects to a
+/// collection of JavaScript objects and returns a [JsObject] proxy to it.
+///
+/// [object] must be a [Map] or [Iterable], the contents of which are also
+/// converted. Maps and Iterables are copied to a new JavaScript object.
+/// Primitives and other transferable values are directly converted to their
+/// JavaScript type, and all other objects are proxied.
+jsify(object) {
+  if ((object is! Map) && (object is! Iterable)) {
+    throw new ArgumentError("object must be a Map or Iterable");
+  }
+  return _convertDataTree(object);
+}
+
+_convertDataTree(data) {
+  var _convertedObjects = new HashMap.identity();
+
+  _convert(o) {
+    if (_convertedObjects.containsKey(o)) {
+      return _convertedObjects[o];
+    }
+    if (o is Map) {
+      final convertedMap = JS('=Object', '{}');
+      _convertedObjects[o] = convertedMap;
+      for (var key in o.keys) {
+        JS('=Object', '#[#]=#', convertedMap, key, _convert(o[key]));
+      }
+      return convertedMap;
+    } else if (o is Iterable) {
+      var convertedList = [];
+      _convertedObjects[o] = convertedList;
+      convertedList.addAll(o.map(_convert));
+      return convertedList;
+    } else {
+      return o;
+    }
+  }
+
+  return _convert(data);
+}
+
+newObject() => JS('=Object', '{}');
+
+bool hasProperty(o, name) => JS('bool', '# in #', name, o);
+getProperty(o, name) => JS('Object|Null', '#[#]', o, name);
+setProperty(o, name, value) => JS('', '#[#]=#', o, name, value);
+
+callMethod(o, String method, List args) =>
+    JS('Object|Null', '#[#].apply(#, #)', o, method, o, args);
+
+bool instanceof(o, Function type) => JS('bool', '# instanceof #', o, type);
+callConstructor(Function constr, List arguments) {
+  if (arguments == null) {
+    return JS('Object', 'new #()', constr);
+  }
+
+  if (JS('bool', '# instanceof Array', arguments)) {
+    int argumentCount = JS('int', '#.length', arguments);
+    switch (argumentCount) {
+      case 0:
+        return JS('Object', 'new #()', constr);
+
+      case 1:
+        var arg0 = JS('', '#[0]', arguments);
+        return JS('Object', 'new #(#)', constr, arg0);
+
+      case 2:
+        var arg0 = JS('', '#[0]', arguments);
+        var arg1 = JS('', '#[1]', arguments);
+        return JS('Object', 'new #(#, #)', constr, arg0, arg1);
+
+      case 3:
+        var arg0 = JS('', '#[0]', arguments);
+        var arg1 = JS('', '#[1]', arguments);
+        var arg2 = JS('', '#[2]', arguments);
+        return JS('Object', 'new #(#, #, #)', constr, arg0, arg1, arg2);
+
+      case 4:
+        var arg0 = JS('', '#[0]', arguments);
+        var arg1 = JS('', '#[1]', arguments);
+        var arg2 = JS('', '#[2]', arguments);
+        var arg3 = JS('', '#[3]', arguments);
+        return JS(
+            'Object', 'new #(#, #, #, #)', constr, arg0, arg1, arg2, arg3);
+    }
+  }
+
+  // The following code solves the problem of invoking a JavaScript
+  // constructor with an unknown number arguments.
+  // First bind the constructor to the argument list using bind.apply().
+  // The first argument to bind() is the binding of 't', so add 'null' to
+  // the arguments list passed to apply().
+  // After that, use the JavaScript 'new' operator which overrides any binding
+  // of 'this' with the new instance.
+  var args = <dynamic>[null]..addAll(arguments);
+  var factoryFunction = JS('', '#.bind.apply(#, #)', constr, constr, args);
+  // Without this line, calling factoryFunction as a constructor throws
+  JS('String', 'String(#)', factoryFunction);
+  // This could return an UnknownJavaScriptObject, or a native
+  // object for which there is an interceptor
+  return JS('Object', 'new #()', factoryFunction);
+
+  // TODO(sra): Investigate:
+  //
+  //     var jsObj = JS('', 'Object.create(#.prototype)', constr);
+  //     JS('', '#.apply(#, #)', constr, jsObj,
+  //         []..addAll(arguments.map(_convertToJS)));
+  //     return _wrapToDart(jsObj);
+}
diff --git a/sdk_nnbd/lib/libraries.json b/sdk_nnbd/lib/libraries.json
new file mode 100644
index 0000000..663991f
--- /dev/null
+++ b/sdk_nnbd/lib/libraries.json
@@ -0,0 +1,490 @@
+{
+  "comment:0": "NOTE: THIS FILE IS GENERATED. DO NOT EDIT.",
+  "comment:1": "Instead modify 'sdk/lib/libraries.yaml' and follow the instructions therein.",
+  "vm": {
+    "libraries": {
+      "_builtin": {
+        "uri": "../../runtime/bin/builtin.dart"
+      },
+      "cli": {
+        "patches": [
+          "../../runtime/bin/cli_patch.dart"
+        ],
+        "uri": "cli/cli.dart"
+      },
+      "core": {
+        "patches": [
+          "../../runtime/lib/core_patch.dart",
+          "../../runtime/lib/array.dart",
+          "../../runtime/lib/array_patch.dart",
+          "../../runtime/lib/bigint_patch.dart",
+          "../../runtime/lib/bool_patch.dart",
+          "../../runtime/lib/date_patch.dart",
+          "../../runtime/lib/double.dart",
+          "../../runtime/lib/double_patch.dart",
+          "../../runtime/lib/errors_patch.dart",
+          "../../runtime/lib/expando_patch.dart",
+          "../../runtime/lib/function.dart",
+          "../../runtime/lib/function_patch.dart",
+          "../../runtime/lib/growable_array.dart",
+          "../../runtime/lib/identical_patch.dart",
+          "../../runtime/lib/immutable_map.dart",
+          "../../runtime/lib/integers.dart",
+          "../../runtime/lib/integers_patch.dart",
+          "../../runtime/lib/invocation_mirror_patch.dart",
+          "../../runtime/lib/lib_prefix.dart",
+          "../../runtime/lib/map_patch.dart",
+          "../../runtime/lib/null_patch.dart",
+          "../../runtime/lib/object_patch.dart",
+          "../../runtime/lib/regexp_patch.dart",
+          "../../runtime/lib/stacktrace.dart",
+          "../../runtime/lib/stopwatch_patch.dart",
+          "../../runtime/lib/string_buffer_patch.dart",
+          "../../runtime/lib/string_patch.dart",
+          "../../runtime/lib/type_patch.dart",
+          "../../runtime/lib/uri_patch.dart",
+          "../../runtime/lib/weak_property.dart"
+        ],
+        "uri": "core/core.dart"
+      },
+      "async": {
+        "patches": [
+          "../../runtime/lib/async_patch.dart",
+          "../../runtime/lib/deferred_load_patch.dart",
+          "../../runtime/lib/schedule_microtask_patch.dart",
+          "../../runtime/lib/timer_patch.dart"
+        ],
+        "uri": "async/async.dart"
+      },
+      "collection": {
+        "patches": [
+          "../../runtime/lib/collection_patch.dart",
+          "../../runtime/lib/compact_hash.dart"
+        ],
+        "uri": "collection/collection.dart"
+      },
+      "ffi": {
+        "patches": [
+          "../../runtime/lib/ffi_patch.dart",
+          "../../runtime/lib/ffi_dynamic_library_patch.dart",
+          "../../runtime/lib/ffi_native_type_patch.dart"
+        ],
+        "uri": "ffi/ffi.dart"
+      },
+      "wasm": {
+        "patches": [
+          "../../runtime/lib/wasm_patch.dart"
+        ],
+        "uri": "wasm/wasm.dart"
+      },
+      "typed_data": {
+        "patches": "../../runtime/lib/typed_data_patch.dart",
+        "uri": "typed_data/typed_data.dart"
+      },
+      "nativewrappers": {
+        "uri": "html/dartium/nativewrappers.dart"
+      },
+      "developer": {
+        "patches": [
+          "../../runtime/lib/developer.dart",
+          "../../runtime/lib/profiler.dart",
+          "../../runtime/lib/timeline.dart"
+        ],
+        "uri": "developer/developer.dart"
+      },
+      "isolate": {
+        "patches": [
+          "../../runtime/lib/isolate_patch.dart",
+          "../../runtime/lib/timer_impl.dart"
+        ],
+        "uri": "isolate/isolate.dart"
+      },
+      "mirrors": {
+        "patches": [
+          "../../runtime/lib/mirrors_patch.dart",
+          "../../runtime/lib/mirrors_impl.dart",
+          "../../runtime/lib/mirror_reference.dart"
+        ],
+        "uri": "mirrors/mirrors.dart"
+      },
+      "_vmservice": {
+        "uri": "vmservice/vmservice.dart"
+      },
+      "io": {
+        "patches": [
+          "../../runtime/bin/common_patch.dart",
+          "../../runtime/bin/directory_patch.dart",
+          "../../runtime/bin/eventhandler_patch.dart",
+          "../../runtime/bin/file_patch.dart",
+          "../../runtime/bin/file_system_entity_patch.dart",
+          "../../runtime/bin/filter_patch.dart",
+          "../../runtime/bin/io_service_patch.dart",
+          "../../runtime/bin/namespace_patch.dart",
+          "../../runtime/bin/platform_patch.dart",
+          "../../runtime/bin/process_patch.dart",
+          "../../runtime/bin/socket_patch.dart",
+          "../../runtime/bin/stdio_patch.dart",
+          "../../runtime/bin/secure_socket_patch.dart",
+          "../../runtime/bin/sync_socket_patch.dart"
+        ],
+        "uri": "io/io.dart"
+      },
+      "_internal": {
+        "patches": [
+          "../../runtime/lib/internal_patch.dart",
+          "../../runtime/lib/class_id_fasta.dart",
+          "../../runtime/lib/print_patch.dart",
+          "../../runtime/lib/symbol_patch.dart",
+          "internal/patch.dart"
+        ],
+        "uri": "internal/internal.dart"
+      },
+      "convert": {
+        "patches": "../../runtime/lib/convert_patch.dart",
+        "uri": "convert/convert.dart"
+      },
+      "profiler": {
+        "uri": "profiler/profiler.dart"
+      },
+      "math": {
+        "patches": "../../runtime/lib/math_patch.dart",
+        "uri": "math/math.dart"
+      },
+      "_http": {
+        "uri": "_http/http.dart"
+      },
+      "vmservice_io": {
+        "uri": "../../runtime/bin/vmservice/vmservice_io.dart"
+      }
+    }
+  },
+  "none": {
+    "libraries": {}
+  },
+  "dart2js": {
+    "libraries": {
+      "async": {
+        "patches": "_internal/js_runtime/lib/async_patch.dart",
+        "uri": "async/async.dart"
+      },
+      "_interceptors": {
+        "uri": "_internal/js_runtime/lib/interceptors.dart"
+      },
+      "mirrors": {
+        "patches": "_internal/js_runtime/lib/mirrors_patch_cfe.dart",
+        "supported": false,
+        "uri": "mirrors/mirrors.dart"
+      },
+      "_js_embedded_names": {
+        "uri": "_internal/js_runtime/lib/shared/embedded_names.dart"
+      },
+      "io": {
+        "patches": "_internal/js_runtime/lib/io_patch.dart",
+        "supported": false,
+        "uri": "io/io.dart"
+      },
+      "_internal": {
+        "patches": "_internal/js_runtime/lib/internal_patch.dart",
+        "uri": "internal/internal.dart"
+      },
+      "_metadata": {
+        "uri": "html/html_common/metadata.dart"
+      },
+      "_async_await_error_codes": {
+        "uri": "_internal/js_runtime/lib/shared/async_await_error_codes.dart"
+      },
+      "_http": {
+        "uri": "_http/http.dart"
+      },
+      "_js_primitives": {
+        "uri": "_internal/js_runtime/lib/js_primitives.dart"
+      },
+      "_js_helper": {
+        "uri": "_internal/js_runtime/lib/js_helper.dart"
+      },
+      "_chrome": {
+        "uri": "_chrome/dart2js/chrome_dart2js.dart"
+      },
+      "js": {
+        "uri": "js/dart2js/js_dart2js.dart"
+      },
+      "html_common": {
+        "uri": "html/html_common/html_common_dart2js.dart"
+      },
+      "_recipe_syntax": {
+        "uri": "_internal/js_runtime/lib/shared/recipe_syntax.dart"
+      },
+      "_native_typed_data": {
+        "uri": "_internal/js_runtime/lib/native_typed_data.dart"
+      },
+      "_js_names": {
+        "uri": "_internal/js_runtime/lib/js_names.dart"
+      },
+      "core": {
+        "patches": "_internal/js_runtime/lib/core_patch.dart",
+        "uri": "core/core.dart"
+      },
+      "collection": {
+        "patches": "_internal/js_runtime/lib/collection_patch.dart",
+        "uri": "collection/collection.dart"
+      },
+      "js_util": {
+        "uri": "js_util/dart2js/js_util_dart2js.dart"
+      },
+      "typed_data": {
+        "patches": "_internal/js_runtime/lib/typed_data_patch.dart",
+        "uri": "typed_data/typed_data.dart"
+      },
+      "web_audio": {
+        "uri": "web_audio/dart2js/web_audio_dart2js.dart"
+      },
+      "html": {
+        "uri": "html/dart2js/html_dart2js.dart"
+      },
+      "isolate": {
+        "patches": "_internal/js_runtime/lib/isolate_patch.dart",
+        "supported": false,
+        "uri": "isolate/isolate.dart"
+      },
+      "developer": {
+        "patches": "_internal/js_runtime/lib/developer_patch.dart",
+        "uri": "developer/developer.dart"
+      },
+      "web_gl": {
+        "uri": "web_gl/dart2js/web_gl_dart2js.dart"
+      },
+      "indexed_db": {
+        "uri": "indexed_db/dart2js/indexed_db_dart2js.dart"
+      },
+      "_js": {
+        "patches": "js/_js_client.dart",
+        "uri": "js/_js.dart"
+      },
+      "convert": {
+        "patches": "_internal/js_runtime/lib/convert_patch.dart",
+        "uri": "convert/convert.dart"
+      },
+      "math": {
+        "patches": "_internal/js_runtime/lib/math_patch.dart",
+        "uri": "math/math.dart"
+      },
+      "_foreign_helper": {
+        "uri": "_internal/js_runtime/lib/foreign_helper.dart"
+      },
+      "web_sql": {
+        "uri": "web_sql/dart2js/web_sql_dart2js.dart"
+      },
+      "_rti": {
+        "uri": "_internal/js_runtime/lib/rti.dart"
+      },
+      "svg": {
+        "uri": "svg/dart2js/svg_dart2js.dart"
+      }
+    }
+  },
+  "dartdevc": {
+    "libraries": {
+      "async": {
+        "patches": "_internal/js_dev_runtime/patch/async_patch.dart",
+        "uri": "async/async.dart"
+      },
+      "_runtime": {
+        "uri": "_internal/js_dev_runtime/private/ddc_runtime/runtime.dart"
+      },
+      "_interceptors": {
+        "uri": "_internal/js_dev_runtime/private/interceptors.dart"
+      },
+      "mirrors": {
+        "patches": "_internal/js_dev_runtime/patch/mirrors_patch.dart",
+        "supported": false,
+        "uri": "mirrors/mirrors.dart"
+      },
+      "_debugger": {
+        "uri": "_internal/js_dev_runtime/private/debugger.dart"
+      },
+      "io": {
+        "patches": "_internal/js_dev_runtime/patch/io_patch.dart",
+        "supported": false,
+        "uri": "io/io.dart"
+      },
+      "_internal": {
+        "patches": "_internal/js_dev_runtime/patch/internal_patch.dart",
+        "uri": "internal/internal.dart"
+      },
+      "_metadata": {
+        "uri": "html/html_common/metadata.dart"
+      },
+      "_http": {
+        "uri": "_http/http.dart"
+      },
+      "_js_primitives": {
+        "uri": "_internal/js_dev_runtime/private/js_primitives.dart"
+      },
+      "_js_helper": {
+        "uri": "_internal/js_dev_runtime/private/js_helper.dart"
+      },
+      "js": {
+        "uri": "_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart"
+      },
+      "_js_mirrors": {
+        "uri": "_internal/js_dev_runtime/private/js_mirrors.dart"
+      },
+      "html_common": {
+        "uri": "html/html_common/html_common_dart2js.dart"
+      },
+      "_native_typed_data": {
+        "uri": "_internal/js_dev_runtime/private/native_typed_data.dart"
+      },
+      "core": {
+        "patches": "_internal/js_dev_runtime/patch/core_patch.dart",
+        "uri": "core/core.dart"
+      },
+      "js_util": {
+        "uri": "_internal/js_dev_runtime/lib/js_util/dart2js/js_util_dart2js.dart"
+      },
+      "collection": {
+        "patches": "_internal/js_dev_runtime/patch/collection_patch.dart",
+        "uri": "collection/collection.dart"
+      },
+      "typed_data": {
+        "patches": "_internal/js_dev_runtime/patch/typed_data_patch.dart",
+        "uri": "typed_data/typed_data.dart"
+      },
+      "web_audio": {
+        "uri": "web_audio/dart2js/web_audio_dart2js.dart"
+      },
+      "html": {
+        "uri": "html/dart2js/html_dart2js.dart"
+      },
+      "developer": {
+        "patches": "_internal/js_dev_runtime/patch/developer_patch.dart",
+        "uri": "developer/developer.dart"
+      },
+      "isolate": {
+        "patches": "_internal/js_dev_runtime/patch/isolate_patch.dart",
+        "supported": false,
+        "uri": "isolate/isolate.dart"
+      },
+      "web_gl": {
+        "uri": "web_gl/dart2js/web_gl_dart2js.dart"
+      },
+      "indexed_db": {
+        "uri": "indexed_db/dart2js/indexed_db_dart2js.dart"
+      },
+      "convert": {
+        "patches": "_internal/js_dev_runtime/patch/convert_patch.dart",
+        "uri": "convert/convert.dart"
+      },
+      "_isolate_helper": {
+        "uri": "_internal/js_dev_runtime/private/isolate_helper.dart"
+      },
+      "math": {
+        "patches": "_internal/js_dev_runtime/patch/math_patch.dart",
+        "uri": "math/math.dart"
+      },
+      "_foreign_helper": {
+        "uri": "_internal/js_dev_runtime/private/foreign_helper.dart"
+      },
+      "web_sql": {
+        "uri": "web_sql/dart2js/web_sql_dart2js.dart"
+      },
+      "svg": {
+        "uri": "svg/dart2js/svg_dart2js.dart"
+      }
+    }
+  },
+  "dart2js_server": {
+    "libraries": {
+      "async": {
+        "patches": "_internal/js_runtime/lib/async_patch.dart",
+        "uri": "async/async.dart"
+      },
+      "mirrors": {
+        "patches": "_internal/js_runtime/lib/mirrors_patch_cfe.dart",
+        "supported": false,
+        "uri": "mirrors/mirrors.dart"
+      },
+      "_interceptors": {
+        "uri": "_internal/js_runtime/lib/interceptors.dart"
+      },
+      "_js_embedded_names": {
+        "uri": "_internal/js_runtime/lib/shared/embedded_names.dart"
+      },
+      "io": {
+        "patches": "_internal/js_runtime/lib/io_patch.dart",
+        "supported": false,
+        "uri": "io/io.dart"
+      },
+      "_internal": {
+        "patches": "_internal/js_runtime/lib/internal_patch.dart",
+        "uri": "internal/internal.dart"
+      },
+      "_async_await_error_codes": {
+        "uri": "_internal/js_runtime/lib/shared/async_await_error_codes.dart"
+      },
+      "_http": {
+        "uri": "_http/http.dart"
+      },
+      "_js_helper": {
+        "uri": "_internal/js_runtime/lib/js_helper.dart"
+      },
+      "_js_primitives": {
+        "uri": "_internal/js_runtime/lib/js_primitives.dart"
+      },
+      "js": {
+        "uri": "js/dart2js/js_dart2js.dart"
+      },
+      "_recipe_syntax": {
+        "uri": "_internal/js_runtime/lib/shared/recipe_syntax.dart"
+      },
+      "_native_typed_data": {
+        "uri": "_internal/js_runtime/lib/native_typed_data.dart"
+      },
+      "core": {
+        "patches": "_internal/js_runtime/lib/core_patch.dart",
+        "uri": "core/core.dart"
+      },
+      "_js_names": {
+        "uri": "_internal/js_runtime/lib/js_names.dart"
+      },
+      "js_util": {
+        "uri": "js_util/dart2js/js_util_dart2js.dart"
+      },
+      "collection": {
+        "patches": "_internal/js_runtime/lib/collection_patch.dart",
+        "uri": "collection/collection.dart"
+      },
+      "typed_data": {
+        "patches": "_internal/js_runtime/lib/typed_data_patch.dart",
+        "uri": "typed_data/typed_data.dart"
+      },
+      "isolate": {
+        "patches": "_internal/js_runtime/lib/isolate_patch.dart",
+        "supported": false,
+        "uri": "isolate/isolate.dart"
+      },
+      "developer": {
+        "patches": "_internal/js_runtime/lib/developer_patch.dart",
+        "uri": "developer/developer.dart"
+      },
+      "_js": {
+        "patches": "js/_js_server.dart",
+        "uri": "js/_js.dart"
+      },
+      "convert": {
+        "patches": "_internal/js_runtime/lib/convert_patch.dart",
+        "uri": "convert/convert.dart"
+      },
+      "math": {
+        "patches": "_internal/js_runtime/lib/math_patch.dart",
+        "uri": "math/math.dart"
+      },
+      "_foreign_helper": {
+        "uri": "_internal/js_runtime/lib/foreign_helper.dart"
+      },
+      "_rti": {
+        "uri": "_internal/js_runtime/lib/rti.dart"
+      }
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/libraries.yaml b/sdk_nnbd/lib/libraries.yaml
new file mode 100644
index 0000000..f33a42b
--- /dev/null
+++ b/sdk_nnbd/lib/libraries.yaml
@@ -0,0 +1,479 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Note: if you edit this file, you must also edit libraries.json in this
+# directory:
+#
+#     python ./tools/yaml2json.py sdk/lib/libraries.yaml sdk/lib/libraries.json
+#
+# We currently have several different files that needs to be updated when
+# changing libraries, sources, and patch files.  See
+# https://github.com/dart-lang/sdk/issues/28836.
+
+none:
+  libraries: {}
+
+vm:
+  libraries:
+    _builtin:
+      uri: "../../runtime/bin/builtin.dart"
+
+    _internal:
+      uri: "internal/internal.dart"
+      patches:
+        - "../../runtime/lib/internal_patch.dart"
+        - "../../runtime/lib/class_id_fasta.dart"
+        - "../../runtime/lib/print_patch.dart"
+        - "../../runtime/lib/symbol_patch.dart"
+        - "internal/patch.dart"
+
+    async:
+      uri: "async/async.dart"
+      patches:
+        - "../../runtime/lib/async_patch.dart"
+        - "../../runtime/lib/deferred_load_patch.dart"
+        - "../../runtime/lib/schedule_microtask_patch.dart"
+        - "../../runtime/lib/timer_patch.dart"
+
+    collection:
+      uri: "collection/collection.dart"
+      patches:
+        - "../../runtime/lib/collection_patch.dart"
+        - "../../runtime/lib/compact_hash.dart"
+
+    convert:
+      uri: "convert/convert.dart"
+      patches: "../../runtime/lib/convert_patch.dart"
+
+    core:
+      uri: "core/core.dart"
+      patches:
+        - "../../runtime/lib/core_patch.dart"
+        - "../../runtime/lib/array.dart"
+        - "../../runtime/lib/array_patch.dart"
+        - "../../runtime/lib/bigint_patch.dart"
+        - "../../runtime/lib/bool_patch.dart"
+        - "../../runtime/lib/date_patch.dart"
+        - "../../runtime/lib/double.dart"
+        - "../../runtime/lib/double_patch.dart"
+        - "../../runtime/lib/errors_patch.dart"
+        - "../../runtime/lib/expando_patch.dart"
+        - "../../runtime/lib/function.dart"
+        - "../../runtime/lib/function_patch.dart"
+        - "../../runtime/lib/growable_array.dart"
+        - "../../runtime/lib/identical_patch.dart"
+        - "../../runtime/lib/immutable_map.dart"
+        - "../../runtime/lib/integers.dart"
+        - "../../runtime/lib/integers_patch.dart"
+        - "../../runtime/lib/invocation_mirror_patch.dart"
+        - "../../runtime/lib/lib_prefix.dart"
+        - "../../runtime/lib/map_patch.dart"
+        - "../../runtime/lib/null_patch.dart"
+        - "../../runtime/lib/object_patch.dart"
+        - "../../runtime/lib/regexp_patch.dart"
+        - "../../runtime/lib/stacktrace.dart"
+        - "../../runtime/lib/stopwatch_patch.dart"
+        - "../../runtime/lib/string_buffer_patch.dart"
+        - "../../runtime/lib/string_patch.dart"
+        - "../../runtime/lib/type_patch.dart"
+        - "../../runtime/lib/uri_patch.dart"
+        - "../../runtime/lib/weak_property.dart"
+
+    developer:
+      uri: "developer/developer.dart"
+      patches:
+        - "../../runtime/lib/developer.dart"
+        - "../../runtime/lib/profiler.dart"
+        - "../../runtime/lib/timeline.dart"
+
+    ffi:
+      uri: "ffi/ffi.dart"
+      patches:
+        - "../../runtime/lib/ffi_patch.dart"
+        - "../../runtime/lib/ffi_dynamic_library_patch.dart"
+        - "../../runtime/lib/ffi_native_type_patch.dart"
+
+    wasm:
+      uri: "wasm/wasm.dart"
+      patches:
+        - "../../runtime/lib/wasm_patch.dart"
+
+    _http:
+      uri: "_http/http.dart"
+
+    io:
+      uri: "io/io.dart"
+      patches:
+        - "../../runtime/bin/common_patch.dart"
+        - "../../runtime/bin/directory_patch.dart"
+        - "../../runtime/bin/eventhandler_patch.dart"
+        - "../../runtime/bin/file_patch.dart"
+        - "../../runtime/bin/file_system_entity_patch.dart"
+        - "../../runtime/bin/filter_patch.dart"
+        - "../../runtime/bin/io_service_patch.dart"
+        - "../../runtime/bin/namespace_patch.dart"
+        - "../../runtime/bin/platform_patch.dart"
+        - "../../runtime/bin/process_patch.dart"
+        - "../../runtime/bin/socket_patch.dart"
+        - "../../runtime/bin/stdio_patch.dart"
+        - "../../runtime/bin/secure_socket_patch.dart"
+        - "../../runtime/bin/sync_socket_patch.dart"
+
+    isolate:
+      uri: "isolate/isolate.dart"
+      patches:
+        - "../../runtime/lib/isolate_patch.dart"
+        - "../../runtime/lib/timer_impl.dart"
+
+    math:
+      uri: "math/math.dart"
+      patches: "../../runtime/lib/math_patch.dart"
+
+    mirrors:
+      uri: "mirrors/mirrors.dart"
+      patches:
+        - "../../runtime/lib/mirrors_patch.dart"
+        - "../../runtime/lib/mirrors_impl.dart"
+        - "../../runtime/lib/mirror_reference.dart"
+
+    nativewrappers:
+      uri: "html/dartium/nativewrappers.dart"
+
+    profiler:
+      uri: "profiler/profiler.dart"
+
+    cli:
+      uri: "cli/cli.dart"
+      patches:
+        - "../../runtime/bin/cli_patch.dart"
+
+    typed_data:
+      uri: "typed_data/typed_data.dart"
+      patches: "../../runtime/lib/typed_data_patch.dart"
+
+    _vmservice:
+      uri: "vmservice/vmservice.dart"
+
+    vmservice_io:
+      uri: "../../runtime/bin/vmservice/vmservice_io.dart"
+
+dart2js:
+  libraries:
+    async:
+      uri: "async/async.dart"
+      patches: "_internal/js_runtime/lib/async_patch.dart"
+
+    _chrome:
+      uri: "_chrome/dart2js/chrome_dart2js.dart"
+
+    collection:
+      uri: "collection/collection.dart"
+      patches: "_internal/js_runtime/lib/collection_patch.dart"
+
+    convert:
+      uri: "convert/convert.dart"
+      patches: "_internal/js_runtime/lib/convert_patch.dart"
+
+    core:
+      uri: "core/core.dart"
+      patches: "_internal/js_runtime/lib/core_patch.dart"
+
+    developer:
+      uri: "developer/developer.dart"
+      patches: "_internal/js_runtime/lib/developer_patch.dart"
+
+    html:
+      uri: "html/dart2js/html_dart2js.dart"
+
+    html_common:
+      uri: "html/html_common/html_common_dart2js.dart"
+
+    indexed_db:
+      uri: "indexed_db/dart2js/indexed_db_dart2js.dart"
+
+    _http:
+      uri: "_http/http.dart"
+
+    io:
+      uri: "io/io.dart"
+      patches: "_internal/js_runtime/lib/io_patch.dart"
+      supported: false
+
+    isolate:
+      uri: "isolate/isolate.dart"
+      patches: "_internal/js_runtime/lib/isolate_patch.dart"
+      supported: false
+
+    js:
+      uri: "js/dart2js/js_dart2js.dart"
+
+    _js:
+      uri: "js/_js.dart"
+      patches: "js/_js_client.dart"
+
+    js_util:
+      uri: "js_util/dart2js/js_util_dart2js.dart"
+
+    math:
+      uri: "math/math.dart"
+      patches: "_internal/js_runtime/lib/math_patch.dart"
+
+    mirrors:
+      uri: "mirrors/mirrors.dart"
+      patches: "_internal/js_runtime/lib/mirrors_patch_cfe.dart"
+      supported: false
+
+    typed_data:
+      uri: "typed_data/typed_data.dart"
+      patches: "_internal/js_runtime/lib/typed_data_patch.dart"
+
+    _native_typed_data:
+      uri: "_internal/js_runtime/lib/native_typed_data.dart"
+
+    svg:
+      uri: "svg/dart2js/svg_dart2js.dart"
+
+    web_audio:
+      uri: "web_audio/dart2js/web_audio_dart2js.dart"
+
+    web_gl:
+      uri: "web_gl/dart2js/web_gl_dart2js.dart"
+
+    web_sql:
+      uri: "web_sql/dart2js/web_sql_dart2js.dart"
+
+    _internal:
+      uri: "internal/internal.dart"
+      patches: "_internal/js_runtime/lib/internal_patch.dart"
+
+    _js_helper:
+      uri: "_internal/js_runtime/lib/js_helper.dart"
+
+    _rti:
+      uri: "_internal/js_runtime/lib/rti.dart"
+
+    _interceptors:
+      uri: "_internal/js_runtime/lib/interceptors.dart"
+
+    _foreign_helper:
+      uri: "_internal/js_runtime/lib/foreign_helper.dart"
+
+    _js_names:
+      uri: "_internal/js_runtime/lib/js_names.dart"
+
+    _js_primitives:
+      uri: "_internal/js_runtime/lib/js_primitives.dart"
+
+    _js_embedded_names:
+      uri: "_internal/js_runtime/lib/shared/embedded_names.dart"
+
+    _async_await_error_codes:
+      uri: "_internal/js_runtime/lib/shared/async_await_error_codes.dart"
+
+    _recipe_syntax:
+      uri: "_internal/js_runtime/lib/shared/recipe_syntax.dart"
+
+    _metadata:
+      uri: "html/html_common/metadata.dart"
+
+dart2js_server:
+  libraries:
+    async:
+      uri: "async/async.dart"
+      patches: "_internal/js_runtime/lib/async_patch.dart"
+
+    collection:
+      uri: "collection/collection.dart"
+      patches: "_internal/js_runtime/lib/collection_patch.dart"
+
+    convert:
+      uri: "convert/convert.dart"
+      patches: "_internal/js_runtime/lib/convert_patch.dart"
+
+    core:
+      uri: "core/core.dart"
+      patches: "_internal/js_runtime/lib/core_patch.dart"
+
+    developer:
+      uri: "developer/developer.dart"
+      patches: "_internal/js_runtime/lib/developer_patch.dart"
+
+    _http:
+      uri: "_http/http.dart"
+
+    io:
+      uri: "io/io.dart"
+      patches: "_internal/js_runtime/lib/io_patch.dart"
+      supported: false
+
+    isolate:
+      uri: "isolate/isolate.dart"
+      patches: "_internal/js_runtime/lib/isolate_patch.dart"
+      supported: false
+
+    js:
+      uri: "js/dart2js/js_dart2js.dart"
+
+    _js:
+      uri: "js/_js.dart"
+      patches: "js/_js_server.dart"
+
+    js_util:
+      uri: "js_util/dart2js/js_util_dart2js.dart"
+
+    math:
+      uri: "math/math.dart"
+      patches: "_internal/js_runtime/lib/math_patch.dart"
+
+    mirrors:
+      uri: "mirrors/mirrors.dart"
+      patches: "_internal/js_runtime/lib/mirrors_patch_cfe.dart"
+      supported: false
+
+    typed_data:
+      uri: "typed_data/typed_data.dart"
+      patches: "_internal/js_runtime/lib/typed_data_patch.dart"
+
+    _native_typed_data:
+      uri: "_internal/js_runtime/lib/native_typed_data.dart"
+
+    _internal:
+      uri: "internal/internal.dart"
+      patches: "_internal/js_runtime/lib/internal_patch.dart"
+
+    _js_helper:
+      uri: "_internal/js_runtime/lib/js_helper.dart"
+
+    _rti:
+      uri: "_internal/js_runtime/lib/rti.dart"
+
+    _interceptors:
+      uri: "_internal/js_runtime/lib/interceptors.dart"
+
+    _foreign_helper:
+      uri: "_internal/js_runtime/lib/foreign_helper.dart"
+
+    _js_names:
+      uri: "_internal/js_runtime/lib/js_names.dart"
+
+    _js_primitives:
+      uri: "_internal/js_runtime/lib/js_primitives.dart"
+
+    _js_embedded_names:
+      uri: "_internal/js_runtime/lib/shared/embedded_names.dart"
+
+    _async_await_error_codes:
+      uri: "_internal/js_runtime/lib/shared/async_await_error_codes.dart"
+
+    _recipe_syntax:
+      uri: "_internal/js_runtime/lib/shared/recipe_syntax.dart"
+
+dartdevc:
+    libraries:
+      _runtime:
+        uri: "_internal/js_dev_runtime/private/ddc_runtime/runtime.dart"
+
+      _debugger:
+        uri: "_internal/js_dev_runtime/private/debugger.dart"
+
+      _foreign_helper:
+        uri: "_internal/js_dev_runtime/private/foreign_helper.dart"
+
+      _http:
+        uri: "_http/http.dart"
+
+      _interceptors:
+        uri: "_internal/js_dev_runtime/private/interceptors.dart"
+
+      _internal:
+        uri: "internal/internal.dart"
+        patches: "_internal/js_dev_runtime/patch/internal_patch.dart"
+
+      _isolate_helper:
+        uri: "_internal/js_dev_runtime/private/isolate_helper.dart"
+
+      _js_helper:
+        uri: "_internal/js_dev_runtime/private/js_helper.dart"
+
+      _js_mirrors:
+        uri: "_internal/js_dev_runtime/private/js_mirrors.dart"
+
+      _js_primitives:
+        uri: "_internal/js_dev_runtime/private/js_primitives.dart"
+
+      _metadata:
+        uri: "html/html_common/metadata.dart"
+
+      _native_typed_data:
+        uri: "_internal/js_dev_runtime/private/native_typed_data.dart"
+
+      async:
+        uri: "async/async.dart"
+        patches: "_internal/js_dev_runtime/patch/async_patch.dart"
+
+      collection:
+        uri: "collection/collection.dart"
+        patches: "_internal/js_dev_runtime/patch/collection_patch.dart"
+
+      convert:
+        uri: "convert/convert.dart"
+        patches: "_internal/js_dev_runtime/patch/convert_patch.dart"
+
+      core:
+        uri: "core/core.dart"
+        patches: "_internal/js_dev_runtime/patch/core_patch.dart"
+
+      developer:
+        uri: "developer/developer.dart"
+        patches: "_internal/js_dev_runtime/patch/developer_patch.dart"
+
+      io:
+        uri: "io/io.dart"
+        patches: "_internal/js_dev_runtime/patch/io_patch.dart"
+        supported: false
+
+      isolate:
+        uri: "isolate/isolate.dart"
+        patches: "_internal/js_dev_runtime/patch/isolate_patch.dart"
+        supported: false
+
+      mirrors:
+        uri: "mirrors/mirrors.dart"
+        patches: "_internal/js_dev_runtime/patch/mirrors_patch.dart"
+        supported: false
+
+      math:
+        uri: "math/math.dart"
+        patches: "_internal/js_dev_runtime/patch/math_patch.dart"
+
+      typed_data:
+        uri: "typed_data/typed_data.dart"
+        patches: "_internal/js_dev_runtime/patch/typed_data_patch.dart"
+
+      html:
+        uri: "html/dart2js/html_dart2js.dart"
+
+      html_common:
+        uri: "html/html_common/html_common_dart2js.dart"
+
+      indexed_db:
+        uri: "indexed_db/dart2js/indexed_db_dart2js.dart"
+
+      js:
+        uri: "_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart"
+
+      js_util:
+        uri: "_internal/js_dev_runtime/lib/js_util/dart2js/js_util_dart2js.dart"
+
+      svg:
+        uri: "svg/dart2js/svg_dart2js.dart"
+
+      web_audio:
+        uri: "web_audio/dart2js/web_audio_dart2js.dart"
+
+      web_gl:
+        uri: "web_gl/dart2js/web_gl_dart2js.dart"
+
+      web_sql:
+        uri: "web_sql/dart2js/web_sql_dart2js.dart"
diff --git a/sdk_nnbd/lib/math/jenkins_smi_hash.dart b/sdk_nnbd/lib/math/jenkins_smi_hash.dart
new file mode 100644
index 0000000..d756b37
--- /dev/null
+++ b/sdk_nnbd/lib/math/jenkins_smi_hash.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.
+part of dart.math;
+
+/// This is the [Jenkins hash function][1] but using masking to keep
+/// values in SMI range.
+///
+/// [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
+///
+/// Use:
+/// Hash each value with the hash of the previous value, then get the final
+/// hash by calling finish.
+///
+///     var hash = 0;
+///     for (var value in values) {
+///       hash = JenkinsSmiHash.combine(hash, value.hashCode);
+///     }
+///     hash = JenkinsSmiHash.finish(hash);
+class _JenkinsSmiHash {
+  // TODO(11617): This class should be optimized and standardized elsewhere.
+
+  static int combine(int hash, int value) {
+    hash = 0x1fffffff & (hash + value);
+    hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
+    return hash ^ (hash >> 6);
+  }
+
+  static int finish(int hash) {
+    hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
+    hash = hash ^ (hash >> 11);
+    return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
+  }
+
+  static int hash2(a, b) => finish(combine(combine(0, a), b));
+
+  static int hash4(a, b, c, d) =>
+      finish(combine(combine(combine(combine(0, a), b), c), d));
+}
diff --git a/sdk_nnbd/lib/math/math.dart b/sdk_nnbd/lib/math/math.dart
new file mode 100644
index 0000000..548fb59
--- /dev/null
+++ b/sdk_nnbd/lib/math/math.dart
@@ -0,0 +1,179 @@
+// Copyright (c) 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.
+
+/// Mathematical constants and functions, plus a random number generator.
+///
+/// To use this library in your code:
+///
+///     import 'dart:math';
+///
+/// {@category Core}
+library dart.math;
+
+part "jenkins_smi_hash.dart";
+part "point.dart";
+part "random.dart";
+part "rectangle.dart";
+
+/// Base of the natural logarithms.
+///
+/// Typically written as "e".
+const double e = 2.718281828459045;
+
+/// Natural logarithm of 10.
+///
+/// The natural logarithm of 10 is the number such that `pow(E, LN10) == 10`.
+/// This value is not exact, but it is the closest representable double to the
+/// exact mathematical value.
+const double ln10 = 2.302585092994046;
+
+/// Natural logarithm of 2.
+///
+/// The natural logarithm of 2 is the number such that `pow(E, LN2) == 2`.
+/// This value is not exact, but it is the closest representable double to the
+/// exact mathematical value.
+const double ln2 = 0.6931471805599453;
+
+/// Base-2 logarithm of [e].
+const double log2e = 1.4426950408889634;
+
+/// Base-10 logarithm of [e].
+const double log10e = 0.4342944819032518;
+
+/// The PI constant.
+const double pi = 3.1415926535897932;
+
+/// Square root of 1/2.
+const double sqrt1_2 = 0.7071067811865476;
+
+/// Square root of 2.
+const double sqrt2 = 1.4142135623730951;
+
+/// Returns the lesser of two numbers.
+///
+/// Returns NaN if either argument is NaN.
+/// The lesser of `-0.0` and `0.0` is `-0.0`.
+/// If the arguments are otherwise equal (including int and doubles with the
+/// same mathematical value) then it is unspecified which of the two arguments
+/// is returned.
+external T min<T extends num>(T a, T b);
+
+/// Returns the larger of two numbers.
+///
+/// Returns NaN if either argument is NaN.
+/// The larger of `-0.0` and `0.0` is `0.0`. If the arguments are
+/// otherwise equal (including int and doubles with the same mathematical value)
+/// then it is unspecified which of the two arguments is returned.
+external T max<T extends num>(T a, T b);
+
+/// A variant of [atan].
+///
+/// Converts both arguments to [double]s.
+///
+/// Returns the angle in radians between the positive x-axis
+/// and the vector ([b],[a]).
+/// The result is in the range -PI..PI.
+///
+/// If [b] is positive, this is the same as `atan(b/a)`.
+///
+/// The result is negative when [a] is negative (including when [a] is the
+/// double -0.0).
+///
+/// If [a] is equal to zero, the vector ([b],[a]) is considered parallel to
+/// the x-axis, even if [b] is also equal to zero. The sign of [b] determines
+/// the direction of the vector along the x-axis.
+///
+/// Returns NaN if either argument is NaN.
+external double atan2(num a, num b);
+
+/// Returns [x] to the power of [exponent].
+///
+/// If [x] is an [int] and [exponent] is a non-negative [int], the result is
+/// an [int], otherwise both arguments are converted to doubles first, and the
+/// result is a [double].
+///
+/// For integers, the power is always equal to the mathematical result of `x` to
+/// the power `exponent`, only limited by the available memory.
+///
+/// For doubles, `pow(x, y)` handles edge cases as follows:
+///
+/// - if `y` is zero (0.0 or -0.0), the result is always 1.0.
+/// - if `x` is 1.0, the result is always 1.0.
+/// - otherwise, if either `x` or `y` is NaN then the result is NaN.
+/// - if `x` is negative (but not -0.0) and `y` is a finite non-integer, the
+///   result is NaN.
+/// - if `x` is Infinity and `y` is negative, the result is 0.0.
+/// - if `x` is Infinity and `y` is positive, the result is Infinity.
+/// - if `x` is 0.0 and `y` is negative, the result is Infinity.
+/// - if `x` is 0.0 and `y` is positive, the result is 0.0.
+/// - if `x` is -Infinity or -0.0 and `y` is an odd integer, then the result is
+///   `-pow(-x ,y)`.
+/// - if `x` is -Infinity or -0.0 and `y` is not an odd integer, then the result
+///   is the same as `pow(-x , y)`.
+/// - if `y` is Infinity and the absolute value of `x` is less than 1, the
+///   result is 0.0.
+/// - if `y` is Infinity and `x` is -1, the result is 1.0.
+/// - if `y` is Infinity and the absolute value of `x` is greater than 1,
+///   the result is Infinity.
+/// - if `y` is -Infinity, the result is `1/pow(x, Infinity)`.
+///
+/// This corresponds to the `pow` function defined in the IEEE Standard
+/// 754-2008.
+///
+/// Notice that the result may overflow. If integers are represented as 64-bit
+/// numbers, an integer result may be truncated, and a double result may
+/// overflow to positive or negative [double.infinity].
+external num pow(num x, num exponent);
+
+/// Converts [radians] to a [double] and returns the sine of the value.
+///
+/// If [radians] is not a finite number, the result is NaN.
+external double sin(num radians);
+
+/// Converts [radians] to a [double] and returns the cosine of the value.
+///
+/// If [radians] is not a finite number, the result is NaN.
+external double cos(num radians);
+
+/// Converts [radians] to a [double] and returns the tangent of the value.
+///
+/// The tangent function is equivalent to `sin(radians)/cos(radians)` and may be
+/// infinite (positive or negative) when `cos(radians)` is equal to zero.
+/// If [radians] is not a finite number, the result is NaN.
+external double tan(num radians);
+
+/// Converts [x] to a [double] and returns its arc cosine in radians.
+///
+/// Returns a value in the range 0..PI, or NaN if [x] is outside
+/// the range -1..1.
+external double acos(num x);
+
+/// Converts [x] to a [double] and returns its arc sine in radians.
+///
+/// Returns a value in the range -PI/2..PI/2, or NaN if [x] is outside
+/// the range -1..1.
+external double asin(num x);
+
+/// Converts [x] to a [double] and returns its arc tangent in radians.
+///
+/// Returns a value in the range -PI/2..PI/2, or NaN if [x] is NaN.
+external double atan(num x);
+
+/// Converts [x] to a [double] and returns the positive square root of the
+/// value.
+///
+/// Returns -0.0 if [x] is -0.0, and NaN if [x] is otherwise negative or NaN.
+external double sqrt(num x);
+
+/// Converts [x] to a [double] and returns the natural exponent, [e],
+/// to the power [x].
+///
+/// Returns NaN if [x] is NaN.
+external double exp(num x);
+
+/// Converts [x] to a [double] and returns the natural logarithm of the value.
+///
+/// Returns negative infinity if [x] is equal to zero.
+/// Returns NaN if [x] is NaN or less than zero.
+external double log(num x);
diff --git a/sdk_nnbd/lib/math/math_sources.gni b/sdk_nnbd/lib/math/math_sources.gni
new file mode 100644
index 0000000..ff8f3fa
--- /dev/null
+++ b/sdk_nnbd/lib/math/math_sources.gni
@@ -0,0 +1,13 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+math_sdk_sources = [
+  "math.dart",
+
+  # The above file needs to be first as it lists the parts below.
+  "jenkins_smi_hash.dart",
+  "point.dart",
+  "random.dart",
+  "rectangle.dart",
+]
diff --git a/sdk_nnbd/lib/math/point.dart b/sdk_nnbd/lib/math/point.dart
new file mode 100644
index 0000000..1015e7b
--- /dev/null
+++ b/sdk_nnbd/lib/math/point.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.
+part of dart.math;
+
+/// A utility class for representing two-dimensional positions.
+class Point<T extends num> {
+  final T x;
+  final T y;
+
+  const Point(T x, T y)
+      : this.x = x,
+        this.y = y;
+
+  String toString() => 'Point($x, $y)';
+
+  /// A `Point` is only equal to another `Point` with the same coordinates.
+  ///
+  /// This point is equal to `other` if, and only if,
+  /// `other` is a `Point` with
+  /// [x] equal to `other.x` and [y] equal to `other.y`.
+  bool operator ==(dynamic other) =>
+      // Cannot change parameter type to `Object` in case some class
+      // inherits the type and uses their argument dynamically.
+      other is Point && x == other.x && y == other.y;
+
+  int get hashCode => _JenkinsSmiHash.hash2(x.hashCode, y.hashCode);
+
+  /// Add [other] to `this`, as if both points were vectors.
+  ///
+  /// Returns the resulting "vector" as a Point.
+  Point<T> operator +(Point<T> other) {
+    return Point<T>(x + other.x, y + other.y);
+  }
+
+  /// Subtract [other] from `this`, as if both points were vectors.
+  ///
+  /// Returns the resulting "vector" as a Point.
+  Point<T> operator -(Point<T> other) {
+    return Point<T>(x - other.x, y - other.y);
+  }
+
+  /// Scale this point by [factor] as if it were a vector.
+  ///
+  /// *Important* *Note*: This function accepts a `num` as its argument only so
+  /// that you can scale Point<double> objects by an `int` factor. Because the
+  /// star operator always returns the same type of Point that originally called
+  /// it, passing in a double [factor] on a `Point<int>` _causes_ _a_
+  /// _runtime_ _error_ in checked mode.
+  Point<T> operator *(num /*T|int*/ factor) {
+    return Point<T>((x * factor), (y * factor));
+  }
+
+  /// Get the straight line (Euclidean) distance between the origin (0, 0) and
+  /// this point.
+  double get magnitude => sqrt(x * x + y * y);
+
+  /// Returns the distance between `this` and [other].
+  double distanceTo(Point<T> other) {
+    var dx = x - other.x;
+    var dy = y - other.y;
+    return sqrt(dx * dx + dy * dy);
+  }
+
+  /// Returns the squared distance between `this` and [other].
+  ///
+  /// Squared distances can be used for comparisons when the actual value is not
+  /// required.
+  T squaredDistanceTo(Point<T> other) {
+    var dx = x - other.x;
+    var dy = y - other.y;
+    return dx * dx + dy * dy;
+  }
+}
diff --git a/sdk_nnbd/lib/math/random.dart b/sdk_nnbd/lib/math/random.dart
new file mode 100644
index 0000000..80e588b
--- /dev/null
+++ b/sdk_nnbd/lib/math/random.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 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 dart.math;
+
+/// A generator of random bool, int, or double values.
+///
+/// The default implementation supplies a stream of pseudo-random bits that are
+/// not suitable for cryptographic purposes.
+///
+/// Use the [Random.secure]() constructor for cryptographic purposes.
+abstract class Random {
+  /// Creates a random number generator.
+  ///
+  /// The optional parameter [seed] is used to initialize the
+  /// internal state of the generator. The implementation of the
+  /// random stream can change between releases of the library.
+  external factory Random([int seed]);
+
+  /// Creates a cryptographically secure random number generator.
+  ///
+  /// If the program cannot provide a cryptographically secure
+  /// source of random numbers, it throws an [UnsupportedError].
+  external factory Random.secure();
+
+  /// Generates a non-negative random integer uniformly distributed in the range
+  /// from 0, inclusive, to [max], exclusive.
+  ///
+  /// Implementation note: The default implementation supports [max] values
+  /// between 1 and (1<<32) inclusive.
+  int nextInt(int max);
+
+  /// Generates a non-negative random floating point value uniformly distributed
+  /// in the range from 0.0, inclusive, to 1.0, exclusive.
+  double nextDouble();
+
+  /// Generates a random boolean value.
+  bool nextBool();
+}
diff --git a/sdk_nnbd/lib/math/rectangle.dart b/sdk_nnbd/lib/math/rectangle.dart
new file mode 100644
index 0000000..6e72036
--- /dev/null
+++ b/sdk_nnbd/lib/math/rectangle.dart
@@ -0,0 +1,247 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+part of dart.math;
+
+/// A base class for representing two-dimensional axis-aligned rectangles.
+///
+/// This rectangle uses a left-handed Cartesian coordinate system, with x
+/// directed to the right and y directed down, as per the convention in 2D
+/// computer graphics.
+///
+/// See also:
+///    [W3C Coordinate Systems Specification](http://www.w3.org/TR/SVG/coords.html#InitialCoordinateSystem).
+///
+/// The rectangle is the set of points with representable coordinates greater
+/// than or equal to left/top, and with distance to left/top no greater than
+/// width/height (to the limit of the precision of the coordinates).
+abstract class _RectangleBase<T extends num> {
+  const _RectangleBase();
+
+  /// The x-coordinate of the left edge.
+  T get left;
+
+  /// The y-coordinate of the top edge.
+  T get top;
+
+  /// The width of the rectangle.
+  T get width;
+
+  /// The height of the rectangle.
+  T get height;
+
+  /// The x-coordinate of the right edge.
+  T get right => left + width;
+
+  /// The y-coordinate of the bottom edge.
+  T get bottom => top + height;
+
+  String toString() {
+    return 'Rectangle ($left, $top) $width x $height';
+  }
+
+  bool operator ==(dynamic other) =>
+      // Can't change argument type to `Object` since subclasses inherit it
+      // and uses their argument dynamically.
+      other is Rectangle &&
+      left == other.left &&
+      top == other.top &&
+      right == other.right &&
+      bottom == other.bottom;
+
+  int get hashCode => _JenkinsSmiHash.hash4(
+      left.hashCode, top.hashCode, right.hashCode, bottom.hashCode);
+
+  /// Computes the intersection of `this` and [other].
+  ///
+  /// The intersection of two axis-aligned rectangles, if any, is always another
+  /// axis-aligned rectangle.
+  ///
+  /// Returns the intersection of this and `other`, or `null` if they don't
+  /// intersect.
+  Rectangle<T> intersection(Rectangle<T> other) {
+    var x0 = max(left, other.left);
+    var x1 = min(left + width, other.left + other.width);
+
+    if (x0 <= x1) {
+      var y0 = max(top, other.top);
+      var y1 = min(top + height, other.top + other.height);
+
+      if (y0 <= y1) {
+        return Rectangle<T>(x0, y0, x1 - x0, y1 - y0);
+      }
+    }
+    return null;
+  }
+
+  /// Returns true if `this` intersects [other].
+  bool intersects(Rectangle<num> other) {
+    return (left <= other.left + other.width &&
+        other.left <= left + width &&
+        top <= other.top + other.height &&
+        other.top <= top + height);
+  }
+
+  /// Returns a new rectangle which completely contains `this` and [other].
+  Rectangle<T> boundingBox(Rectangle<T> other) {
+    var right = max(this.left + this.width, other.left + other.width);
+    var bottom = max(this.top + this.height, other.top + other.height);
+
+    var left = min(this.left, other.left);
+    var top = min(this.top, other.top);
+
+    return Rectangle<T>(left, top, right - left, bottom - top);
+  }
+
+  /// Tests whether `this` entirely contains [another].
+  bool containsRectangle(Rectangle<num> another) {
+    return left <= another.left &&
+        left + width >= another.left + another.width &&
+        top <= another.top &&
+        top + height >= another.top + another.height;
+  }
+
+  /// Tests whether [another] is inside or along the edges of `this`.
+  bool containsPoint(Point<num> another) {
+    return another.x >= left &&
+        another.x <= left + width &&
+        another.y >= top &&
+        another.y <= top + height;
+  }
+
+  Point<T> get topLeft => Point<T>(this.left, this.top);
+  Point<T> get topRight => Point<T>(this.left + this.width, this.top);
+  Point<T> get bottomRight =>
+      Point<T>(this.left + this.width, this.top + this.height);
+  Point<T> get bottomLeft => Point<T>(this.left, this.top + this.height);
+}
+
+/// A class for representing two-dimensional rectangles whose properties are
+/// immutable.
+class Rectangle<T extends num> extends _RectangleBase<T> {
+  final T left;
+  final T top;
+  final T width;
+  final T height;
+
+  /// Create a rectangle spanned by `(left, top)` and
+  /// `(left+width, top+height)`.
+  ///
+  /// The rectangle contains the points
+  /// with x-coordinate between `left` and `left + width`, and
+  /// with y-coordinate between `top` and `top + height`, both inclusive.
+  ///
+  /// The `width` and `height` should be non-negative.
+  /// If `width` or `height` are negative, they are clamped to zero.
+  ///
+  /// If `width` and `height` are zero, the "rectangle" comprises only the
+  /// single point `(left, top)`.
+  const Rectangle(this.left, this.top, T width, T height)
+      : this.width = (width < 0) ? -width * 0 : width, // Inline _clampToZero.
+        this.height = (height < 0) ? -height * 0 : height;
+
+  /// Create a rectangle spanned by the points [a] and [b];
+  ///
+  /// The rectangle contains the points
+  /// with x-coordinate between `a.x` and `b.x`, and
+  /// with y-coordinate between `a.y` and `b.y`, both inclusive.
+  ///
+  /// If the distance between `a.x` and `b.x` is not representable
+  /// (which can happen if one or both is a double),
+  /// the actual right edge might be slightly off from `max(a.x, b.x)`.
+  /// Similar for the y-coordinates and the bottom edge.
+  factory Rectangle.fromPoints(Point<T> a, Point<T> b) {
+    T left = min(a.x, b.x);
+    T width = max(a.x, b.x) - left;
+    T top = min(a.y, b.y);
+    T height = max(a.y, b.y) - top;
+    return Rectangle<T>(left, top, width, height);
+  }
+}
+
+/// A class for representing two-dimensional axis-aligned rectangles with
+/// mutable properties.
+class MutableRectangle<T extends num> extends _RectangleBase<T>
+    implements Rectangle<T> {
+  /// The x-coordinate of the left edge.
+  ///
+  /// Setting the value will move the rectangle without changing its width.
+  T left;
+
+  /// The y-coordinate of the left edge.
+  ///
+  /// Setting the value will move the rectangle without changing its height.
+  T top;
+  T _width;
+  T _height;
+
+  /// Create a mutable rectangle spanned by `(left, top)` and
+  /// `(left+width, top+height)`.
+  ///
+  /// The rectangle contains the points
+  /// with x-coordinate between `left` and `left + width`, and
+  /// with y-coordinate between `top` and `top + height`, both inclusive.
+  ///
+  /// The `width` and `height` should be non-negative.
+  /// If `width` or `height` are negative, they are clamped to zero.
+  ///
+  /// If `width` and `height` are zero, the "rectangle" comprises only the
+  /// single point `(left, top)`.
+  MutableRectangle(this.left, this.top, T width, T height)
+      : this._width = (width < 0) ? _clampToZero<T>(width) : width,
+        this._height = (height < 0) ? _clampToZero<T>(height) : height;
+
+  /// Create a mutable rectangle spanned by the points [a] and [b];
+  ///
+  /// The rectangle contains the points
+  /// with x-coordinate between `a.x` and `b.x`, and
+  /// with y-coordinate between `a.y` and `b.y`, both inclusive.
+  ///
+  /// If the distance between `a.x` and `b.x` is not representable
+  /// (which can happen if one or both is a double),
+  /// the actual right edge might be slightly off from `max(a.x, b.x)`.
+  /// Similar for the y-coordinates and the bottom edge.
+  factory MutableRectangle.fromPoints(Point<T> a, Point<T> b) {
+    T left = min(a.x, b.x);
+    T width = max(a.x, b.x) - left;
+    T top = min(a.y, b.y);
+    T height = max(a.y, b.y) - top;
+    return MutableRectangle<T>(left, top, width, height);
+  }
+
+  T get width => _width;
+
+  /// Sets the width of the rectangle.
+  ///
+  /// The width must be non-negative.
+  /// If a negative width is supplied, it is clamped to zero.
+  ///
+  /// Setting the value will change the right edge of the rectangle,
+  /// but will not change [left].
+  set width(T width) {
+    if (width < 0) width = _clampToZero<T>(width);
+    _width = width;
+  }
+
+  T get height => _height;
+
+  /// Sets the height of the rectangle.
+  ///
+  /// The height must be non-negative.
+  /// If a negative height is supplied, it is clamped to zero.
+  ///
+  /// Setting the value will change the bottom edge of the rectangle,
+  /// but will not change [top].
+  set height(T height) {
+    if (height < 0) height = _clampToZero<T>(height);
+    _height = height;
+  }
+}
+
+/// Converts a negative [int] or [double] to a zero-value of the same type.
+///
+/// Returns `0` if value is int, `0.0` if value is double.
+T _clampToZero<T extends num>(T value) {
+  assert(value < 0);
+  return -value * 0;
+}
diff --git a/sdk_nnbd/lib/mirrors/mirrors.dart b/sdk_nnbd/lib/mirrors/mirrors.dart
new file mode 100644
index 0000000..64f88a2
--- /dev/null
+++ b/sdk_nnbd/lib/mirrors/mirrors.dart
@@ -0,0 +1,1467 @@
+// 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.
+
+// For the purposes of the mirrors library, we adopt a naming
+// convention with respect to getters and setters.  Specifically, for
+// some variable or field...
+//
+//   var myField;
+//
+// ...the getter is named 'myField' and the setter is named
+// 'myField='.  This allows us to assign unique names to getters and
+// setters for the purposes of member lookup.
+
+/**
+ * Basic reflection in Dart,
+ * with support for introspection and dynamic invocation.
+ *
+ * *Introspection* is that subset of reflection by which a running
+ * program can examine its own structure. For example, a function
+ * that prints out the names of all the members of an arbitrary object.
+ *
+ * *Dynamic invocation* refers the ability to evaluate code that
+ * has not been literally specified at compile time, such as calling a method
+ * whose name is provided as an argument (because it is looked up
+ * in a database, or provided interactively by the user).
+ *
+ * ## How to interpret this library's documentation
+ *
+ * As a rule, the names of Dart declarations are represented using
+ * instances of class [Symbol]. Whenever the doc speaks of an object *s*
+ * of class [Symbol] denoting a name, it means the string that
+ * was used to construct *s*.
+ *
+ * The documentation frequently abuses notation with
+ * Dart pseudo-code such as [:o.x(a):], where
+ * o and a are defined to be objects; what is actually meant in these
+ * cases is [:o'.x(a'):] where *o'* and *a'* are Dart variables
+ * bound to *o* and *a* respectively. Furthermore, *o'* and *a'*
+ * are assumed to be fresh variables (meaning that they are
+ * distinct from any other variables in the program).
+ *
+ * Sometimes the documentation refers to *serializable* objects.
+ * An object is serializable across isolates if and only if it is an instance of
+ * num, bool, String, a list of objects that are serializable
+ * across isolates, or a map with keys and values that are all serializable across
+ * isolates.
+ *
+ * ## Status: Unstable
+ *
+ * The dart:mirrors library is unstable and its API might change slightly as a
+ * result of user feedback. This library is platform dependent and therefore it
+ * has implementations for both dart2js and the Dart VM. Both are under
+ * development and may not support all operations yet.
+ *
+ * {@category VM}
+ */
+library dart.mirrors;
+
+import 'dart:async' show Future;
+
+/**
+ * A [MirrorSystem] is the main interface used to reflect on a set of
+ * associated libraries.
+ *
+ * At runtime each running isolate has a distinct [MirrorSystem].
+ *
+ * It is also possible to have a [MirrorSystem] which represents a set
+ * of libraries which are not running -- perhaps at compile-time.  In
+ * this case, all available reflective functionality would be
+ * supported, but runtime functionality (such as invoking a function
+ * or inspecting the contents of a variable) would fail dynamically.
+ */
+abstract class MirrorSystem {
+  /**
+   * All libraries known to the mirror system, indexed by their URI.
+   *
+   * Returns an unmodifiable map of the libraries with [LibraryMirror.uri] as
+   * keys.
+   *
+   * For a runtime mirror system, only libraries which are currently loaded
+   * are included, and repeated calls of this method may return different maps
+   * as libraries are loaded.
+   */
+  Map<Uri, LibraryMirror> get libraries;
+
+  /**
+   * Returns the unique library named [libraryName] if it exists.
+   *
+   * If no unique library exists, an error is thrown.
+   */
+  external LibraryMirror findLibrary(Symbol libraryName);
+
+  /**
+   * A mirror on the isolate associated with this [MirrorSystem].
+   *
+   * This may be null if this mirror system is not running.
+   */
+  IsolateMirror get isolate;
+
+  /**
+   * A mirror on the [:dynamic:] type.
+   */
+  TypeMirror get dynamicType;
+
+  /**
+   * A mirror on the [:void:] type.
+   */
+  TypeMirror get voidType;
+
+  /**
+   * Returns the name of [symbol].
+   *
+   * The following text is non-normative:
+   *
+   * Using this method may result in larger output.  If possible, use
+   * [MirrorsUsed] to specify which symbols must be retained in clear text.
+   */
+  external static String getName(Symbol symbol);
+
+  /**
+   * Returns a symbol for [name].
+   *
+   * If [library] is not a [LibraryMirror] or if [name] is a private identifier
+   * and [library] is `null`, throws an [ArgumentError]. If [name] is a private
+   * identifier, the symbol returned is with respect to [library].
+   *
+   * The following text is non-normative:
+   *
+   * Using this method may result in larger output.  If possible, use
+   * the const constructor of [Symbol] or symbol literals.
+   */
+  external static Symbol getSymbol(String name, [LibraryMirror library]);
+}
+
+/**
+ * Returns a [MirrorSystem] for the current isolate.
+ */
+external MirrorSystem currentMirrorSystem();
+
+/**
+ * Reflects an instance.
+ *
+ * Returns an [InstanceMirror] reflecting [reflectee]. If [reflectee] is a
+ * function or an instance of a class that has a [:call:] method, the returned
+ * instance mirror will be a [ClosureMirror].
+ *
+ * Note that since one cannot obtain an object from another isolate, this
+ * function can only be used to obtain  mirrors on objects of the current
+ * isolate.
+ */
+external InstanceMirror reflect(Object reflectee);
+
+/**
+ * Reflects a class declaration.
+ *
+ * Let *C* be the original class declaration of the class represented by [key].
+ * This function returns a [ClassMirror] reflecting *C*.
+ *
+ * If [key] is not an instance of [Type], then this function throws an
+ * [ArgumentError]. If [key] is the Type for dynamic or a function typedef,
+ * throws an [ArgumentError].
+ *
+ * Note that since one cannot obtain a [Type] object from another isolate, this
+ * function can only be used to obtain class mirrors on classes of the current
+ * isolate.
+ */
+external ClassMirror reflectClass(Type key);
+
+/**
+ * Reflects the type represented by [key].
+ *
+ * If [key] is not an instance of [Type], then this function throws an
+ * [ArgumentError].
+ *
+ * Optionally takes a list of [typeArguments] for generic classes. If the list
+ * is provided, then the [key] must be a generic class type, and the number of
+ * the provided type arguments must be equal to the number of type variables
+ * declared by the class.
+ *
+ * Note that since one cannot obtain a [Type] object from another isolate, this
+ * function can only be used to obtain type mirrors on types of the current
+ * isolate.
+ */
+external TypeMirror reflectType(Type key, [List<Type> typeArguments]);
+
+/**
+ * A [Mirror] reflects some Dart language entity.
+ *
+ * Every [Mirror] originates from some [MirrorSystem].
+ */
+abstract class Mirror {}
+
+/**
+ * An [IsolateMirror] reflects an isolate.
+ */
+abstract class IsolateMirror implements Mirror {
+  /**
+   * A unique name used to refer to the isolate in debugging messages.
+   */
+  String get debugName;
+
+  /**
+   * Whether this mirror reflects the currently running isolate.
+   */
+  bool get isCurrent;
+
+  /**
+   * The root library for the reflected isolate.
+   */
+  LibraryMirror get rootLibrary;
+
+  /**
+   * Whether [other] is an [IsolateMirror] on the same isolate as this mirror.
+   *
+   * The equality holds if and only if
+   *
+   * 1. [other] is a mirror of the same kind, and
+   * 2. the isolate being reflected by this mirror is the same isolate being
+   *    reflected by [other].
+   */
+  bool operator ==(other);
+
+  /**
+   * Loads the library at the given uri into this isolate.
+   *
+   * WARNING: You are strongly encouraged to use Isolate.spawnUri instead when
+   * possible. IsolateMirror.loadUri should only be used when synchronous
+   * communication or shared state with dynamically loaded code is needed.
+   *
+   * If a library with the same canonicalized uri has already been loaded,
+   * the existing library will be returned. (The isolate will not load a new
+   * copy of the library.)
+   *
+   * This behavior is similar to the behavior of an import statement that
+   * appears in the root library, except that the import scope of the root
+   * library is not changed.
+   */
+  Future<LibraryMirror> loadUri(Uri uri);
+}
+
+/**
+ * A [DeclarationMirror] reflects some entity declared in a Dart program.
+ */
+abstract class DeclarationMirror implements Mirror {
+  /**
+   * The simple name for this Dart language entity.
+   *
+   * The simple name is in most cases the identifier name of the entity,
+   * such as 'myMethod' for a method, [:void myMethod() {...}:] or 'mylibrary'
+   * for a [:library 'mylibrary';:] declaration.
+   */
+  Symbol get simpleName;
+
+  /**
+   * The fully-qualified name for this Dart language entity.
+   *
+   * This name is qualified by the name of the owner. For instance,
+   * the qualified name of a method 'method' in class 'Class' in
+   * library 'library' is 'library.Class.method'.
+   *
+   * Returns a [Symbol] constructed from a string representing the
+   * fully qualified name of the reflectee.
+   * Let *o* be the [owner] of this mirror, let *r* be the reflectee of
+   * this mirror, let *p* be the fully qualified
+   * name of the reflectee of *o*, and let *s* be the simple name of *r*
+   * computed by [simpleName].
+   * The fully qualified name of *r* is the
+   * concatenation of *p*, '.', and *s*.
+   *
+   * Because an isolate can contain more than one library with the same name (at
+   * different URIs), a fully-qualified name does not uniquely identify any
+   * language entity.
+   */
+  Symbol get qualifiedName;
+
+  /**
+   * A mirror on the owner of this Dart language entity.
+   *
+   * The owner is the declaration immediately surrounding the reflectee:
+   *
+   * * For a library, the owner is [:null:].
+   * * For a class declaration, typedef or top level function or variable, the
+   *   owner is the enclosing library.
+   * * For a mixin application `S with M`, the owner is the owner of `M`.
+   * * For a constructor, the owner is the immediately enclosing class.
+   * * For a method, instance variable or a static variable, the owner is the
+   *   immediately enclosing class, unless the class is a mixin application
+   *   `S with M`, in which case the owner is `M`. Note that `M` may be an
+   *   invocation of a generic.
+   * * For a parameter, local variable or local function the owner is the
+   *   immediately enclosing function.
+   */
+  DeclarationMirror get owner;
+
+  /**
+   * Whether this declaration is library private.
+   *
+   * Always returns `false` for a library declaration,
+   * otherwise returns `true` if the declaration's name starts with an
+   * underscore character (`_`), and `false` if it doesn't.
+   */
+  bool get isPrivate;
+
+  /**
+   * Whether this declaration is top-level.
+   *
+   * A declaration is considered top-level if its [owner] is a [LibraryMirror].
+   */
+  bool get isTopLevel;
+
+  /**
+   * The source location of this Dart language entity, or [:null:] if the
+   * entity is synthetic.
+   *
+   * If the reflectee is a variable, the returned location gives the position
+   * of the variable name at its point of declaration.
+   *
+   * If the reflectee is a library, class, typedef, function or type variable
+   * with associated metadata, the returned location gives the position of the
+   * first metadata declaration associated with the reflectee.
+   *
+   * Otherwise:
+   *
+   * If the reflectee is a library, the returned location gives the position of
+   * the keyword 'library' at the reflectee's point of declaration, if the
+   * reflectee is a named library, or the first character of the first line in
+   * the compilation unit defining the reflectee if the reflectee is anonymous.
+   *
+   * If the reflectee is an abstract class, the returned location gives the
+   * position of the keyword 'abstract' at the reflectee's point of declaration.
+   * Otherwise, if the reflectee is a class, the returned location gives the
+   * position of the keyword 'class' at the reflectee's point of declaration.
+   *
+   * If the reflectee is a typedef the returned location gives the position of
+   * the of the keyword 'typedef' at the reflectee's point of declaration.
+   *
+   * If the reflectee is a function with a declared return type, the returned
+   * location gives the position of the function's return type at the
+   * reflectee's point of declaration. Otherwise. the returned location gives
+   * the position of the function's name at the reflectee's point of
+   * declaration.
+   *
+   * This operation is optional and may throw an [UnsupportedError].
+   */
+  SourceLocation get location;
+
+  /**
+   * A list of the metadata associated with this declaration.
+   *
+   * Let *D* be the declaration this mirror reflects.
+   * If *D* is decorated with annotations *A1, ..., An*
+   * where *n > 0*, then for each annotation *Ai* associated
+   * with *D, 1 <= i <= n*, let *ci* be the constant object
+   * specified by *Ai*. Then this method returns a list whose
+   * members are instance mirrors on *c1, ..., cn*.
+   * If no annotations are associated with *D*, then
+   * an empty list is returned.
+   *
+   * If evaluating any of *c1, ..., cn* would cause a
+   * compilation error
+   * the effect is the same as if a non-reflective compilation error
+   * had been encountered.
+   */
+  List<InstanceMirror> get metadata;
+}
+
+/**
+ * An [ObjectMirror] is a common superinterface of [InstanceMirror],
+ * [ClassMirror], and [LibraryMirror] that represents their shared
+ * functionality.
+ *
+ * For the purposes of the mirrors library, these types are all
+ * object-like, in that they support method invocation and field
+ * access.  Real Dart objects are represented by the [InstanceMirror]
+ * type.
+ *
+ * See [InstanceMirror], [ClassMirror], and [LibraryMirror].
+ */
+abstract class ObjectMirror implements Mirror {
+  /**
+   * Invokes the named function and returns a mirror on the result.
+   *
+   * Let *o* be the object reflected by this mirror, let *f* be the simple name
+   * of the member denoted by [memberName], let *a1, ..., an* be the elements
+   * of [positionalArguments], let *k1, ..., km* be the identifiers denoted by
+   * the elements of [namedArguments.keys], and let *v1, ..., vm* be the
+   * elements of [namedArguments.values]. Then this method will perform the
+   * method invocation *o.f(a1, ..., an, k1: v1, ..., km: vm)* in a scope that
+   * has access to the private members of *o* (if *o* is a class or library) or
+   * the private members of the class of *o* (otherwise).
+   *
+   * If the invocation returns a result *r*, this method returns the result of
+   * calling [reflect]\(*r*\).
+   *
+   * If the invocation causes a compilation error the effect is the same as if
+   * a non-reflective compilation error had been encountered.
+   *
+   * If the invocation throws an exception *e* (that it does not catch), this
+   * method throws *e*.
+   */
+  /*
+   * TODO(turnidge): Handle ambiguous names.
+   * TODO(turnidge): Handle optional & named arguments.
+   */
+  InstanceMirror invoke(Symbol memberName, List positionalArguments,
+      [Map<Symbol, dynamic> namedArguments]);
+
+  /**
+   * Invokes a getter and returns a mirror on the result.
+   *
+   * The getter can be the implicit getter for a field or a user-defined getter
+   * method.
+   *
+   * Let *o* be the object reflected by this mirror,
+   * let *f* be the simple name of the getter denoted by [fieldName].
+   *
+   * Then this method will perform the getter invocation *o.f* in a scope that
+   * has access to the private members of *o* (if *o* is a class or library) or
+   * the private members of the class of *o* (otherwise).
+   *
+   * If this mirror is an [InstanceMirror], and [fieldName] denotes an instance
+   * method on its reflectee, the result of the invocation is an instance
+   * mirror on a closure corresponding to that method.
+   *
+   * If this mirror is a [LibraryMirror], and [fieldName] denotes a top-level
+   * method in the corresponding library, the result of the invocation is an
+   * instance mirror on a closure corresponding to that method.
+   *
+   * If this mirror is a [ClassMirror], and [fieldName] denotes a static method
+   * in the corresponding class, the result of the invocation is an instance
+   * mirror on a closure corresponding to that method.
+   *
+   * If the invocation returns a result *r*, this method returns the result of
+   * calling [reflect]\(*r*\).
+   *
+   * If the invocation causes a compilation error, the effect is the same as if
+   * a non-reflective compilation error had been encountered.
+   *
+   * If the invocation throws an exception *e* (that it does not catch), this
+   * method throws *e*.
+   */
+  // TODO(ahe): Remove stuff about scope and private members. [fieldName] is a
+  // capability giving access to private members.
+  InstanceMirror getField(Symbol fieldName);
+
+  /**
+   * Invokes a setter and returns a mirror on the result.
+   *
+   * The setter may be either the implicit setter for a non-final field or a
+   * user-defined setter method.
+   *
+   * Let *o* be the object reflected by this mirror,
+   * let *f* be the simple name of the getter denoted by [fieldName],
+   * and let *a* be the object bound to [value].
+   *
+   * Then this method will perform the setter invocation *o.f = a* in a scope
+   * that has access to the private members of *o* (if *o* is a class or
+   * library) or the private members of the class of *o* (otherwise).
+   *
+   * If the invocation returns a result *r*, this method returns the result of
+   * calling [reflect]\([value]\).
+   *
+   * If the invocation causes a compilation error, the effect is the same as if
+   * a non-reflective compilation error had been encountered.
+   *
+   * If the invocation throws an exception *e* (that it does not catch) this
+   * method throws *e*.
+   */
+  /* TODO(turnidge): Handle ambiguous names.*/
+  InstanceMirror setField(Symbol fieldName, Object value);
+
+  /**
+   * Performs [invocation] on the reflectee of this [ObjectMirror].
+   *
+   * Equivalent to
+   *
+   *     if (invocation.isGetter) {
+   *       return this.getField(invocation.memberName).reflectee;
+   *     } else if (invocation.isSetter) {
+   *       return this.setField(invocation.memberName,
+   *                            invocation.positionalArguments[0]).reflectee;
+   *     } else {
+   *       return this.invoke(invocation.memberName,
+   *                          invocation.positionalArguments,
+   *                          invocation.namedArguments).reflectee;
+   *     }
+   */
+  delegate(Invocation invocation);
+}
+
+/**
+ * An [InstanceMirror] reflects an instance of a Dart language object.
+ */
+abstract class InstanceMirror implements ObjectMirror {
+  /**
+   * A mirror on the type of the reflectee.
+   *
+   * Returns a mirror on the actual class of the reflectee.
+   * The class of the reflectee may differ from
+   * the object returned by invoking [runtimeType] on
+   * the reflectee.
+   */
+  ClassMirror get type;
+
+  /**
+   * Whether [reflectee] will return the instance reflected by this mirror.
+   *
+   * This will always be true in the local case (reflecting instances in the
+   * same isolate), but only true in the remote case if this mirror reflects a
+   * simple value.
+   *
+   * A value is simple if one of the following holds:
+   *
+   * * the value is [:null:]
+   * * the value is of type [num]
+   * * the value is of type [bool]
+   * * the value is of type [String]
+   */
+  bool get hasReflectee;
+
+  /**
+   * If the [InstanceMirror] reflects an instance it is meaningful to
+   * have a local reference to, we provide access to the actual
+   * instance here.
+   *
+   * If you access [reflectee] when [hasReflectee] is false, an
+   * exception is thrown.
+   */
+  get reflectee;
+
+  /**
+   * Whether this mirror is equal to [other].
+   *
+   * The equality holds if and only if
+   *
+   * 1. [other] is a mirror of the same kind, and
+   * 2. either
+   *
+   *    a. [hasReflectee] is true and so is
+   *    [:identical(reflectee, other.reflectee):], or
+   *
+   *    b. the remote objects reflected by this mirror and by [other] are
+   *    identical.
+   */
+  bool operator ==(other);
+}
+
+/**
+ * A [ClosureMirror] reflects a closure.
+ *
+ * A [ClosureMirror] provides the ability to execute its reflectee and
+ * introspect its function.
+ */
+abstract class ClosureMirror implements InstanceMirror {
+  /**
+   * A mirror on the function associated with this closure.
+   *
+   * The function associated with an implicit closure of a function is that
+   * function.
+   *
+   * The function associated with an instance of a class that has a [:call:]
+   * method is that [:call:] method.
+   *
+   * A Dart implementation might choose to create a class for each closure
+   * expression, in which case [:function:] would be the same as
+   * [:type.declarations[#call]:]. But the Dart language model does not require
+   * this. A more typical implementation involves a single closure class for
+   * each type signature, where the call method dispatches to a function held
+   * in the closure rather the call method
+   * directly implementing the closure body. So one cannot rely on closures from
+   * distinct closure expressions having distinct classes ([:type:]), but one
+   * can rely on them having distinct functions ([:function:]).
+   */
+  MethodMirror get function;
+
+  /**
+   * Executes the closure and returns a mirror on the result.
+   *
+   * Let *f* be the closure reflected by this mirror,
+   * let *a1, ..., an* be the elements of [positionalArguments],
+   * let *k1, ..., km* be the identifiers denoted by the elements of
+   * [namedArguments.keys],
+   * and let *v1, ..., vm* be the elements of [namedArguments.values].
+   *
+   * Then this method will perform the method invocation
+   * *f(a1, ..., an, k1: v1, ..., km: vm)*.
+   *
+   * If the invocation returns a result *r*, this method returns the result of
+   * calling [reflect]\(*r*\).
+   *
+   * If the invocation causes a compilation error, the effect is the same as if
+   * a non-reflective compilation error had been encountered.
+   *
+   * If the invocation throws an exception *e* (that it does not catch), this
+   * method throws *e*.
+   */
+  InstanceMirror apply(List positionalArguments,
+      [Map<Symbol, dynamic> namedArguments]);
+}
+
+/**
+ * A [LibraryMirror] reflects a Dart language library, providing
+ * access to the variables, functions, and classes of the
+ * library.
+ */
+abstract class LibraryMirror implements DeclarationMirror, ObjectMirror {
+  /**
+   * The absolute uri of the library.
+   */
+  Uri get uri;
+
+  /**
+   * Returns an immutable map of the declarations actually given in the library.
+   *
+   * This map includes all regular methods, getters, setters, fields, classes
+   * and typedefs actually declared in the library. The map is keyed by the
+   * simple names of the declarations.
+   */
+  Map<Symbol, DeclarationMirror> get declarations;
+
+  /**
+   * Whether this mirror is equal to [other].
+   *
+   * The equality holds if and only if
+   *
+   * 1. [other] is a mirror of the same kind, and
+   * 2. The library being reflected by this mirror and the library being
+   *    reflected by [other] are the same library in the same isolate.
+   */
+  bool operator ==(other);
+
+  /**
+   * Returns a list of the imports and exports in this library;
+   */
+  List<LibraryDependencyMirror> get libraryDependencies;
+}
+
+/// A mirror on an import or export declaration.
+abstract class LibraryDependencyMirror implements Mirror {
+  /// Is `true` if this dependency is an import.
+  bool get isImport;
+
+  /// Is `true` if this dependency is an export.
+  bool get isExport;
+
+  /// Returns true iff this dependency is a deferred import. Otherwise returns
+  /// false.
+  bool get isDeferred;
+
+  /// Returns the library mirror of the library that imports or exports the
+  /// [targetLibrary].
+  LibraryMirror get sourceLibrary;
+
+  /// Returns the library mirror of the library that is imported or exported,
+  /// or null if the library is not loaded.
+  LibraryMirror get targetLibrary;
+
+  /// Returns the prefix if this is a prefixed import and `null` otherwise.
+  Symbol get prefix;
+
+  /// Returns the list of show/hide combinators on the import/export
+  /// declaration.
+  List<CombinatorMirror> get combinators;
+
+  /// Returns the source location for this import/export declaration.
+  SourceLocation get location;
+
+  List<InstanceMirror> get metadata;
+
+  /// Returns a future that completes with a library mirror on the library being
+  /// imported or exported when it is loaded, and initiates a load of that
+  /// library if it is not loaded.
+  Future<LibraryMirror> loadLibrary();
+}
+
+/// A mirror on a show/hide combinator declared on a library dependency.
+abstract class CombinatorMirror implements Mirror {
+  /// The list of identifiers on the combinator.
+  List<Symbol> get identifiers;
+
+  /// Is `true` if this is a 'show' combinator.
+  bool get isShow;
+
+  /// Is `true` if this is a 'hide' combinator.
+  bool get isHide;
+}
+
+/**
+ * A [TypeMirror] reflects a Dart language class, typedef,
+ * function type or type variable.
+ */
+abstract class TypeMirror implements DeclarationMirror {
+  /**
+   * Returns true if this mirror reflects dynamic, a non-generic class or
+   * typedef, or an instantiated generic class or typedef in the current
+   * isolate. Otherwise, returns false.
+   */
+  bool get hasReflectedType;
+
+  /**
+   * If [:hasReflectedType:] returns true, returns the corresponding [Type].
+   * Otherwise, an [UnsupportedError] is thrown.
+   */
+  Type get reflectedType;
+
+  /**
+   * An immutable list with mirrors for all type variables for this type.
+   *
+   * If this type is a generic declaration or an invocation of a generic
+   * declaration, the returned list contains mirrors on the type variables
+   * declared in the original declaration.
+   * Otherwise, the returned list is empty.
+   *
+   * This list preserves the order of declaration of the type variables.
+   */
+  List<TypeVariableMirror> get typeVariables;
+
+  /**
+   * An immutable list with mirrors for all type arguments for
+   * this type.
+   *
+   * If the reflectee is an invocation of a generic class,
+   * the type arguments are the bindings of its type parameters.
+   * If the reflectee is the original declaration of a generic,
+   * it has no type arguments and this method returns an empty list.
+   * If the reflectee is not generic, then
+   * it has no type arguments and this method returns an empty list.
+   *
+   * This list preserves the order of declaration of the type variables.
+   */
+  List<TypeMirror> get typeArguments;
+
+  /**
+   * Is this the original declaration of this type?
+   *
+   * For most classes, they are their own original declaration.  For
+   * generic classes, however, there is a distinction between the
+   * original class declaration, which has unbound type variables, and
+   * the instantiations of generic classes, which have bound type
+   * variables.
+   */
+  bool get isOriginalDeclaration;
+
+  /**
+   * A mirror on the original declaration of this type.
+   *
+   * For most classes, they are their own original declaration.  For
+   * generic classes, however, there is a distinction between the
+   * original class declaration, which has unbound type variables, and
+   * the instantiations of generic classes, which have bound type
+   * variables.
+   */
+  TypeMirror get originalDeclaration;
+
+  /**
+   * Checks the subtype relationship, denoted by `<:` in the language
+   * specification.
+   *
+   * This is the type relationship used in `is` test checks.
+   */
+  bool isSubtypeOf(TypeMirror other);
+
+  /**
+   * Checks the assignability relationship, denoted by `<=>` in the language
+   * specification.
+   *
+   * This is the type relationship tested on assignment in checked mode.
+   */
+  bool isAssignableTo(TypeMirror other);
+}
+
+/**
+ * A [ClassMirror] reflects a Dart language class.
+ */
+abstract class ClassMirror implements TypeMirror, ObjectMirror {
+  /**
+   * A mirror on the superclass on the reflectee.
+   *
+   * If this type is [:Object:], the superclass will be null.
+   */
+  ClassMirror get superclass;
+
+  /**
+   * A list of mirrors on the superinterfaces of the reflectee.
+   */
+  List<ClassMirror> get superinterfaces;
+
+  /**
+   * Is the reflectee abstract?
+   */
+  bool get isAbstract;
+
+  /**
+   * Is the reflectee an enum?
+   */
+  bool get isEnum;
+
+  /**
+   * Returns an immutable map of the declarations actually given in the class
+   * declaration.
+   *
+   * This map includes all regular methods, getters, setters, fields,
+   * constructors and type variables actually declared in the class. Both
+   * static and instance members are included, but no inherited members are
+   * included. The map is keyed by the simple names of the declarations.
+   *
+   * This does not include inherited members.
+   */
+  Map<Symbol, DeclarationMirror> get declarations;
+
+  /**
+   * Returns a map of the methods, getters and setters of an instance of the
+   * class.
+   *
+   * The intent is to capture those members that constitute the API of an
+   * instance. Hence fields are not included, but the getters and setters
+   * implicitly introduced by fields are included. The map includes methods,
+   * getters and setters that are inherited as well as those introduced by the
+   * class itself.
+   *
+   * The map is keyed by the simple names of the members.
+   */
+  Map<Symbol, MethodMirror> get instanceMembers;
+
+  /**
+   * Returns a map of the static methods, getters and setters of the class.
+   *
+   * The intent is to capture those members that constitute the API of a class.
+   * Hence fields are not included, but the getters and setters implicitly
+   * introduced by fields are included.
+   *
+   * The map is keyed by the simple names of the members.
+   */
+  Map<Symbol, MethodMirror> get staticMembers;
+
+  /**
+   * The mixin of this class.
+   *
+   * If this class is the result of a mixin application of the form S with M,
+   * returns a class mirror on M. Otherwise returns a class mirror on
+   * the reflectee.
+   */
+  ClassMirror get mixin;
+
+  // TODO(ahe): What about:
+  // /// Finds the instance member named [name] declared or inherited in the
+  // /// reflected class.
+  // DeclarationMirror instanceLookup(Symbol name);
+
+  /**
+   * Invokes the named constructor and returns a mirror on the result.
+   *
+   * Let *c* be the class reflected by this mirror,
+   * let *a1, ..., an* be the elements of [positionalArguments],
+   * let *k1, ..., km* be the identifiers denoted by the elements of
+   * [namedArguments.keys],
+   * and let *v1, ..., vm* be the elements of [namedArguments.values].
+   *
+   * If [constructorName] was created from the empty string, then this method
+   * will execute the instance creation expression
+   * *new c(a1, ..., an, k1: v1, ..., km: vm)* in a scope that has access to
+   * the private members of *c*.
+   *
+   * Otherwise, let *f* be the simple name of the constructor denoted by
+   * [constructorName]. Then this method will execute the instance creation
+   * expression *new c.f(a1, ..., an, k1: v1, ..., km: vm)* in a scope that has
+   * access to the private members of *c*.
+   *
+   * In either case:
+   *
+   * * If the expression evaluates to a result *r*, this method returns the
+   *   result of calling [reflect]\(*r*\).
+   * * If evaluating the expression causes a compilation error, the effect is
+   *   the same as if a non-reflective compilation error had been encountered.
+   * * If evaluating the expression throws an exception *e* (that it does not
+   *   catch), this method throws *e*.
+   */
+  InstanceMirror newInstance(Symbol constructorName, List positionalArguments,
+      [Map<Symbol, dynamic> namedArguments]);
+
+  /**
+   * Whether this mirror is equal to [other].
+   *
+   * The equality holds if and only if
+   *
+   * 1. [other] is a mirror of the same kind, and
+   * 2. This mirror and [other] reflect the same class.
+   *
+   * Note that if the reflected class is an invocation of a generic class, 2.
+   * implies that the reflected class and [other] have equal type arguments.
+   */
+  bool operator ==(other);
+
+  /**
+   * Returns whether the class denoted by the receiver is a subclass of the
+   * class denoted by the argument.
+   *
+   * Note that the subclass relationship is reflexive.
+   */
+  bool isSubclassOf(ClassMirror other);
+}
+
+/**
+ * A [FunctionTypeMirror] represents the type of a function in the
+ * Dart language.
+ */
+abstract class FunctionTypeMirror implements ClassMirror {
+  /**
+   * Returns the return type of the reflectee.
+   */
+  TypeMirror get returnType;
+
+  /**
+   * Returns a list of the parameter types of the reflectee.
+   */
+  List<ParameterMirror> get parameters;
+
+  /**
+   * A mirror on the [:call:] method for the reflectee.
+   */
+  // This is only here because in the past the VM did not implement a call
+  // method on closures.
+  MethodMirror get callMethod;
+}
+
+/**
+ * A [TypeVariableMirror] represents a type parameter of a generic type.
+ */
+abstract class TypeVariableMirror extends TypeMirror {
+  /**
+   * A mirror on the type that is the upper bound of this type variable.
+   */
+  TypeMirror get upperBound;
+
+  /**
+   * Is the reflectee static?
+   *
+   * For the purposes of the mirrors library, type variables are considered
+   * non-static.
+   */
+  bool get isStatic;
+
+  /**
+   * Whether [other] is a [TypeVariableMirror] on the same type variable as this
+   * mirror.
+   *
+   * The equality holds if and only if
+   *
+   * 1. [other] is a mirror of the same kind, and
+   * 2. [:simpleName == other.simpleName:] and [:owner == other.owner:].
+   */
+  bool operator ==(other);
+}
+
+/**
+ * A [TypedefMirror] represents a typedef in a Dart language program.
+ */
+abstract class TypedefMirror implements TypeMirror {
+  /**
+   * The defining type for this typedef.
+   *
+   * If the type referred to by the reflectee is a function type *F*, the
+   * result will be [:FunctionTypeMirror:] reflecting *F* which is abstract
+   * and has an abstract method [:call:] whose signature corresponds to *F*.
+   * For instance [:void f(int):] is the referent for [:typedef void f(int):].
+   */
+  FunctionTypeMirror get referent;
+}
+
+/**
+ * A [MethodMirror] reflects a Dart language function, method,
+ * constructor, getter, or setter.
+ */
+abstract class MethodMirror implements DeclarationMirror {
+  /**
+   * A mirror on the return type for the reflectee.
+   */
+  TypeMirror get returnType;
+
+  /**
+   * The source code for the reflectee, if available. Otherwise null.
+   */
+  String get source;
+
+  /**
+   * A list of mirrors on the parameters for the reflectee.
+   */
+  List<ParameterMirror> get parameters;
+
+  /**
+   * A function is considered non-static iff it is permited to refer to 'this'.
+   *
+   * Note that generative constructors are considered non-static, whereas
+   * factory constructors are considered static.
+   */
+  bool get isStatic;
+
+  /**
+   * Is the reflectee abstract?
+   */
+  bool get isAbstract;
+
+  /**
+   * Returns true if the reflectee is synthetic, and returns false otherwise.
+   *
+   * A reflectee is synthetic if it is a getter or setter implicitly introduced
+   * for a field or Type, or if it is a constructor that was implicitly
+   * introduced as a default constructor or as part of a mixin application.
+   */
+  bool get isSynthetic;
+
+  /**
+   * Is the reflectee a regular function or method?
+   *
+   * A function or method is regular if it is not a getter, setter, or
+   * constructor.  Note that operators, by this definition, are
+   * regular methods.
+   */
+  bool get isRegularMethod;
+
+  /**
+   * Is the reflectee an operator?
+   */
+  bool get isOperator;
+
+  /**
+   * Is the reflectee a getter?
+   */
+  bool get isGetter;
+
+  /**
+   * Is the reflectee a setter?
+   */
+  bool get isSetter;
+
+  /**
+   * Is the reflectee a constructor?
+   */
+  bool get isConstructor;
+
+  /**
+   * The constructor name for named constructors and factory methods.
+   *
+   * For unnamed constructors, this is the empty string.  For
+   * non-constructors, this is the empty string.
+   *
+   * For example, [:'bar':] is the constructor name for constructor
+   * [:Foo.bar:] of type [:Foo:].
+   */
+  Symbol get constructorName;
+
+  /**
+   * Is the reflectee a const constructor?
+   */
+  bool get isConstConstructor;
+
+  /**
+   * Is the reflectee a generative constructor?
+   */
+  bool get isGenerativeConstructor;
+
+  /**
+   * Is the reflectee a redirecting constructor?
+   */
+  bool get isRedirectingConstructor;
+
+  /**
+   * Is the reflectee a factory constructor?
+   */
+  bool get isFactoryConstructor;
+
+  /**
+   * Whether this mirror is equal to [other].
+   *
+   * The equality holds if and only if
+   *
+   * 1. [other] is a mirror of the same kind, and
+   * 2. [:simpleName == other.simpleName:] and [:owner == other.owner:].
+   */
+  bool operator ==(other);
+}
+
+/**
+ * A [VariableMirror] reflects a Dart language variable declaration.
+ */
+abstract class VariableMirror implements DeclarationMirror {
+  /**
+   * Returns a mirror on the type of the reflectee.
+   */
+  TypeMirror get type;
+
+  /**
+   * Returns [:true:] if the reflectee is a static variable.
+   * Otherwise returns [:false:].
+   *
+   * For the purposes of the mirror library, top-level variables are
+   * implicitly declared static.
+   */
+  bool get isStatic;
+
+  /**
+   * Returns [:true:] if the reflectee is a final variable.
+   * Otherwise returns [:false:].
+   */
+  bool get isFinal;
+
+  /**
+   * Returns [:true:] if the reflectee is declared [:const:].
+   * Otherwise returns [:false:].
+   */
+  bool get isConst;
+
+  /**
+   * Whether this mirror is equal to [other].
+   *
+   * The equality holds if and only if
+   *
+   * 1. [other] is a mirror of the same kind, and
+   * 2. [:simpleName == other.simpleName:] and [:owner == other.owner:].
+   */
+  bool operator ==(other);
+}
+
+/**
+ * A [ParameterMirror] reflects a Dart formal parameter declaration.
+ */
+abstract class ParameterMirror implements VariableMirror {
+  /**
+   * A mirror on the type of this parameter.
+   */
+  TypeMirror get type;
+
+  /**
+   * Returns [:true:] if the reflectee is an optional parameter.
+   * Otherwise returns [:false:].
+   */
+  bool get isOptional;
+
+  /**
+   * Returns [:true:] if the reflectee is a named parameter.
+   * Otherwise returns [:false:].
+   */
+  bool get isNamed;
+
+  /**
+   * Returns [:true:] if the reflectee has explicitly declared a default value.
+   * Otherwise returns [:false:].
+   */
+  bool get hasDefaultValue;
+
+  /**
+   * Returns the default value of an optional parameter.
+   *
+   * Returns an [InstanceMirror] on the (compile-time constant)
+   * default value for an optional parameter.
+   * If no default value is declared, it defaults to `null`
+   * and a mirror of `null` is returned.
+   *
+   * Returns `null` for a required parameter.
+   */
+  InstanceMirror get defaultValue;
+}
+
+/**
+ * A [SourceLocation] describes the span of an entity in Dart source code.
+ */
+abstract class SourceLocation {
+  /**
+   * The 1-based line number for this source location.
+   *
+   * A value of 0 means that the line number is unknown.
+   */
+  int get line;
+
+  /**
+   * The 1-based column number for this source location.
+   *
+   * A value of 0 means that the column number is unknown.
+   */
+  int get column;
+
+  /**
+   * Returns the URI where the source originated.
+   */
+  Uri get sourceUri;
+}
+
+/**
+ * Class used for encoding comments as metadata annotations.
+ */
+class Comment {
+  /**
+   * The comment text as written in the source text.
+   */
+  final String text;
+
+  /**
+   * The comment text without the start, end, and padding text.
+   *
+   * For example, if [text] is [: /** Comment text. */ :] then the [trimmedText]
+   * is [: Comment text. :].
+   */
+  final String trimmedText;
+
+  /**
+   * Is [:true:] if this comment is a documentation comment.
+   *
+   * That is, that the comment is either enclosed in [: /** ... */ :] or starts
+   * with [: /// :].
+   */
+  final bool isDocComment;
+
+  const Comment(this.text, this.trimmedText, this.isDocComment);
+}
+
+/**
+ * Annotation describing how "dart:mirrors" is used (EXPERIMENTAL).
+ *
+ * When used as metadata on an import of "dart:mirrors" in library *L*, this
+ * class describes how "dart:mirrors" is used by library *L* unless overridden.
+ * See [override].
+ *
+ * The following text is non-normative:
+ *
+ * In some scenarios, for example, when minifying Dart code, or when generating
+ * JavaScript code from a Dart program, the size and performance of the output
+ * can suffer from use of reflection.  In those cases, telling the compiler
+ * what is used, can have a significant impact.
+ *
+ * Example usage:
+ *
+ *     @MirrorsUsed(symbols: 'foo')
+ *     import 'dart:mirrors';
+ *
+ *     class Foo {
+ *       noSuchMethod(Invocation invocation) {
+ *         print(MirrorSystem.getName(invocation.memberName));
+ *       }
+ *     }
+ *
+ *     main() {
+ *       new Foo().foo(); // Prints "foo".
+ *       new Foo().bar(); // Might print an arbitrary (mangled) name, "bar".
+ *     }
+ *
+ * For a detailed description of the parameters to the [MirrorsUsed] constructor
+ * see the comments for [symbols], [targets], [metaTargets] and [override].
+ *
+ * An import of `dart:mirrors` may have multiple [MirrorsUsed] annotations. This
+ * is particularly helpful to specify overrides for specific libraries. For
+ * example:
+ *
+ *     @MirrorsUsed(targets: 'foo.Bar', override: 'foo')
+ *     @MirrorsUsed(targets: 'Bar')
+ *     import 'dart:mirrors';
+ *
+ * will ensure that the target `Bar` from the current library and from library
+ * `foo` is available for reflection. See also [override].
+ */
+@Deprecated("No longer has any effect. Will be removed in a later release.")
+class MirrorsUsed {
+  // Note: the fields of this class are untyped.  This is because the most
+  // convenient way to specify symbols today is using a single string. In
+  // some cases, a const list of classes might be convenient. Some
+  // might prefer to use a const list of symbols.
+
+  /**
+   * The list of strings passed to new [Symbol], and symbols that might be
+   * passed to [MirrorSystem.getName].
+   *
+   * Combined with the names of [targets], [metaTargets] and their members,
+   * this forms the complete list of strings passed to new [Symbol], and
+   * symbols that might be passed to [MirrorSystem.getName] by the library to
+   * which this metadata applies.
+   *
+   * The following text is non-normative:
+   *
+   * Dart2js currently supports the following formats to specify symbols:
+   *
+   * * A constant [List] of [String] constants representing symbol names,
+   *   e.g., `const ['foo', 'bar']`.
+   * * A single [String] constant whose value is a comma-separated list of
+   *   symbol names, e.g., `"foo, bar"`.
+   *
+   * Specifying the `symbols` field turns off the following warnings emitted by
+   * dart2js:
+   *
+   * * Using "MirrorSystem.getName" may result in larger output.
+   * * Using "new Symbol" may result in larger output.
+   *
+   * For example, if you're using [noSuchMethod] to interact with a database,
+   * extract all the possible column names and include them in this list.
+   * Similarly, if you're using [noSuchMethod] to interact with another
+   * language (JavaScript, for example) extract all the identifiers from the
+   * API you use and include them in this list.
+   *
+   * Note that specifying a symbol only ensures that the symbol will be
+   * available under that name at runtime. It does not mark targets with
+   * that name as available for reflection. See [targets] and [metaTargets]
+   * for that purpose.
+   */
+  final symbols;
+
+  /**
+   * A list of reflective targets.
+   *
+   * Combined with [metaTargets], this provides the complete list of reflective
+   * targets used by the library to which this metadata applies.
+   *
+   * The following text is non-normative:
+   *
+   * For now, there is no formal description of what a reflective target is.
+   * Informally, a target is a library, a class, a method or a field.
+   *
+   * Dart2js currently supports the following formats to specify targets:
+   *
+   * * A constant [List] containing [String] constants representing (qualified)
+   *   names of targets and Dart types.
+   * * A single [String] constant whose value is a comma-separated list of
+   *   (qualified) names.
+   * * A single Dart type.
+   *
+   * A (qualified) name is resolved to a target as follows:
+   *
+   * 1. If the qualified name matches a library name, the matching library is
+   *    the target.
+   * 2. Else, find the longest prefix of the name such that the prefix ends
+   *    just before a `.` and is a library name.
+   * 3. Use that library as current scope. If no matching prefix was found, use
+   *    the current library, i.e., the library where the [MirrorsUsed]
+   *    annotation was placed.
+   * 4. Split the remaining suffix (the entire name if no library name was
+   *    found in step 3) into a list of [String] using `.` as a
+   *    separator.
+   * 5. Select all targets in the current scope whose name matches a [String]
+   *    from the list.
+   *
+   * For example:
+   *
+   *     library my.library.one;
+   *
+   *     class A {
+   *       var aField;
+   *     }
+   *
+   *     library main;
+   *
+   *     @MirrorsUsed(targets: "my.library.one.A.aField")
+   *     import "dart:mirrors";
+   *
+   * The [MirrorsUsed] annotation specifies `A` and `aField` from library
+   * `my.library.one` as targets. This will mark the class `A` as a reflective
+   * target. The target specification for `aField` has no effect, as there is
+   * no target in `my.library.one` with that name.
+   *
+   * Note that everything within a target also is available for reflection.
+   * So, if a library is specified as target, all classes in that library
+   * become targets for reflection. Likewise, if a class is a target, all
+   * its methods and fields become targets for reflection. As a consequence,
+   * `aField` in the above example is also a reflective target.
+   *
+   */
+  final targets;
+
+  /**
+   * A list of classes that when used as metadata indicates a reflective
+   * target. See also [targets].
+   *
+   * The following text is non-normative:
+   *
+   * The format for specifying the list of classes is the same as used for
+   * specifying [targets]. However, as a library cannot be used as a metadata
+   * annotation in Dart, adding a library to the list of [metaTargets] has no
+   * effect. In particular, adding a library to [metaTargets] does not make
+   * the library's classes valid metadata annotations to enable reflection.
+   *
+   * If an instance of a class specified in [metaTargets] is used as
+   * metadata annotation on a library, class, field or method, that library,
+   * class, field or  method is added to the set of targets for reflection.
+   *
+   * Example usage:
+   *
+   *     library example;
+   *     @MirrorsUsed(metaTargets: "example.Reflectable")
+   *     import "dart:mirrors";
+   *
+   *     class Reflectable {
+   *       const Reflectable();
+   *     }
+   *
+   *     class Foo {
+   *       @Reflectable()
+   *       reflectableMethod() { ... }
+   *
+   *       nonReflectableMethod() { ... }
+   *     }
+   *
+   * In the above example. `reflectableMethod` is marked as reflectable by
+   * using the `Reflectable` class, which in turn is specified in the
+   * [metaTargets] annotation.
+   *
+   * The method `nonReflectableMethod` lacks a metadata annotation and thus
+   * will not be reflectable at runtime.
+   */
+  final metaTargets;
+
+  /**
+   * A list of library names or "*".
+   *
+   * When used as metadata on an import of "dart:mirrors", this metadata does
+   * not apply to the library in which the annotation is used, but instead
+   * applies to the other libraries (all libraries if "*" is used).
+   *
+   * The following text is non-normative:
+   *
+   * Dart2js currently supports the following formats to specify libraries:
+   *
+   * * A constant [List] containing [String] constants representing names of
+   *   libraries.
+   * * A single [String] constant whose value is a comma-separated list of
+   *   library names.
+   *
+   * Conceptually, a [MirrorsUsed] annotation with [override] has the same
+   * effect as placing the annotation directly on the import of `dart:mirrors`
+   * in each of the referenced libraries. Thus, if the library had no
+   * [MirrorsUsed] annotation before, its unconditional import of
+   * `dart:mirrors` is overridden by an annotated import.
+   *
+   * Note that, like multiple explicit [MirrorsUsed] annotations, using
+   * override on a library with an existing [MirrorsUsed] annotation is
+   * additive. That is, the overall set of reflective targets is the union
+   * of the reflective targets that arise from the original and the
+   * overriding [MirrorsUsed] annotations.
+   *
+   * The use of [override] is only meaningful for libraries that have an
+   * import of `dart:mirrors` without annotation because otherwise it would
+   * work exactly the same way without the [override] parameter.
+   *
+   * While the annotation will apply to the given target libraries, the
+   * [symbols], [targets] and [metaTargets] are still evaluated in the
+   * scope of the annotation. Thus, to select a target from library `foo`,
+   * a qualified name has to be used or, if the target is visible in the
+   * current scope, its type may be referenced.
+   *
+   * For example, the following code marks all targets in the library `foo`
+   * as reflectable that have a metadata annotation using the `Reflectable`
+   * class from the same library.
+   *
+   *     @MirrorsUsed(metaTargets: "foo.Reflectable", override: "foo")
+   *
+   * However, the following code would require the use of the `Reflectable`
+   * class from the current library, instead.
+   *
+   *     @MirrorsUsed(metaTargets: "Reflectable", override: "foo")
+   *
+   */
+  final override;
+
+  /**
+   * See the documentation for [MirrorsUsed.symbols], [MirrorsUsed.targets],
+   * [MirrorsUsed.metaTargets] and [MirrorsUsed.override] for documentation
+   * of the parameters.
+   */
+  const MirrorsUsed(
+      {this.symbols, this.targets, this.metaTargets, this.override});
+}
diff --git a/sdk_nnbd/lib/mirrors/mirrors_sources.gni b/sdk_nnbd/lib/mirrors/mirrors_sources.gni
new file mode 100644
index 0000000..e019c34
--- /dev/null
+++ b/sdk_nnbd/lib/mirrors/mirrors_sources.gni
@@ -0,0 +1,8 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+mirrors_sdk_sources = [
+  "mirrors.dart",
+  # The above file needs to be first if additional parts are added to the lib.
+]
diff --git a/sdk_nnbd/lib/profiler/profiler.dart b/sdk_nnbd/lib/profiler/profiler.dart
new file mode 100644
index 0000000..1b96dfe
--- /dev/null
+++ b/sdk_nnbd/lib/profiler/profiler.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Please see 'dart:developer'.
+@Deprecated("Dart SDK 1.12")
+library dart.profiler;
+
+export 'dart:developer'
+    show getCurrentTag, Counter, Gauge, Metric, Metrics, UserTag;
diff --git a/sdk_nnbd/lib/profiler/profiler_sources.gni b/sdk_nnbd/lib/profiler/profiler_sources.gni
new file mode 100644
index 0000000..adbf447
--- /dev/null
+++ b/sdk_nnbd/lib/profiler/profiler_sources.gni
@@ -0,0 +1,8 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+profiler_sdk_sources = [
+  "profiler.dart",
+  # The above file needs to be first if additional parts are added to the lib.
+]
diff --git a/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart b/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart
new file mode 100644
index 0000000..7966fd7
--- /dev/null
+++ b/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart
@@ -0,0 +1,4011 @@
+/**
+ * Scalable Vector Graphics:
+ * Two-dimensional vector graphics with support for events and animation.
+ *
+ * For details about the features and syntax of SVG, a W3C standard,
+ * refer to the
+ * [Scalable Vector Graphics Specification](http://www.w3.org/TR/SVG/).
+ *
+ * {@category Web}
+ */
+library dart.dom.svg;
+
+import 'dart:async';
+import 'dart:collection' hide LinkedList, LinkedListEntry;
+import 'dart:_internal' show FixedLengthListMixin;
+import 'dart:html';
+import 'dart:html_common';
+import 'dart:_js_helper' show Creates, Returns, JSName, Native;
+import 'dart:_foreign_helper' show JS;
+import 'dart:_interceptors' show Interceptor;
+// DO NOT EDIT - unless you are editing documentation as per:
+// https://code.google.com/p/dart/wiki/ContributingHTMLDocumentation
+// Auto-generated dart:svg library.
+
+// Copyright (c) 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.
+
+class _SvgElementFactoryProvider {
+  static SvgElement createSvgElement_tag(String tag) {
+    final Element temp =
+        document.createElementNS("http://www.w3.org/2000/svg", tag);
+    return temp;
+  }
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGAElement")
+class AElement extends GraphicsElement implements UriReference {
+  // To suppress missing implicit constructor warnings.
+  factory AElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory AElement() => _SvgElementFactoryProvider.createSvgElement_tag("a");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AElement.created() : super.created();
+
+  final AnimatedString target;
+
+  // From SVGURIReference
+
+  final AnimatedString href;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGAngle")
+class Angle extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Angle._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int SVG_ANGLETYPE_DEG = 2;
+
+  static const int SVG_ANGLETYPE_GRAD = 4;
+
+  static const int SVG_ANGLETYPE_RAD = 3;
+
+  static const int SVG_ANGLETYPE_UNKNOWN = 0;
+
+  static const int SVG_ANGLETYPE_UNSPECIFIED = 1;
+
+  final int unitType;
+
+  num value;
+
+  String valueAsString;
+
+  num valueInSpecifiedUnits;
+
+  void convertToSpecifiedUnits(int unitType) native;
+
+  void newValueSpecifiedUnits(int unitType, num valueInSpecifiedUnits) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGAnimateElement")
+class AnimateElement extends AnimationElement {
+  // To suppress missing implicit constructor warnings.
+  factory AnimateElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory AnimateElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("animate");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AnimateElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('animate') &&
+      (new SvgElement.tag('animate') is AnimateElement);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGAnimateMotionElement")
+class AnimateMotionElement extends AnimationElement {
+  // To suppress missing implicit constructor warnings.
+  factory AnimateMotionElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory AnimateMotionElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("animateMotion");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AnimateMotionElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('animateMotion') &&
+      (new SvgElement.tag('animateMotion') is AnimateMotionElement);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGAnimateTransformElement")
+class AnimateTransformElement extends AnimationElement {
+  // To suppress missing implicit constructor warnings.
+  factory AnimateTransformElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory AnimateTransformElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("animateTransform");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AnimateTransformElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('animateTransform') &&
+      (new SvgElement.tag('animateTransform') is AnimateTransformElement);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGAnimatedAngle")
+class AnimatedAngle extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AnimatedAngle._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final Angle animVal;
+
+  final Angle baseVal;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGAnimatedBoolean")
+class AnimatedBoolean extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AnimatedBoolean._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool animVal;
+
+  bool baseVal;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGAnimatedEnumeration")
+class AnimatedEnumeration extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AnimatedEnumeration._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int animVal;
+
+  int baseVal;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGAnimatedInteger")
+class AnimatedInteger extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AnimatedInteger._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int animVal;
+
+  int baseVal;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGAnimatedLength")
+class AnimatedLength extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AnimatedLength._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final Length animVal;
+
+  final Length baseVal;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGAnimatedLengthList")
+class AnimatedLengthList extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AnimatedLengthList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final LengthList animVal;
+
+  final LengthList baseVal;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGAnimatedNumber")
+class AnimatedNumber extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AnimatedNumber._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num animVal;
+
+  num baseVal;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGAnimatedNumberList")
+class AnimatedNumberList extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AnimatedNumberList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final NumberList animVal;
+
+  final NumberList baseVal;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGAnimatedPreserveAspectRatio")
+class AnimatedPreserveAspectRatio extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AnimatedPreserveAspectRatio._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final PreserveAspectRatio animVal;
+
+  final PreserveAspectRatio baseVal;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGAnimatedRect")
+class AnimatedRect extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AnimatedRect._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final Rect animVal;
+
+  final Rect baseVal;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGAnimatedString")
+class AnimatedString extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AnimatedString._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String animVal;
+
+  String baseVal;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGAnimatedTransformList")
+class AnimatedTransformList extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AnimatedTransformList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final TransformList animVal;
+
+  final TransformList baseVal;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGAnimationElement")
+class AnimationElement extends SvgElement implements Tests {
+  // To suppress missing implicit constructor warnings.
+  factory AnimationElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory AnimationElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("animation");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AnimationElement.created() : super.created();
+
+  final SvgElement targetElement;
+
+  void beginElement() native;
+
+  void beginElementAt(num offset) native;
+
+  void endElement() native;
+
+  void endElementAt(num offset) native;
+
+  double getCurrentTime() native;
+
+  double getSimpleDuration() native;
+
+  double getStartTime() native;
+
+  // From SVGTests
+
+  final StringList requiredExtensions;
+
+  final StringList systemLanguage;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGCircleElement")
+class CircleElement extends GeometryElement {
+  // To suppress missing implicit constructor warnings.
+  factory CircleElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory CircleElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("circle");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  CircleElement.created() : super.created();
+
+  final AnimatedLength cx;
+
+  final AnimatedLength cy;
+
+  final AnimatedLength r;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGClipPathElement")
+class ClipPathElement extends GraphicsElement {
+  // To suppress missing implicit constructor warnings.
+  factory ClipPathElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ClipPathElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("clipPath");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ClipPathElement.created() : super.created();
+
+  final AnimatedEnumeration clipPathUnits;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGDefsElement")
+class DefsElement extends GraphicsElement {
+  // To suppress missing implicit constructor warnings.
+  factory DefsElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DefsElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("defs");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DefsElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGDescElement")
+class DescElement extends SvgElement {
+  // To suppress missing implicit constructor warnings.
+  factory DescElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DescElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("desc");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DescElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Native("SVGDiscardElement")
+class DiscardElement extends SvgElement {
+  // To suppress missing implicit constructor warnings.
+  factory DiscardElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DiscardElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGEllipseElement")
+class EllipseElement extends GeometryElement {
+  // To suppress missing implicit constructor warnings.
+  factory EllipseElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory EllipseElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("ellipse");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  EllipseElement.created() : super.created();
+
+  final AnimatedLength cx;
+
+  final AnimatedLength cy;
+
+  final AnimatedLength rx;
+
+  final AnimatedLength ry;
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEBlendElement")
+class FEBlendElement extends SvgElement
+    implements FilterPrimitiveStandardAttributes {
+  // To suppress missing implicit constructor warnings.
+  factory FEBlendElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FEBlendElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feBlend");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEBlendElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feBlend') &&
+      (new SvgElement.tag('feBlend') is FEBlendElement);
+
+  static const int SVG_FEBLEND_MODE_DARKEN = 4;
+
+  static const int SVG_FEBLEND_MODE_LIGHTEN = 5;
+
+  static const int SVG_FEBLEND_MODE_MULTIPLY = 2;
+
+  static const int SVG_FEBLEND_MODE_NORMAL = 1;
+
+  static const int SVG_FEBLEND_MODE_SCREEN = 3;
+
+  static const int SVG_FEBLEND_MODE_UNKNOWN = 0;
+
+  final AnimatedString in1;
+
+  final AnimatedString in2;
+
+  final AnimatedEnumeration mode;
+
+  // From SVGFilterPrimitiveStandardAttributes
+
+  final AnimatedLength height;
+
+  final AnimatedString result;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEColorMatrixElement")
+class FEColorMatrixElement extends SvgElement
+    implements FilterPrimitiveStandardAttributes {
+  // To suppress missing implicit constructor warnings.
+  factory FEColorMatrixElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FEColorMatrixElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feColorMatrix");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEColorMatrixElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feColorMatrix') &&
+      (new SvgElement.tag('feColorMatrix') is FEColorMatrixElement);
+
+  static const int SVG_FECOLORMATRIX_TYPE_HUEROTATE = 3;
+
+  static const int SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA = 4;
+
+  static const int SVG_FECOLORMATRIX_TYPE_MATRIX = 1;
+
+  static const int SVG_FECOLORMATRIX_TYPE_SATURATE = 2;
+
+  static const int SVG_FECOLORMATRIX_TYPE_UNKNOWN = 0;
+
+  final AnimatedString in1;
+
+  final AnimatedEnumeration type;
+
+  final AnimatedNumberList values;
+
+  // From SVGFilterPrimitiveStandardAttributes
+
+  final AnimatedLength height;
+
+  final AnimatedString result;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEComponentTransferElement")
+class FEComponentTransferElement extends SvgElement
+    implements FilterPrimitiveStandardAttributes {
+  // To suppress missing implicit constructor warnings.
+  factory FEComponentTransferElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FEComponentTransferElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feComponentTransfer");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEComponentTransferElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feComponentTransfer') &&
+      (new SvgElement.tag('feComponentTransfer') is FEComponentTransferElement);
+
+  final AnimatedString in1;
+
+  // From SVGFilterPrimitiveStandardAttributes
+
+  final AnimatedLength height;
+
+  final AnimatedString result;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGFECompositeElement")
+class FECompositeElement extends SvgElement
+    implements FilterPrimitiveStandardAttributes {
+  // To suppress missing implicit constructor warnings.
+  factory FECompositeElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FECompositeElement.created() : super.created();
+
+  static const int SVG_FECOMPOSITE_OPERATOR_ARITHMETIC = 6;
+
+  static const int SVG_FECOMPOSITE_OPERATOR_ATOP = 4;
+
+  static const int SVG_FECOMPOSITE_OPERATOR_IN = 2;
+
+  static const int SVG_FECOMPOSITE_OPERATOR_OUT = 3;
+
+  static const int SVG_FECOMPOSITE_OPERATOR_OVER = 1;
+
+  static const int SVG_FECOMPOSITE_OPERATOR_UNKNOWN = 0;
+
+  static const int SVG_FECOMPOSITE_OPERATOR_XOR = 5;
+
+  final AnimatedString in1;
+
+  final AnimatedString in2;
+
+  final AnimatedNumber k1;
+
+  final AnimatedNumber k2;
+
+  final AnimatedNumber k3;
+
+  final AnimatedNumber k4;
+
+  final AnimatedEnumeration operator;
+
+  // From SVGFilterPrimitiveStandardAttributes
+
+  final AnimatedLength height;
+
+  final AnimatedString result;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEConvolveMatrixElement")
+class FEConvolveMatrixElement extends SvgElement
+    implements FilterPrimitiveStandardAttributes {
+  // To suppress missing implicit constructor warnings.
+  factory FEConvolveMatrixElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FEConvolveMatrixElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feConvolveMatrix");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEConvolveMatrixElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feConvolveMatrix') &&
+      (new SvgElement.tag('feConvolveMatrix') is FEConvolveMatrixElement);
+
+  static const int SVG_EDGEMODE_DUPLICATE = 1;
+
+  static const int SVG_EDGEMODE_NONE = 3;
+
+  static const int SVG_EDGEMODE_UNKNOWN = 0;
+
+  static const int SVG_EDGEMODE_WRAP = 2;
+
+  final AnimatedNumber bias;
+
+  final AnimatedNumber divisor;
+
+  final AnimatedEnumeration edgeMode;
+
+  final AnimatedString in1;
+
+  final AnimatedNumberList kernelMatrix;
+
+  final AnimatedNumber kernelUnitLengthX;
+
+  final AnimatedNumber kernelUnitLengthY;
+
+  final AnimatedInteger orderX;
+
+  final AnimatedInteger orderY;
+
+  final AnimatedBoolean preserveAlpha;
+
+  final AnimatedInteger targetX;
+
+  final AnimatedInteger targetY;
+
+  // From SVGFilterPrimitiveStandardAttributes
+
+  final AnimatedLength height;
+
+  final AnimatedString result;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEDiffuseLightingElement")
+class FEDiffuseLightingElement extends SvgElement
+    implements FilterPrimitiveStandardAttributes {
+  // To suppress missing implicit constructor warnings.
+  factory FEDiffuseLightingElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FEDiffuseLightingElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feDiffuseLighting");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEDiffuseLightingElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feDiffuseLighting') &&
+      (new SvgElement.tag('feDiffuseLighting') is FEDiffuseLightingElement);
+
+  final AnimatedNumber diffuseConstant;
+
+  final AnimatedString in1;
+
+  final AnimatedNumber kernelUnitLengthX;
+
+  final AnimatedNumber kernelUnitLengthY;
+
+  final AnimatedNumber surfaceScale;
+
+  // From SVGFilterPrimitiveStandardAttributes
+
+  final AnimatedLength height;
+
+  final AnimatedString result;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEDisplacementMapElement")
+class FEDisplacementMapElement extends SvgElement
+    implements FilterPrimitiveStandardAttributes {
+  // To suppress missing implicit constructor warnings.
+  factory FEDisplacementMapElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FEDisplacementMapElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feDisplacementMap");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEDisplacementMapElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feDisplacementMap') &&
+      (new SvgElement.tag('feDisplacementMap') is FEDisplacementMapElement);
+
+  static const int SVG_CHANNEL_A = 4;
+
+  static const int SVG_CHANNEL_B = 3;
+
+  static const int SVG_CHANNEL_G = 2;
+
+  static const int SVG_CHANNEL_R = 1;
+
+  static const int SVG_CHANNEL_UNKNOWN = 0;
+
+  final AnimatedString in1;
+
+  final AnimatedString in2;
+
+  final AnimatedNumber scale;
+
+  final AnimatedEnumeration xChannelSelector;
+
+  final AnimatedEnumeration yChannelSelector;
+
+  // From SVGFilterPrimitiveStandardAttributes
+
+  final AnimatedLength height;
+
+  final AnimatedString result;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEDistantLightElement")
+class FEDistantLightElement extends SvgElement {
+  // To suppress missing implicit constructor warnings.
+  factory FEDistantLightElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FEDistantLightElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feDistantLight");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEDistantLightElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feDistantLight') &&
+      (new SvgElement.tag('feDistantLight') is FEDistantLightElement);
+
+  final AnimatedNumber azimuth;
+
+  final AnimatedNumber elevation;
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEFloodElement")
+class FEFloodElement extends SvgElement
+    implements FilterPrimitiveStandardAttributes {
+  // To suppress missing implicit constructor warnings.
+  factory FEFloodElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FEFloodElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feFlood");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEFloodElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feFlood') &&
+      (new SvgElement.tag('feFlood') is FEFloodElement);
+
+  // From SVGFilterPrimitiveStandardAttributes
+
+  final AnimatedLength height;
+
+  final AnimatedString result;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEFuncAElement")
+class FEFuncAElement extends _SVGComponentTransferFunctionElement {
+  // To suppress missing implicit constructor warnings.
+  factory FEFuncAElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FEFuncAElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feFuncA");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEFuncAElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feFuncA') &&
+      (new SvgElement.tag('feFuncA') is FEFuncAElement);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEFuncBElement")
+class FEFuncBElement extends _SVGComponentTransferFunctionElement {
+  // To suppress missing implicit constructor warnings.
+  factory FEFuncBElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FEFuncBElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feFuncB");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEFuncBElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feFuncB') &&
+      (new SvgElement.tag('feFuncB') is FEFuncBElement);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEFuncGElement")
+class FEFuncGElement extends _SVGComponentTransferFunctionElement {
+  // To suppress missing implicit constructor warnings.
+  factory FEFuncGElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FEFuncGElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feFuncG");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEFuncGElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feFuncG') &&
+      (new SvgElement.tag('feFuncG') is FEFuncGElement);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEFuncRElement")
+class FEFuncRElement extends _SVGComponentTransferFunctionElement {
+  // To suppress missing implicit constructor warnings.
+  factory FEFuncRElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FEFuncRElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feFuncR");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEFuncRElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feFuncR') &&
+      (new SvgElement.tag('feFuncR') is FEFuncRElement);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEGaussianBlurElement")
+class FEGaussianBlurElement extends SvgElement
+    implements FilterPrimitiveStandardAttributes {
+  // To suppress missing implicit constructor warnings.
+  factory FEGaussianBlurElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FEGaussianBlurElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feGaussianBlur");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEGaussianBlurElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feGaussianBlur') &&
+      (new SvgElement.tag('feGaussianBlur') is FEGaussianBlurElement);
+
+  final AnimatedString in1;
+
+  final AnimatedNumber stdDeviationX;
+
+  final AnimatedNumber stdDeviationY;
+
+  void setStdDeviation(num stdDeviationX, num stdDeviationY) native;
+
+  // From SVGFilterPrimitiveStandardAttributes
+
+  final AnimatedLength height;
+
+  final AnimatedString result;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEImageElement")
+class FEImageElement extends SvgElement
+    implements FilterPrimitiveStandardAttributes, UriReference {
+  // To suppress missing implicit constructor warnings.
+  factory FEImageElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FEImageElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feImage");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEImageElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feImage') &&
+      (new SvgElement.tag('feImage') is FEImageElement);
+
+  final AnimatedPreserveAspectRatio preserveAspectRatio;
+
+  // From SVGFilterPrimitiveStandardAttributes
+
+  final AnimatedLength height;
+
+  final AnimatedString result;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+
+  // From SVGURIReference
+
+  final AnimatedString href;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEMergeElement")
+class FEMergeElement extends SvgElement
+    implements FilterPrimitiveStandardAttributes {
+  // To suppress missing implicit constructor warnings.
+  factory FEMergeElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FEMergeElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feMerge");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEMergeElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feMerge') &&
+      (new SvgElement.tag('feMerge') is FEMergeElement);
+
+  // From SVGFilterPrimitiveStandardAttributes
+
+  final AnimatedLength height;
+
+  final AnimatedString result;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEMergeNodeElement")
+class FEMergeNodeElement extends SvgElement {
+  // To suppress missing implicit constructor warnings.
+  factory FEMergeNodeElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FEMergeNodeElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feMergeNode");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEMergeNodeElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feMergeNode') &&
+      (new SvgElement.tag('feMergeNode') is FEMergeNodeElement);
+
+  final AnimatedString in1;
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEMorphologyElement")
+class FEMorphologyElement extends SvgElement
+    implements FilterPrimitiveStandardAttributes {
+  // To suppress missing implicit constructor warnings.
+  factory FEMorphologyElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEMorphologyElement.created() : super.created();
+
+  static const int SVG_MORPHOLOGY_OPERATOR_DILATE = 2;
+
+  static const int SVG_MORPHOLOGY_OPERATOR_ERODE = 1;
+
+  static const int SVG_MORPHOLOGY_OPERATOR_UNKNOWN = 0;
+
+  final AnimatedString in1;
+
+  final AnimatedEnumeration operator;
+
+  final AnimatedNumber radiusX;
+
+  final AnimatedNumber radiusY;
+
+  // From SVGFilterPrimitiveStandardAttributes
+
+  final AnimatedLength height;
+
+  final AnimatedString result;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEOffsetElement")
+class FEOffsetElement extends SvgElement
+    implements FilterPrimitiveStandardAttributes {
+  // To suppress missing implicit constructor warnings.
+  factory FEOffsetElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FEOffsetElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feOffset");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEOffsetElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feOffset') &&
+      (new SvgElement.tag('feOffset') is FEOffsetElement);
+
+  final AnimatedNumber dx;
+
+  final AnimatedNumber dy;
+
+  final AnimatedString in1;
+
+  // From SVGFilterPrimitiveStandardAttributes
+
+  final AnimatedLength height;
+
+  final AnimatedString result;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFEPointLightElement")
+class FEPointLightElement extends SvgElement {
+  // To suppress missing implicit constructor warnings.
+  factory FEPointLightElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FEPointLightElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("fePointLight");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEPointLightElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('fePointLight') &&
+      (new SvgElement.tag('fePointLight') is FEPointLightElement);
+
+  final AnimatedNumber x;
+
+  final AnimatedNumber y;
+
+  final AnimatedNumber z;
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFESpecularLightingElement")
+class FESpecularLightingElement extends SvgElement
+    implements FilterPrimitiveStandardAttributes {
+  // To suppress missing implicit constructor warnings.
+  factory FESpecularLightingElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FESpecularLightingElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feSpecularLighting");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FESpecularLightingElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feSpecularLighting') &&
+      (new SvgElement.tag('feSpecularLighting') is FESpecularLightingElement);
+
+  final AnimatedString in1;
+
+  final AnimatedNumber kernelUnitLengthX;
+
+  final AnimatedNumber kernelUnitLengthY;
+
+  final AnimatedNumber specularConstant;
+
+  final AnimatedNumber specularExponent;
+
+  final AnimatedNumber surfaceScale;
+
+  // From SVGFilterPrimitiveStandardAttributes
+
+  final AnimatedLength height;
+
+  final AnimatedString result;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFESpotLightElement")
+class FESpotLightElement extends SvgElement {
+  // To suppress missing implicit constructor warnings.
+  factory FESpotLightElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FESpotLightElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feSpotLight");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FESpotLightElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feSpotLight') &&
+      (new SvgElement.tag('feSpotLight') is FESpotLightElement);
+
+  final AnimatedNumber limitingConeAngle;
+
+  final AnimatedNumber pointsAtX;
+
+  final AnimatedNumber pointsAtY;
+
+  final AnimatedNumber pointsAtZ;
+
+  final AnimatedNumber specularExponent;
+
+  final AnimatedNumber x;
+
+  final AnimatedNumber y;
+
+  final AnimatedNumber z;
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFETileElement")
+class FETileElement extends SvgElement
+    implements FilterPrimitiveStandardAttributes {
+  // To suppress missing implicit constructor warnings.
+  factory FETileElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FETileElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feTile");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FETileElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feTile') &&
+      (new SvgElement.tag('feTile') is FETileElement);
+
+  final AnimatedString in1;
+
+  // From SVGFilterPrimitiveStandardAttributes
+
+  final AnimatedLength height;
+
+  final AnimatedString result;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFETurbulenceElement")
+class FETurbulenceElement extends SvgElement
+    implements FilterPrimitiveStandardAttributes {
+  // To suppress missing implicit constructor warnings.
+  factory FETurbulenceElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FETurbulenceElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("feTurbulence");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FETurbulenceElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('feTurbulence') &&
+      (new SvgElement.tag('feTurbulence') is FETurbulenceElement);
+
+  static const int SVG_STITCHTYPE_NOSTITCH = 2;
+
+  static const int SVG_STITCHTYPE_STITCH = 1;
+
+  static const int SVG_STITCHTYPE_UNKNOWN = 0;
+
+  static const int SVG_TURBULENCE_TYPE_FRACTALNOISE = 1;
+
+  static const int SVG_TURBULENCE_TYPE_TURBULENCE = 2;
+
+  static const int SVG_TURBULENCE_TYPE_UNKNOWN = 0;
+
+  final AnimatedNumber baseFrequencyX;
+
+  final AnimatedNumber baseFrequencyY;
+
+  final AnimatedInteger numOctaves;
+
+  final AnimatedNumber seed;
+
+  final AnimatedEnumeration stitchTiles;
+
+  final AnimatedEnumeration type;
+
+  // From SVGFilterPrimitiveStandardAttributes
+
+  final AnimatedLength height;
+
+  final AnimatedString result;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGFilterElement")
+class FilterElement extends SvgElement implements UriReference {
+  // To suppress missing implicit constructor warnings.
+  factory FilterElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory FilterElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("filter");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FilterElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('filter') &&
+      (new SvgElement.tag('filter') is FilterElement);
+
+  final AnimatedEnumeration filterUnits;
+
+  final AnimatedLength height;
+
+  final AnimatedEnumeration primitiveUnits;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+
+  // From SVGURIReference
+
+  final AnimatedString href;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+abstract class FilterPrimitiveStandardAttributes extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory FilterPrimitiveStandardAttributes._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final AnimatedLength height;
+
+  final AnimatedString result;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+abstract class FitToViewBox extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory FitToViewBox._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final AnimatedPreserveAspectRatio preserveAspectRatio;
+
+  final AnimatedRect viewBox;
+}
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGForeignObjectElement")
+class ForeignObjectElement extends GraphicsElement {
+  // To suppress missing implicit constructor warnings.
+  factory ForeignObjectElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ForeignObjectElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("foreignObject");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ForeignObjectElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('foreignObject') &&
+      (new SvgElement.tag('foreignObject') is ForeignObjectElement);
+
+  final AnimatedLength height;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGGElement")
+class GElement extends GraphicsElement {
+  // To suppress missing implicit constructor warnings.
+  factory GElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory GElement() => _SvgElementFactoryProvider.createSvgElement_tag("g");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  GElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Native("SVGGeometryElement")
+class GeometryElement extends GraphicsElement {
+  // To suppress missing implicit constructor warnings.
+  factory GeometryElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  GeometryElement.created() : super.created();
+
+  final AnimatedNumber pathLength;
+
+  Point getPointAtLength(num distance) native;
+
+  double getTotalLength() native;
+
+  bool isPointInFill(Point point) native;
+
+  bool isPointInStroke(Point point) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("SVGGraphicsElement")
+class GraphicsElement extends SvgElement implements Tests {
+  // To suppress missing implicit constructor warnings.
+  factory GraphicsElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  GraphicsElement.created() : super.created();
+
+  final SvgElement farthestViewportElement;
+
+  final SvgElement nearestViewportElement;
+
+  final AnimatedTransformList transform;
+
+  Rect getBBox() native;
+
+  @JSName('getCTM')
+  Matrix getCtm() native;
+
+  @JSName('getScreenCTM')
+  Matrix getScreenCtm() native;
+
+  // From SVGTests
+
+  final StringList requiredExtensions;
+
+  final StringList systemLanguage;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGImageElement")
+class ImageElement extends GraphicsElement implements UriReference {
+  // To suppress missing implicit constructor warnings.
+  factory ImageElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ImageElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("image");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ImageElement.created() : super.created();
+
+  String async;
+
+  final AnimatedLength height;
+
+  final AnimatedPreserveAspectRatio preserveAspectRatio;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+
+  Future decode() => promiseToFuture(JS("", "#.decode()", this));
+
+  // From SVGURIReference
+
+  final AnimatedString href;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGLength")
+class Length extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Length._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int SVG_LENGTHTYPE_CM = 6;
+
+  static const int SVG_LENGTHTYPE_EMS = 3;
+
+  static const int SVG_LENGTHTYPE_EXS = 4;
+
+  static const int SVG_LENGTHTYPE_IN = 8;
+
+  static const int SVG_LENGTHTYPE_MM = 7;
+
+  static const int SVG_LENGTHTYPE_NUMBER = 1;
+
+  static const int SVG_LENGTHTYPE_PC = 10;
+
+  static const int SVG_LENGTHTYPE_PERCENTAGE = 2;
+
+  static const int SVG_LENGTHTYPE_PT = 9;
+
+  static const int SVG_LENGTHTYPE_PX = 5;
+
+  static const int SVG_LENGTHTYPE_UNKNOWN = 0;
+
+  final int unitType;
+
+  num value;
+
+  String valueAsString;
+
+  num valueInSpecifiedUnits;
+
+  void convertToSpecifiedUnits(int unitType) native;
+
+  void newValueSpecifiedUnits(int unitType, num valueInSpecifiedUnits) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGLengthList")
+class LengthList extends Interceptor
+    with ListMixin<Length>, ImmutableListMixin<Length>
+    implements List<Length> {
+  // To suppress missing implicit constructor warnings.
+  factory LengthList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  final int numberOfItems;
+
+  Length operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return this.getItem(index);
+  }
+
+  void operator []=(int index, Length value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<Length> mixins.
+  // Length is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  Length get first {
+    if (this.length > 0) {
+      return JS('Length', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  Length get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('Length', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  Length get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('Length', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  Length elementAt(int index) => this[index];
+  // -- end List<Length> mixins.
+
+  void __setter__(int index, Length newItem) native;
+
+  Length appendItem(Length newItem) native;
+
+  void clear() native;
+
+  Length getItem(int index) native;
+
+  Length initialize(Length newItem) native;
+
+  Length insertItemBefore(Length newItem, int index) native;
+
+  Length removeItem(int index) native;
+
+  Length replaceItem(Length newItem, int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGLineElement")
+class LineElement extends GeometryElement {
+  // To suppress missing implicit constructor warnings.
+  factory LineElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory LineElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("line");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  LineElement.created() : super.created();
+
+  final AnimatedLength x1;
+
+  final AnimatedLength x2;
+
+  final AnimatedLength y1;
+
+  final AnimatedLength y2;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGLinearGradientElement")
+class LinearGradientElement extends _GradientElement {
+  // To suppress missing implicit constructor warnings.
+  factory LinearGradientElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory LinearGradientElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("linearGradient");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  LinearGradientElement.created() : super.created();
+
+  final AnimatedLength x1;
+
+  final AnimatedLength x2;
+
+  final AnimatedLength y1;
+
+  final AnimatedLength y2;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGMarkerElement")
+class MarkerElement extends SvgElement implements FitToViewBox {
+  // To suppress missing implicit constructor warnings.
+  factory MarkerElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MarkerElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("marker");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MarkerElement.created() : super.created();
+
+  static const int SVG_MARKERUNITS_STROKEWIDTH = 2;
+
+  static const int SVG_MARKERUNITS_UNKNOWN = 0;
+
+  static const int SVG_MARKERUNITS_USERSPACEONUSE = 1;
+
+  static const int SVG_MARKER_ORIENT_ANGLE = 2;
+
+  static const int SVG_MARKER_ORIENT_AUTO = 1;
+
+  static const int SVG_MARKER_ORIENT_UNKNOWN = 0;
+
+  final AnimatedLength markerHeight;
+
+  final AnimatedEnumeration markerUnits;
+
+  final AnimatedLength markerWidth;
+
+  final AnimatedAngle orientAngle;
+
+  final AnimatedEnumeration orientType;
+
+  final AnimatedLength refX;
+
+  final AnimatedLength refY;
+
+  void setOrientToAngle(Angle angle) native;
+
+  void setOrientToAuto() native;
+
+  // From SVGFitToViewBox
+
+  final AnimatedPreserveAspectRatio preserveAspectRatio;
+
+  final AnimatedRect viewBox;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGMaskElement")
+class MaskElement extends SvgElement implements Tests {
+  // To suppress missing implicit constructor warnings.
+  factory MaskElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MaskElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("mask");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MaskElement.created() : super.created();
+
+  final AnimatedLength height;
+
+  final AnimatedEnumeration maskContentUnits;
+
+  final AnimatedEnumeration maskUnits;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+
+  // From SVGTests
+
+  final StringList requiredExtensions;
+
+  final StringList systemLanguage;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGMatrix")
+class Matrix extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Matrix._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  num a;
+
+  num b;
+
+  num c;
+
+  num d;
+
+  num e;
+
+  num f;
+
+  Matrix flipX() native;
+
+  Matrix flipY() native;
+
+  Matrix inverse() native;
+
+  Matrix multiply(Matrix secondMatrix) native;
+
+  Matrix rotate(num angle) native;
+
+  Matrix rotateFromVector(num x, num y) native;
+
+  Matrix scale(num scaleFactor) native;
+
+  Matrix scaleNonUniform(num scaleFactorX, num scaleFactorY) native;
+
+  Matrix skewX(num angle) native;
+
+  Matrix skewY(num angle) native;
+
+  Matrix translate(num x, num y) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGMetadataElement")
+class MetadataElement extends SvgElement {
+  // To suppress missing implicit constructor warnings.
+  factory MetadataElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MetadataElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGNumber")
+class Number extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Number._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  num value;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGNumberList")
+class NumberList extends Interceptor
+    with ListMixin<Number>, ImmutableListMixin<Number>
+    implements List<Number> {
+  // To suppress missing implicit constructor warnings.
+  factory NumberList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  final int numberOfItems;
+
+  Number operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return this.getItem(index);
+  }
+
+  void operator []=(int index, Number value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<Number> mixins.
+  // Number is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  Number get first {
+    if (this.length > 0) {
+      return JS('Number', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  Number get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('Number', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  Number get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('Number', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  Number elementAt(int index) => this[index];
+  // -- end List<Number> mixins.
+
+  void __setter__(int index, Number newItem) native;
+
+  Number appendItem(Number newItem) native;
+
+  void clear() native;
+
+  Number getItem(int index) native;
+
+  Number initialize(Number newItem) native;
+
+  Number insertItemBefore(Number newItem, int index) native;
+
+  Number removeItem(int index) native;
+
+  Number replaceItem(Number newItem, int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGPathElement")
+class PathElement extends GeometryElement {
+  // To suppress missing implicit constructor warnings.
+  factory PathElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PathElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("path");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  PathElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGPatternElement")
+class PatternElement extends SvgElement
+    implements FitToViewBox, UriReference, Tests {
+  // To suppress missing implicit constructor warnings.
+  factory PatternElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PatternElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("pattern");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  PatternElement.created() : super.created();
+
+  final AnimatedLength height;
+
+  final AnimatedEnumeration patternContentUnits;
+
+  final AnimatedTransformList patternTransform;
+
+  final AnimatedEnumeration patternUnits;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+
+  // From SVGFitToViewBox
+
+  final AnimatedPreserveAspectRatio preserveAspectRatio;
+
+  final AnimatedRect viewBox;
+
+  // From SVGTests
+
+  final StringList requiredExtensions;
+
+  final StringList systemLanguage;
+
+  // From SVGURIReference
+
+  final AnimatedString href;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGPoint")
+class Point extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Point._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  num x;
+
+  num y;
+
+  Point matrixTransform(Matrix matrix) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGPointList")
+class PointList extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PointList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int length;
+
+  final int numberOfItems;
+
+  void __setter__(int index, Point newItem) native;
+
+  Point appendItem(Point newItem) native;
+
+  void clear() native;
+
+  Point getItem(int index) native;
+
+  Point initialize(Point newItem) native;
+
+  Point insertItemBefore(Point newItem, int index) native;
+
+  Point removeItem(int index) native;
+
+  Point replaceItem(Point newItem, int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGPolygonElement")
+class PolygonElement extends GeometryElement {
+  // To suppress missing implicit constructor warnings.
+  factory PolygonElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PolygonElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("polygon");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  PolygonElement.created() : super.created();
+
+  final PointList animatedPoints;
+
+  final PointList points;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGPolylineElement")
+class PolylineElement extends GeometryElement {
+  // To suppress missing implicit constructor warnings.
+  factory PolylineElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PolylineElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("polyline");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  PolylineElement.created() : super.created();
+
+  final PointList animatedPoints;
+
+  final PointList points;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGPreserveAspectRatio")
+class PreserveAspectRatio extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PreserveAspectRatio._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int SVG_MEETORSLICE_MEET = 1;
+
+  static const int SVG_MEETORSLICE_SLICE = 2;
+
+  static const int SVG_MEETORSLICE_UNKNOWN = 0;
+
+  static const int SVG_PRESERVEASPECTRATIO_NONE = 1;
+
+  static const int SVG_PRESERVEASPECTRATIO_UNKNOWN = 0;
+
+  static const int SVG_PRESERVEASPECTRATIO_XMAXYMAX = 10;
+
+  static const int SVG_PRESERVEASPECTRATIO_XMAXYMID = 7;
+
+  static const int SVG_PRESERVEASPECTRATIO_XMAXYMIN = 4;
+
+  static const int SVG_PRESERVEASPECTRATIO_XMIDYMAX = 9;
+
+  static const int SVG_PRESERVEASPECTRATIO_XMIDYMID = 6;
+
+  static const int SVG_PRESERVEASPECTRATIO_XMIDYMIN = 3;
+
+  static const int SVG_PRESERVEASPECTRATIO_XMINYMAX = 8;
+
+  static const int SVG_PRESERVEASPECTRATIO_XMINYMID = 5;
+
+  static const int SVG_PRESERVEASPECTRATIO_XMINYMIN = 2;
+
+  int align;
+
+  int meetOrSlice;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGRadialGradientElement")
+class RadialGradientElement extends _GradientElement {
+  // To suppress missing implicit constructor warnings.
+  factory RadialGradientElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory RadialGradientElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("radialGradient");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  RadialGradientElement.created() : super.created();
+
+  final AnimatedLength cx;
+
+  final AnimatedLength cy;
+
+  final AnimatedLength fr;
+
+  final AnimatedLength fx;
+
+  final AnimatedLength fy;
+
+  final AnimatedLength r;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGRect")
+class Rect extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Rect._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  num height;
+
+  num width;
+
+  num x;
+
+  num y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGRectElement")
+class RectElement extends GeometryElement {
+  // To suppress missing implicit constructor warnings.
+  factory RectElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory RectElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("rect");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  RectElement.created() : super.created();
+
+  final AnimatedLength height;
+
+  final AnimatedLength rx;
+
+  final AnimatedLength ry;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGScriptElement")
+class ScriptElement extends SvgElement implements UriReference {
+  // To suppress missing implicit constructor warnings.
+  factory ScriptElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ScriptElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("script");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ScriptElement.created() : super.created();
+
+  String type;
+
+  // From SVGURIReference
+
+  final AnimatedString href;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Unstable()
+@Native("SVGSetElement")
+class SetElement extends AnimationElement {
+  // To suppress missing implicit constructor warnings.
+  factory SetElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory SetElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("set");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SetElement.created() : super.created();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      SvgElement.isTagSupported('set') &&
+      (new SvgElement.tag('set') is SetElement);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGStopElement")
+class StopElement extends SvgElement {
+  // To suppress missing implicit constructor warnings.
+  factory StopElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory StopElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("stop");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  StopElement.created() : super.created();
+
+  @JSName('offset')
+  final AnimatedNumber gradientOffset;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGStringList")
+class StringList extends Interceptor
+    with ListMixin<String>, ImmutableListMixin<String>
+    implements List<String> {
+  // To suppress missing implicit constructor warnings.
+  factory StringList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  final int numberOfItems;
+
+  String operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return this.getItem(index);
+  }
+
+  void operator []=(int index, String value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<String> mixins.
+  // String is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  String get first {
+    if (this.length > 0) {
+      return JS('String', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  String get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('String', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  String get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('String', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  String elementAt(int index) => this[index];
+  // -- end List<String> mixins.
+
+  void __setter__(int index, String newItem) native;
+
+  String appendItem(String newItem) native;
+
+  void clear() native;
+
+  String getItem(int index) native;
+
+  String initialize(String newItem) native;
+
+  String insertItemBefore(String item, int index) native;
+
+  String removeItem(int index) native;
+
+  String replaceItem(String newItem, int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("SVGStyleElement")
+class StyleElement extends SvgElement {
+  // To suppress missing implicit constructor warnings.
+  factory StyleElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory StyleElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("style");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  StyleElement.created() : super.created();
+
+  bool disabled;
+
+  String media;
+
+  final StyleSheet sheet;
+
+  // Use implementation from Element.
+  // final String title;
+
+  String type;
+}
+// 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.
+
+class AttributeClassSet extends CssClassSetImpl {
+  final Element _element;
+
+  AttributeClassSet(this._element);
+
+  Set<String> readClasses() {
+    var classname = _element.attributes['class'];
+    if (classname is AnimatedString) {
+      classname = (classname as AnimatedString).baseVal;
+    }
+
+    Set<String> s = new LinkedHashSet<String>();
+    if (classname == null) {
+      return s;
+    }
+    for (String name in classname.split(' ')) {
+      String trimmed = name.trim();
+      if (!trimmed.isEmpty) {
+        s.add(trimmed);
+      }
+    }
+    return s;
+  }
+
+  void writeClasses(Set s) {
+    _element.setAttribute('class', s.join(' '));
+  }
+}
+
+@Unstable()
+@Native("SVGElement")
+class SvgElement extends Element implements GlobalEventHandlers, NoncedElement {
+  static final _START_TAG_REGEXP = new RegExp('<(\\w+)');
+
+  factory SvgElement.tag(String tag) =>
+      document.createElementNS("http://www.w3.org/2000/svg", tag);
+  factory SvgElement.svg(String svg,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    if (validator == null && treeSanitizer == null) {
+      validator = new NodeValidatorBuilder.common()..allowSvg();
+    }
+
+    final match = _START_TAG_REGEXP.firstMatch(svg);
+    var parentElement;
+    if (match != null && match.group(1).toLowerCase() == 'svg') {
+      parentElement = document.body;
+    } else {
+      parentElement = new SvgSvgElement();
+    }
+    var fragment = parentElement.createFragment(svg,
+        validator: validator, treeSanitizer: treeSanitizer);
+    return fragment.nodes.where((e) => e is SvgElement).single;
+  }
+
+  CssClassSet get classes => new AttributeClassSet(this);
+
+  List<Element> get children => new FilteredElementList(this);
+
+  set children(List<Element> value) {
+    final children = this.children;
+    children.clear();
+    children.addAll(value);
+  }
+
+  String get outerHtml {
+    final container = new DivElement();
+    final SvgElement cloned = this.clone(true);
+    container.children.add(cloned);
+    return container.innerHtml;
+  }
+
+  String get innerHtml {
+    final container = new DivElement();
+    final SvgElement cloned = this.clone(true);
+    container.children.addAll(cloned.children);
+    return container.innerHtml;
+  }
+
+  set innerHtml(String value) {
+    this.setInnerHtml(value);
+  }
+
+  DocumentFragment createFragment(String svg,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    if (treeSanitizer == null) {
+      if (validator == null) {
+        validator = new NodeValidatorBuilder.common()..allowSvg();
+      }
+      treeSanitizer = new NodeTreeSanitizer(validator);
+    }
+
+    // We create a fragment which will parse in the HTML parser
+    var html = '<svg version="1.1">$svg</svg>';
+    var fragment =
+        document.body.createFragment(html, treeSanitizer: treeSanitizer);
+
+    var svgFragment = new DocumentFragment();
+    // The root is the <svg/> element, need to pull out the contents.
+    var root = fragment.nodes.single;
+    while (root.firstChild != null) {
+      svgFragment.append(root.firstChild);
+    }
+    return svgFragment;
+  }
+
+  // Unsupported methods inherited from Element.
+
+  void insertAdjacentText(String where, String text) {
+    throw new UnsupportedError("Cannot invoke insertAdjacentText on SVG.");
+  }
+
+  void insertAdjacentHtml(String where, String text,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    throw new UnsupportedError("Cannot invoke insertAdjacentHtml on SVG.");
+  }
+
+  Element insertAdjacentElement(String where, Element element) {
+    throw new UnsupportedError("Cannot invoke insertAdjacentElement on SVG.");
+  }
+
+  HtmlCollection get _children {
+    throw new UnsupportedError("Cannot get _children on SVG.");
+  }
+
+  bool get isContentEditable => false;
+  void click() {
+    throw new UnsupportedError("Cannot invoke click SVG.");
+  }
+
+  /**
+   * Checks to see if the SVG element type is supported by the current platform.
+   *
+   * The tag should be a valid SVG element tag name.
+   */
+  static bool isTagSupported(String tag) {
+    var e = new SvgElement.tag(tag);
+    return e is SvgElement && !(e is UnknownElement);
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory SvgElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> abortEvent =
+      const EventStreamProvider<Event>('abort');
+
+  static const EventStreamProvider<Event> blurEvent =
+      const EventStreamProvider<Event>('blur');
+
+  static const EventStreamProvider<Event> canPlayEvent =
+      const EventStreamProvider<Event>('canplay');
+
+  static const EventStreamProvider<Event> canPlayThroughEvent =
+      const EventStreamProvider<Event>('canplaythrough');
+
+  static const EventStreamProvider<Event> changeEvent =
+      const EventStreamProvider<Event>('change');
+
+  static const EventStreamProvider<MouseEvent> clickEvent =
+      const EventStreamProvider<MouseEvent>('click');
+
+  static const EventStreamProvider<MouseEvent> contextMenuEvent =
+      const EventStreamProvider<MouseEvent>('contextmenu');
+
+  @DomName('SVGElement.dblclickEvent')
+  static const EventStreamProvider<Event> doubleClickEvent =
+      const EventStreamProvider<Event>('dblclick');
+
+  static const EventStreamProvider<MouseEvent> dragEvent =
+      const EventStreamProvider<MouseEvent>('drag');
+
+  static const EventStreamProvider<MouseEvent> dragEndEvent =
+      const EventStreamProvider<MouseEvent>('dragend');
+
+  static const EventStreamProvider<MouseEvent> dragEnterEvent =
+      const EventStreamProvider<MouseEvent>('dragenter');
+
+  static const EventStreamProvider<MouseEvent> dragLeaveEvent =
+      const EventStreamProvider<MouseEvent>('dragleave');
+
+  static const EventStreamProvider<MouseEvent> dragOverEvent =
+      const EventStreamProvider<MouseEvent>('dragover');
+
+  static const EventStreamProvider<MouseEvent> dragStartEvent =
+      const EventStreamProvider<MouseEvent>('dragstart');
+
+  static const EventStreamProvider<MouseEvent> dropEvent =
+      const EventStreamProvider<MouseEvent>('drop');
+
+  static const EventStreamProvider<Event> durationChangeEvent =
+      const EventStreamProvider<Event>('durationchange');
+
+  static const EventStreamProvider<Event> emptiedEvent =
+      const EventStreamProvider<Event>('emptied');
+
+  static const EventStreamProvider<Event> endedEvent =
+      const EventStreamProvider<Event>('ended');
+
+  static const EventStreamProvider<Event> errorEvent =
+      const EventStreamProvider<Event>('error');
+
+  static const EventStreamProvider<Event> focusEvent =
+      const EventStreamProvider<Event>('focus');
+
+  static const EventStreamProvider<Event> inputEvent =
+      const EventStreamProvider<Event>('input');
+
+  static const EventStreamProvider<Event> invalidEvent =
+      const EventStreamProvider<Event>('invalid');
+
+  static const EventStreamProvider<KeyboardEvent> keyDownEvent =
+      const EventStreamProvider<KeyboardEvent>('keydown');
+
+  static const EventStreamProvider<KeyboardEvent> keyPressEvent =
+      const EventStreamProvider<KeyboardEvent>('keypress');
+
+  static const EventStreamProvider<KeyboardEvent> keyUpEvent =
+      const EventStreamProvider<KeyboardEvent>('keyup');
+
+  static const EventStreamProvider<Event> loadEvent =
+      const EventStreamProvider<Event>('load');
+
+  static const EventStreamProvider<Event> loadedDataEvent =
+      const EventStreamProvider<Event>('loadeddata');
+
+  static const EventStreamProvider<Event> loadedMetadataEvent =
+      const EventStreamProvider<Event>('loadedmetadata');
+
+  static const EventStreamProvider<MouseEvent> mouseDownEvent =
+      const EventStreamProvider<MouseEvent>('mousedown');
+
+  static const EventStreamProvider<MouseEvent> mouseEnterEvent =
+      const EventStreamProvider<MouseEvent>('mouseenter');
+
+  static const EventStreamProvider<MouseEvent> mouseLeaveEvent =
+      const EventStreamProvider<MouseEvent>('mouseleave');
+
+  static const EventStreamProvider<MouseEvent> mouseMoveEvent =
+      const EventStreamProvider<MouseEvent>('mousemove');
+
+  static const EventStreamProvider<MouseEvent> mouseOutEvent =
+      const EventStreamProvider<MouseEvent>('mouseout');
+
+  static const EventStreamProvider<MouseEvent> mouseOverEvent =
+      const EventStreamProvider<MouseEvent>('mouseover');
+
+  static const EventStreamProvider<MouseEvent> mouseUpEvent =
+      const EventStreamProvider<MouseEvent>('mouseup');
+
+  static const EventStreamProvider<WheelEvent> mouseWheelEvent =
+      const EventStreamProvider<WheelEvent>('mousewheel');
+
+  static const EventStreamProvider<Event> pauseEvent =
+      const EventStreamProvider<Event>('pause');
+
+  static const EventStreamProvider<Event> playEvent =
+      const EventStreamProvider<Event>('play');
+
+  static const EventStreamProvider<Event> playingEvent =
+      const EventStreamProvider<Event>('playing');
+
+  static const EventStreamProvider<Event> rateChangeEvent =
+      const EventStreamProvider<Event>('ratechange');
+
+  static const EventStreamProvider<Event> resetEvent =
+      const EventStreamProvider<Event>('reset');
+
+  static const EventStreamProvider<Event> resizeEvent =
+      const EventStreamProvider<Event>('resize');
+
+  static const EventStreamProvider<Event> scrollEvent =
+      const EventStreamProvider<Event>('scroll');
+
+  static const EventStreamProvider<Event> seekedEvent =
+      const EventStreamProvider<Event>('seeked');
+
+  static const EventStreamProvider<Event> seekingEvent =
+      const EventStreamProvider<Event>('seeking');
+
+  static const EventStreamProvider<Event> selectEvent =
+      const EventStreamProvider<Event>('select');
+
+  static const EventStreamProvider<Event> stalledEvent =
+      const EventStreamProvider<Event>('stalled');
+
+  static const EventStreamProvider<Event> submitEvent =
+      const EventStreamProvider<Event>('submit');
+
+  static const EventStreamProvider<Event> suspendEvent =
+      const EventStreamProvider<Event>('suspend');
+
+  static const EventStreamProvider<Event> timeUpdateEvent =
+      const EventStreamProvider<Event>('timeupdate');
+
+  static const EventStreamProvider<TouchEvent> touchCancelEvent =
+      const EventStreamProvider<TouchEvent>('touchcancel');
+
+  static const EventStreamProvider<TouchEvent> touchEndEvent =
+      const EventStreamProvider<TouchEvent>('touchend');
+
+  static const EventStreamProvider<TouchEvent> touchMoveEvent =
+      const EventStreamProvider<TouchEvent>('touchmove');
+
+  static const EventStreamProvider<TouchEvent> touchStartEvent =
+      const EventStreamProvider<TouchEvent>('touchstart');
+
+  static const EventStreamProvider<Event> volumeChangeEvent =
+      const EventStreamProvider<Event>('volumechange');
+
+  static const EventStreamProvider<Event> waitingEvent =
+      const EventStreamProvider<Event>('waiting');
+
+  static const EventStreamProvider<WheelEvent> wheelEvent =
+      const EventStreamProvider<WheelEvent>('wheel');
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SvgElement.created() : super.created();
+
+  // Shadowing definition.
+  AnimatedString get _svgClassName => JS("AnimatedString", "#.className", this);
+
+  @JSName('ownerSVGElement')
+  final SvgSvgElement ownerSvgElement;
+
+  // Use implementation from Element.
+  // final CssStyleDeclaration style;
+
+  // Use implementation from Element.
+  // final int tabIndex;
+
+  final SvgElement viewportElement;
+
+  void blur() native;
+
+  void focus() native;
+
+  // From NoncedElement
+
+  String nonce;
+
+  ElementStream<Event> get onAbort => abortEvent.forElement(this);
+
+  ElementStream<Event> get onBlur => blurEvent.forElement(this);
+
+  ElementStream<Event> get onCanPlay => canPlayEvent.forElement(this);
+
+  ElementStream<Event> get onCanPlayThrough =>
+      canPlayThroughEvent.forElement(this);
+
+  ElementStream<Event> get onChange => changeEvent.forElement(this);
+
+  ElementStream<MouseEvent> get onClick => clickEvent.forElement(this);
+
+  ElementStream<MouseEvent> get onContextMenu =>
+      contextMenuEvent.forElement(this);
+
+  @DomName('SVGElement.ondblclick')
+  ElementStream<Event> get onDoubleClick => doubleClickEvent.forElement(this);
+
+  ElementStream<MouseEvent> get onDrag => dragEvent.forElement(this);
+
+  ElementStream<MouseEvent> get onDragEnd => dragEndEvent.forElement(this);
+
+  ElementStream<MouseEvent> get onDragEnter => dragEnterEvent.forElement(this);
+
+  ElementStream<MouseEvent> get onDragLeave => dragLeaveEvent.forElement(this);
+
+  ElementStream<MouseEvent> get onDragOver => dragOverEvent.forElement(this);
+
+  ElementStream<MouseEvent> get onDragStart => dragStartEvent.forElement(this);
+
+  ElementStream<MouseEvent> get onDrop => dropEvent.forElement(this);
+
+  ElementStream<Event> get onDurationChange =>
+      durationChangeEvent.forElement(this);
+
+  ElementStream<Event> get onEmptied => emptiedEvent.forElement(this);
+
+  ElementStream<Event> get onEnded => endedEvent.forElement(this);
+
+  ElementStream<Event> get onError => errorEvent.forElement(this);
+
+  ElementStream<Event> get onFocus => focusEvent.forElement(this);
+
+  ElementStream<Event> get onInput => inputEvent.forElement(this);
+
+  ElementStream<Event> get onInvalid => invalidEvent.forElement(this);
+
+  ElementStream<KeyboardEvent> get onKeyDown => keyDownEvent.forElement(this);
+
+  ElementStream<KeyboardEvent> get onKeyPress => keyPressEvent.forElement(this);
+
+  ElementStream<KeyboardEvent> get onKeyUp => keyUpEvent.forElement(this);
+
+  ElementStream<Event> get onLoad => loadEvent.forElement(this);
+
+  ElementStream<Event> get onLoadedData => loadedDataEvent.forElement(this);
+
+  ElementStream<Event> get onLoadedMetadata =>
+      loadedMetadataEvent.forElement(this);
+
+  ElementStream<MouseEvent> get onMouseDown => mouseDownEvent.forElement(this);
+
+  ElementStream<MouseEvent> get onMouseEnter =>
+      mouseEnterEvent.forElement(this);
+
+  ElementStream<MouseEvent> get onMouseLeave =>
+      mouseLeaveEvent.forElement(this);
+
+  ElementStream<MouseEvent> get onMouseMove => mouseMoveEvent.forElement(this);
+
+  ElementStream<MouseEvent> get onMouseOut => mouseOutEvent.forElement(this);
+
+  ElementStream<MouseEvent> get onMouseOver => mouseOverEvent.forElement(this);
+
+  ElementStream<MouseEvent> get onMouseUp => mouseUpEvent.forElement(this);
+
+  ElementStream<WheelEvent> get onMouseWheel =>
+      mouseWheelEvent.forElement(this);
+
+  ElementStream<Event> get onPause => pauseEvent.forElement(this);
+
+  ElementStream<Event> get onPlay => playEvent.forElement(this);
+
+  ElementStream<Event> get onPlaying => playingEvent.forElement(this);
+
+  ElementStream<Event> get onRateChange => rateChangeEvent.forElement(this);
+
+  ElementStream<Event> get onReset => resetEvent.forElement(this);
+
+  ElementStream<Event> get onResize => resizeEvent.forElement(this);
+
+  ElementStream<Event> get onScroll => scrollEvent.forElement(this);
+
+  ElementStream<Event> get onSeeked => seekedEvent.forElement(this);
+
+  ElementStream<Event> get onSeeking => seekingEvent.forElement(this);
+
+  ElementStream<Event> get onSelect => selectEvent.forElement(this);
+
+  ElementStream<Event> get onStalled => stalledEvent.forElement(this);
+
+  ElementStream<Event> get onSubmit => submitEvent.forElement(this);
+
+  ElementStream<Event> get onSuspend => suspendEvent.forElement(this);
+
+  ElementStream<Event> get onTimeUpdate => timeUpdateEvent.forElement(this);
+
+  ElementStream<TouchEvent> get onTouchCancel =>
+      touchCancelEvent.forElement(this);
+
+  ElementStream<TouchEvent> get onTouchEnd => touchEndEvent.forElement(this);
+
+  ElementStream<TouchEvent> get onTouchMove => touchMoveEvent.forElement(this);
+
+  ElementStream<TouchEvent> get onTouchStart =>
+      touchStartEvent.forElement(this);
+
+  ElementStream<Event> get onVolumeChange => volumeChangeEvent.forElement(this);
+
+  ElementStream<Event> get onWaiting => waitingEvent.forElement(this);
+
+  ElementStream<WheelEvent> get onWheel => wheelEvent.forElement(this);
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGSVGElement")
+class SvgSvgElement extends GraphicsElement
+    implements FitToViewBox, ZoomAndPan {
+  factory SvgSvgElement() {
+    final el = new SvgElement.tag("svg");
+    // The SVG spec requires the version attribute to match the spec version
+    el.attributes['version'] = "1.1";
+    return el;
+  }
+
+  // To suppress missing implicit constructor warnings.
+  factory SvgSvgElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SvgSvgElement.created() : super.created();
+
+  num currentScale;
+
+  final Point currentTranslate;
+
+  final AnimatedLength height;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+
+  bool animationsPaused() native;
+
+  bool checkEnclosure(SvgElement element, Rect rect) native;
+
+  bool checkIntersection(SvgElement element, Rect rect) native;
+
+  @JSName('createSVGAngle')
+  Angle createSvgAngle() native;
+
+  @JSName('createSVGLength')
+  Length createSvgLength() native;
+
+  @JSName('createSVGMatrix')
+  Matrix createSvgMatrix() native;
+
+  @JSName('createSVGNumber')
+  Number createSvgNumber() native;
+
+  @JSName('createSVGPoint')
+  Point createSvgPoint() native;
+
+  @JSName('createSVGRect')
+  Rect createSvgRect() native;
+
+  @JSName('createSVGTransform')
+  Transform createSvgTransform() native;
+
+  @JSName('createSVGTransformFromMatrix')
+  Transform createSvgTransformFromMatrix(Matrix matrix) native;
+
+  void deselectAll() native;
+
+  void forceRedraw() native;
+
+  double getCurrentTime() native;
+
+  Element getElementById(String elementId) native;
+
+  @Returns('NodeList|Null')
+  @Creates('NodeList')
+  List<Node> getEnclosureList(Rect rect, SvgElement referenceElement) native;
+
+  @Returns('NodeList|Null')
+  @Creates('NodeList')
+  List<Node> getIntersectionList(Rect rect, SvgElement referenceElement) native;
+
+  void pauseAnimations() native;
+
+  void setCurrentTime(num seconds) native;
+
+  int suspendRedraw(int maxWaitMilliseconds) native;
+
+  void unpauseAnimations() native;
+
+  void unsuspendRedraw(int suspendHandleId) native;
+
+  void unsuspendRedrawAll() native;
+
+  // From SVGFitToViewBox
+
+  final AnimatedPreserveAspectRatio preserveAspectRatio;
+
+  final AnimatedRect viewBox;
+
+  // From SVGZoomAndPan
+
+  int zoomAndPan;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGSwitchElement")
+class SwitchElement extends GraphicsElement {
+  // To suppress missing implicit constructor warnings.
+  factory SwitchElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory SwitchElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("switch");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SwitchElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGSymbolElement")
+class SymbolElement extends SvgElement implements FitToViewBox {
+  // To suppress missing implicit constructor warnings.
+  factory SymbolElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory SymbolElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("symbol");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SymbolElement.created() : super.created();
+
+  // From SVGFitToViewBox
+
+  final AnimatedPreserveAspectRatio preserveAspectRatio;
+
+  final AnimatedRect viewBox;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGTSpanElement")
+class TSpanElement extends TextPositioningElement {
+  // To suppress missing implicit constructor warnings.
+  factory TSpanElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory TSpanElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("tspan");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TSpanElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Unstable()
+abstract class Tests extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Tests._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final StringList requiredExtensions;
+
+  final StringList systemLanguage;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGTextContentElement")
+class TextContentElement extends GraphicsElement {
+  // To suppress missing implicit constructor warnings.
+  factory TextContentElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TextContentElement.created() : super.created();
+
+  static const int LENGTHADJUST_SPACING = 1;
+
+  static const int LENGTHADJUST_SPACINGANDGLYPHS = 2;
+
+  static const int LENGTHADJUST_UNKNOWN = 0;
+
+  final AnimatedEnumeration lengthAdjust;
+
+  final AnimatedLength textLength;
+
+  int getCharNumAtPosition(Point point) native;
+
+  double getComputedTextLength() native;
+
+  Point getEndPositionOfChar(int charnum) native;
+
+  Rect getExtentOfChar(int charnum) native;
+
+  int getNumberOfChars() native;
+
+  double getRotationOfChar(int charnum) native;
+
+  Point getStartPositionOfChar(int charnum) native;
+
+  double getSubStringLength(int charnum, int nchars) native;
+
+  void selectSubString(int charnum, int nchars) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGTextElement")
+class TextElement extends TextPositioningElement {
+  // To suppress missing implicit constructor warnings.
+  factory TextElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory TextElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("text");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TextElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGTextPathElement")
+class TextPathElement extends TextContentElement implements UriReference {
+  // To suppress missing implicit constructor warnings.
+  factory TextPathElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TextPathElement.created() : super.created();
+
+  static const int TEXTPATH_METHODTYPE_ALIGN = 1;
+
+  static const int TEXTPATH_METHODTYPE_STRETCH = 2;
+
+  static const int TEXTPATH_METHODTYPE_UNKNOWN = 0;
+
+  static const int TEXTPATH_SPACINGTYPE_AUTO = 1;
+
+  static const int TEXTPATH_SPACINGTYPE_EXACT = 2;
+
+  static const int TEXTPATH_SPACINGTYPE_UNKNOWN = 0;
+
+  final AnimatedEnumeration method;
+
+  final AnimatedEnumeration spacing;
+
+  final AnimatedLength startOffset;
+
+  // From SVGURIReference
+
+  final AnimatedString href;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGTextPositioningElement")
+class TextPositioningElement extends TextContentElement {
+  // To suppress missing implicit constructor warnings.
+  factory TextPositioningElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TextPositioningElement.created() : super.created();
+
+  final AnimatedLengthList dx;
+
+  final AnimatedLengthList dy;
+
+  final AnimatedNumberList rotate;
+
+  final AnimatedLengthList x;
+
+  final AnimatedLengthList y;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGTitleElement")
+class TitleElement extends SvgElement {
+  // To suppress missing implicit constructor warnings.
+  factory TitleElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory TitleElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("title");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TitleElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGTransform")
+class Transform extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Transform._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int SVG_TRANSFORM_MATRIX = 1;
+
+  static const int SVG_TRANSFORM_ROTATE = 4;
+
+  static const int SVG_TRANSFORM_SCALE = 3;
+
+  static const int SVG_TRANSFORM_SKEWX = 5;
+
+  static const int SVG_TRANSFORM_SKEWY = 6;
+
+  static const int SVG_TRANSFORM_TRANSLATE = 2;
+
+  static const int SVG_TRANSFORM_UNKNOWN = 0;
+
+  final num angle;
+
+  final Matrix matrix;
+
+  final int type;
+
+  void setMatrix(Matrix matrix) native;
+
+  void setRotate(num angle, num cx, num cy) native;
+
+  void setScale(num sx, num sy) native;
+
+  void setSkewX(num angle) native;
+
+  void setSkewY(num angle) native;
+
+  void setTranslate(num tx, num ty) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGTransformList")
+class TransformList extends Interceptor
+    with ListMixin<Transform>, ImmutableListMixin<Transform>
+    implements List<Transform> {
+  // To suppress missing implicit constructor warnings.
+  factory TransformList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  final int numberOfItems;
+
+  Transform operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return this.getItem(index);
+  }
+
+  void operator []=(int index, Transform value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<Transform> mixins.
+  // Transform is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  Transform get first {
+    if (this.length > 0) {
+      return JS('Transform', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  Transform get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('Transform', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  Transform get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('Transform', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  Transform elementAt(int index) => this[index];
+  // -- end List<Transform> mixins.
+
+  void __setter__(int index, Transform newItem) native;
+
+  Transform appendItem(Transform newItem) native;
+
+  void clear() native;
+
+  Transform consolidate() native;
+
+  @JSName('createSVGTransformFromMatrix')
+  Transform createSvgTransformFromMatrix(Matrix matrix) native;
+
+  Transform getItem(int index) native;
+
+  Transform initialize(Transform newItem) native;
+
+  Transform insertItemBefore(Transform newItem, int index) native;
+
+  Transform removeItem(int index) native;
+
+  Transform replaceItem(Transform newItem, int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGUnitTypes")
+class UnitTypes extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory UnitTypes._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int SVG_UNIT_TYPE_OBJECTBOUNDINGBOX = 2;
+
+  static const int SVG_UNIT_TYPE_UNKNOWN = 0;
+
+  static const int SVG_UNIT_TYPE_USERSPACEONUSE = 1;
+}
+// Copyright (c) 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.
+
+@Unstable()
+abstract class UriReference extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory UriReference._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final AnimatedString href;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGUseElement")
+class UseElement extends GraphicsElement implements UriReference {
+  // To suppress missing implicit constructor warnings.
+  factory UseElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory UseElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("use");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  UseElement.created() : super.created();
+
+  final AnimatedLength height;
+
+  final AnimatedLength width;
+
+  final AnimatedLength x;
+
+  final AnimatedLength y;
+
+  // From SVGURIReference
+
+  final AnimatedString href;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGViewElement")
+class ViewElement extends SvgElement implements FitToViewBox, ZoomAndPan {
+  // To suppress missing implicit constructor warnings.
+  factory ViewElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ViewElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("view");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ViewElement.created() : super.created();
+
+  // From SVGFitToViewBox
+
+  final AnimatedPreserveAspectRatio preserveAspectRatio;
+
+  final AnimatedRect viewBox;
+
+  // From SVGZoomAndPan
+
+  int zoomAndPan;
+}
+// Copyright (c) 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.
+
+@Unstable()
+abstract class ZoomAndPan extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ZoomAndPan._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int SVG_ZOOMANDPAN_DISABLE = 1;
+
+  static const int SVG_ZOOMANDPAN_MAGNIFY = 2;
+
+  static const int SVG_ZOOMANDPAN_UNKNOWN = 0;
+
+  int zoomAndPan;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("SVGGradientElement")
+class _GradientElement extends SvgElement implements UriReference {
+  // To suppress missing implicit constructor warnings.
+  factory _GradientElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _GradientElement.created() : super.created();
+
+  static const int SVG_SPREADMETHOD_PAD = 1;
+
+  static const int SVG_SPREADMETHOD_REFLECT = 2;
+
+  static const int SVG_SPREADMETHOD_REPEAT = 3;
+
+  static const int SVG_SPREADMETHOD_UNKNOWN = 0;
+
+  final AnimatedTransformList gradientTransform;
+
+  final AnimatedEnumeration gradientUnits;
+
+  final AnimatedEnumeration spreadMethod;
+
+  // From SVGURIReference
+
+  final AnimatedString href;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("SVGComponentTransferFunctionElement")
+abstract class _SVGComponentTransferFunctionElement extends SvgElement {
+  // To suppress missing implicit constructor warnings.
+  factory _SVGComponentTransferFunctionElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGComponentTransferFunctionElement.created() : super.created();
+}
+// Copyright (c) 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.
+
+@Native("SVGFEDropShadowElement")
+abstract class _SVGFEDropShadowElement extends SvgElement
+    implements FilterPrimitiveStandardAttributes {
+  // To suppress missing implicit constructor warnings.
+  factory _SVGFEDropShadowElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGFEDropShadowElement.created() : super.created();
+
+  // From SVGFilterPrimitiveStandardAttributes
+
+}
+
+// Copyright (c) 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.
+
+@Native("SVGMPathElement")
+abstract class _SVGMPathElement extends SvgElement implements UriReference {
+  // To suppress missing implicit constructor warnings.
+  factory _SVGMPathElement._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory _SVGMPathElement() =>
+      _SvgElementFactoryProvider.createSvgElement_tag("mpath");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGMPathElement.created() : super.created();
+
+  // From SVGURIReference
+
+}
diff --git a/sdk_nnbd/lib/typed_data/typed_data.dart b/sdk_nnbd/lib/typed_data/typed_data.dart
new file mode 100644
index 0000000..89c9496
--- /dev/null
+++ b/sdk_nnbd/lib/typed_data/typed_data.dart
@@ -0,0 +1,2596 @@
+// 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.
+
+/// Lists that efficiently handle fixed sized data
+/// (for example, unsigned 8 byte integers) and SIMD numeric types.
+///
+/// To use this library in your code:
+///
+///     import 'dart:typed_data';
+///
+/// {@category Core}
+library dart.typed_data;
+
+import "dart:_internal" show UnmodifiableListBase;
+
+part "unmodifiable_typed_data.dart";
+
+/**
+ * A sequence of bytes underlying a typed data object.
+ *
+ * Used to process large quantities of binary or numerical data
+ * more efficiently using a typed view.
+ */
+abstract class ByteBuffer {
+  /**
+   * Returns the length of this byte buffer, in bytes.
+   */
+  int get lengthInBytes;
+
+  /**
+   * Creates a [Uint8List] _view_ of a region of this byte buffer.
+   *
+   * The view is backed by the bytes of this byte buffer.
+   * Any changes made to the `Uint8List` will also change the buffer,
+   * and vice versa.
+   *
+   * The viewed region start at [offsetInBytes] and contains [length] bytes.
+   * If [length] is omitted, the range extends to the end of the buffer.
+   *
+   * The start index and length must describe a valid range of the buffer:
+   *
+   * * `offsetInBytes` must not be negative,
+   * * `length` must not be negative, and
+   * * `offsetInBytes + length` must not be greater than [lengthInBytes].
+   */
+  Uint8List asUint8List([int offsetInBytes = 0, int length]);
+
+  /**
+   * Creates a [Int8List] _view_ of a region of this byte buffer.
+   *
+   * The view is backed by the bytes of this byte buffer.
+   * Any changes made to the `Int8List` will also change the buffer,
+   * and vice versa.
+   *
+   * The viewed region start at [offsetInBytes] and contains [length] bytes.
+   * If [length] is omitted, the range extends to the end of the buffer.
+   *
+   * The start index and length must describe a valid range of the buffer:
+   *
+   * * `offsetInBytes` must not be negative,
+   * * `length` must not be negative, and
+   * * `offsetInBytes + length` must not be greater than [lengthInBytes].
+   */
+  Int8List asInt8List([int offsetInBytes = 0, int length]);
+
+  /**
+   * Creates a [Uint8ClampedList] _view_ of a region of this byte buffer.
+   *
+   * The view is backed by the bytes of this byte buffer.
+   * Any changes made to the `Uint8ClampedList` will also change the buffer,
+   * and vice versa.
+   *
+   * The viewed region start at [offsetInBytes] and contains [length] bytes.
+   * If [length] is omitted, the range extends to the end of the buffer.
+   *
+   * The start index and length must describe a valid range of the buffer:
+   *
+   * * `offsetInBytes` must not be negative,
+   * * `length` must not be negative, and
+   * * `offsetInBytes + length` must not be greater than [lengthInBytes].
+   */
+  Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int length]);
+
+  /**
+   * Creates a [Uint16List] _view_ of a region of this byte buffer.
+   *
+   * The view is backed by the bytes of this byte buffer.
+   * Any changes made to the `Uint16List` will also change the buffer,
+   * and vice versa.
+   *
+   * The viewed region start at [offsetInBytes], which must be 16-bit aligned,
+   * and contains [length] 16-bit integers.
+   * If [length] is omitted, the range extends as far towards the end of
+   * the buffer as possible -
+   * if [lengthInBytes] is not even, the last byte can't be part of the view.
+   *
+   * The start index and length must describe a valid 16-bit aligned range
+   * of the buffer:
+   *
+   * * `offsetInBytes` must not be negative,
+   * * `offsetInBytes` must be divisible by two,
+   * * `length` must not be negative, and
+   * * `offsetInBytes + length * 2` must not be greater than [lengthInBytes].
+   */
+  Uint16List asUint16List([int offsetInBytes = 0, int length]);
+
+  /**
+   * Creates a [Int16List] _view_ of a region of this byte buffer.
+   *
+   * The view is backed by the bytes of this byte buffer.
+   * Any changes made to the `Int16List` will also change the buffer,
+   * and vice versa.
+   *
+   * The viewed region start at [offsetInBytes], which must be 16-bit aligned,
+   * and contains [length] 16-bit integers.
+   * If [length] is omitted, the range extends as far towards the end of
+   * the buffer as possible -
+   * if [lengthInBytes] is not even, the last byte can't be part of the view.
+   *
+   * The start index and length must describe a valid 16-bit aligned range
+   * of the buffer:
+   *
+   * * `offsetInBytes` must not be negative,
+   * * `offsetInBytes` must be divisible by two,
+   * * `length` must not be negative, and
+   * * `offsetInBytes + length * 2` must not be greater than [lengthInBytes].
+   */
+  Int16List asInt16List([int offsetInBytes = 0, int length]);
+
+  /**
+   * Creates a [Uint32List] _view_ of a region of this byte buffer.
+   *
+   * The view is backed by the bytes of this byte buffer.
+   * Any changes made to the `Uint32List` will also change the buffer,
+   * and vice versa.
+   *
+   * The viewed region start at [offsetInBytes], which must be 32-bit aligned,
+   * and contains [length] 32-bit integers.
+   * If [length] is omitted, the range extends as far towards the end of
+   * the buffer as possible -
+   * if [lengthInBytes] is not divisible by four, the last bytes can't be part
+   * of the view.
+   *
+   * The start index and length must describe a valid 32-bit aligned range
+   * of the buffer:
+   *
+   * * `offsetInBytes` must not be negative,
+   * * `offsetInBytes` must be divisible by four,
+   * * `length` must not be negative, and
+   * * `offsetInBytes + length * 4` must not be greater than [lengthInBytes].
+   */
+  Uint32List asUint32List([int offsetInBytes = 0, int length]);
+
+  /**
+   * Creates a [Int32List] _view_ of a region of this byte buffer.
+   *
+   * The view is backed by the bytes of this byte buffer.
+   * Any changes made to the `Int32List` will also change the buffer,
+   * and vice versa.
+   *
+   * The viewed region start at [offsetInBytes], which must be 32-bit aligned,
+   * and contains [length] 32-bit integers.
+   * If [length] is omitted, the range extends as far towards the end of
+   * the buffer as possible -
+   * if [lengthInBytes] is not divisible by four, the last bytes can't be part
+   * of the view.
+   *
+   * The start index and length must describe a valid 32-bit aligned range
+   * of the buffer:
+   *
+   * * `offsetInBytes` must not be negative,
+   * * `offsetInBytes` must be divisible by four,
+   * * `length` must not be negative, and
+   * * `offsetInBytes + length * 4` must not be greater than [lengthInBytes].
+   */
+  Int32List asInt32List([int offsetInBytes = 0, int length]);
+
+  /**
+   * Creates a [Uint64List] _view_ of a region of this byte buffer.
+   *
+   * The view is backed by the bytes of this byte buffer.
+   * Any changes made to the `Uint64List` will also change the buffer,
+   * and vice versa.
+   *
+   * The viewed region start at [offsetInBytes], which must be 64-bit aligned,
+   * and contains [length] 64-bit integers.
+   * If [length] is omitted, the range extends as far towards the end of
+   * the buffer as possible -
+   * if [lengthInBytes] is not divisible by eight, the last bytes can't be part
+   * of the view.
+   *
+   * The start index and length must describe a valid 64-bit aligned range
+   * of the buffer:
+   *
+   * * `offsetInBytes` must not be negative,
+   * * `offsetInBytes` must be divisible by eight,
+   * * `length` must not be negative, and
+   * * `offsetInBytes + length * 8` must not be greater than [lengthInBytes].
+   */
+  Uint64List asUint64List([int offsetInBytes = 0, int length]);
+
+  /**
+   * Creates a [Int64List] _view_ of a region of this byte buffer.
+   *
+   * The view is backed by the bytes of this byte buffer.
+   * Any changes made to the `Int64List` will also change the buffer,
+   * and vice versa.
+   *
+   * The viewed region start at [offsetInBytes], which must be 64-bit aligned,
+   * and contains [length] 64-bit integers.
+   * If [length] is omitted, the range extends as far towards the end of
+   * the buffer as possible -
+   * if [lengthInBytes] is not divisible by eight, the last bytes can't be part
+   * of the view.
+   *
+   * The start index and length must describe a valid 64-bit aligned range
+   * of the buffer:
+   *
+   * * `offsetInBytes` must not be negative,
+   * * `offsetInBytes` must be divisible by eight,
+   * * `length` must not be negative, and
+   * * `offsetInBytes + length * 8` must not be greater than [lengthInBytes].
+   */
+  Int64List asInt64List([int offsetInBytes = 0, int length]);
+
+  /**
+   * Creates a [Int32x4List] _view_ of a region of this byte buffer.
+   *
+   * The view is backed by the bytes of this byte buffer.
+   * Any changes made to the `Int32x4List` will also change the buffer,
+   * and vice versa.
+   *
+   * The viewed region start at [offsetInBytes], which must be 128-bit aligned,
+   * and contains [length] 128-bit integers.
+   * If [length] is omitted, the range extends as far towards the end of
+   * the buffer as possible -
+   * if [lengthInBytes] is not divisible by 16, the last bytes can't be part
+   * of the view.
+   *
+   * The start index and length must describe a valid 128-bit aligned range
+   * of the buffer:
+   *
+   * * `offsetInBytes` must not be negative,
+   * * `offsetInBytes` must be divisible by sixteen,
+   * * `length` must not be negative, and
+   * * `offsetInBytes + length * 16` must not be greater than [lengthInBytes].
+   */
+  Int32x4List asInt32x4List([int offsetInBytes = 0, int length]);
+
+  /**
+   * Creates a [Float32List] _view_ of a region of this byte buffer.
+   *
+   * The view is backed by the bytes of this byte buffer.
+   * Any changes made to the `Float32List` will also change the buffer,
+   * and vice versa.
+   *
+   * The viewed region start at [offsetInBytes], which must be 32-bit aligned,
+   * and contains [length] 32-bit integers.
+   * If [length] is omitted, the range extends as far towards the end of
+   * the buffer as possible -
+   * if [lengthInBytes] is not divisible by four, the last bytes can't be part
+   * of the view.
+   *
+   * The start index and length must describe a valid 32-bit aligned range
+   * of the buffer:
+   *
+   * * `offsetInBytes` must not be negative,
+   * * `offsetInBytes` must be divisible by four,
+   * * `length` must not be negative, and
+   * * `offsetInBytes + length * 4` must not be greater than [lengthInBytes].
+   */
+  Float32List asFloat32List([int offsetInBytes = 0, int length]);
+
+  /**
+   * Creates a [Float64List] _view_ of a region of this byte buffer.
+   *
+   * The view is backed by the bytes of this byte buffer.
+   * Any changes made to the `Float64List` will also change the buffer,
+   * and vice versa.
+   *
+   * The viewed region start at [offsetInBytes], which must be 64-bit aligned,
+   * and contains [length] 64-bit integers.
+   * If [length] is omitted, the range extends as far towards the end of
+   * the buffer as possible -
+   * if [lengthInBytes] is not divisible by eight, the last bytes can't be part
+   * of the view.
+   *
+   * The start index and length must describe a valid 64-bit aligned range
+   * of the buffer:
+   *
+   * * `offsetInBytes` must not be negative,
+   * * `offsetInBytes` must be divisible by eight,
+   * * `length` must not be negative, and
+   * * `offsetInBytes + length * 8` must not be greater than [lengthInBytes].
+   */
+  Float64List asFloat64List([int offsetInBytes = 0, int length]);
+
+  /**
+   * Creates a [Float32x4List] _view_ of a region of this byte buffer.
+   *
+   * The view is backed by the bytes of this byte buffer.
+   * Any changes made to the `Float32x4List` will also change the buffer,
+   * and vice versa.
+   *
+   * The viewed region start at [offsetInBytes], which must be 128-bit aligned,
+   * and contains [length] 128-bit integers.
+   * If [length] is omitted, the range extends as far towards the end of
+   * the buffer as possible -
+   * if [lengthInBytes] is not divisible by 16, the last bytes can't be part
+   * of the view.
+   *
+   * The start index and length must describe a valid 128-bit aligned range
+   * of the buffer:
+   *
+   * * `offsetInBytes` must not be negative,
+   * * `offsetInBytes` must be divisible by sixteen,
+   * * `length` must not be negative, and
+   * * `offsetInBytes + length * 16` must not be greater than [lengthInBytes].
+   */
+  Float32x4List asFloat32x4List([int offsetInBytes = 0, int length]);
+
+  /**
+   * Creates a [Float64x2List] _view_ of a region of this byte buffer.
+   *
+   * The view is backed by the bytes of this byte buffer.
+   * Any changes made to the `Float64x2List` will also change the buffer,
+   * and vice versa.
+   *
+   * The viewed region start at [offsetInBytes], which must be 128-bit aligned,
+   * and contains [length] 128-bit integers.
+   * If [length] is omitted, the range extends as far towards the end of
+   * the buffer as possible -
+   * if [lengthInBytes] is not divisible by 16, the last bytes can't be part
+   * of the view.
+   *
+   * The start index and length must describe a valid 128-bit aligned range
+   * of the buffer:
+   *
+   * * `offsetInBytes` must not be negative,
+   * * `offsetInBytes` must be divisible by sixteen,
+   * * `length` must not be negative, and
+   * * `offsetInBytes + length * 16` must not be greater than [lengthInBytes].
+   */
+  Float64x2List asFloat64x2List([int offsetInBytes = 0, int length]);
+
+  /**
+   * Creates a [ByteData] _view_ of a region of this byte buffer.
+   *
+   * The view is backed by the bytes of this byte buffer.
+   * Any changes made to the `ByteData` will also change the buffer,
+   * and vice versa.
+   *
+   * The viewed region start at [offsetInBytes] and contains [length] bytes.
+   * If [length] is omitted, the range extends to the end of the buffer.
+   *
+   * The start index and length must describe a valid range of the buffer:
+   *
+   * * `offsetInBytes` must not be negative,
+   * * `length` must not be negative, and
+   * * `offsetInBytes + length` must not be greater than [lengthInBytes].
+   */
+  ByteData asByteData([int offsetInBytes = 0, int length]);
+}
+
+/**
+ * A typed view of a sequence of bytes.
+ */
+abstract class TypedData {
+  /**
+   * Returns the number of bytes in the representation of each element in this
+   * list.
+   */
+  int get elementSizeInBytes;
+
+  /**
+   * Returns the offset in bytes into the underlying byte buffer of this view.
+   */
+  int get offsetInBytes;
+
+  /**
+   * Returns the length of this view, in bytes.
+   */
+  int get lengthInBytes;
+
+  /**
+   * Returns the byte buffer associated with this object.
+   */
+  ByteBuffer get buffer;
+}
+
+abstract class _TypedIntList extends TypedData {
+  /**
+   * Returns the concatenation of this list and [other].
+   *
+   * If other is also a typed-data integer list, the returned list will
+   * be a type-data integer list capable of containing all the elements of
+   * this list and of [other].
+   * Otherwise the returned list will be a normal growable `List<int>`.
+   */
+  List<int> operator +(List<int> other);
+}
+
+abstract class _TypedFloatList extends TypedData {
+  /**
+   * Returns the concatenation of this list and [other].
+   *
+   * If other is also a typed-data floating point number list,
+   * the returned list will be a type-data float list capable of containing
+   * all the elements of this list and of [other].
+   * Otherwise the returned list will be a normal growable `List<double>`.
+   */
+  List<double> operator +(List<double> other);
+}
+
+/**
+ * Describes endianness to be used when accessing or updating a
+ * sequence of bytes.
+ */
+class Endian {
+  final bool _littleEndian;
+  const Endian._(this._littleEndian);
+
+  static const Endian big = const Endian._(false);
+  static const Endian little = const Endian._(true);
+  static final Endian host =
+      (new ByteData.view(new Uint16List.fromList([1]).buffer)).getInt8(0) == 1
+          ? little
+          : big;
+}
+
+/**
+ * A fixed-length, random-access sequence of bytes that also provides random
+ * and unaligned access to the fixed-width integers and floating point
+ * numbers represented by those bytes.
+ *
+ * `ByteData` may be used to pack and unpack data from external sources
+ * (such as networks or files systems), and to process large quantities
+ * of numerical data more efficiently than would be possible
+ * with ordinary [List] implementations.
+ * `ByteData` can save space, by eliminating the need for object headers,
+ * and time, by eliminating the need for data copies.
+ * Finally, `ByteData` may be used to intentionally reinterpret the bytes
+ * representing one arithmetic type as another.
+ * For example this code fragment determine what 32-bit signed integer
+ * is represented by the bytes of a 32-bit floating point number:
+ *
+ *     var buffer = new Uint8List(8).buffer;
+ *     var bdata = new ByteData.view(buffer);
+ *     bdata.setFloat32(0, 3.04);
+ *     int huh = bdata.getInt32(0);
+ */
+abstract class ByteData implements TypedData {
+  /**
+   * Creates a [ByteData] of the specified length (in elements), all of
+   * whose bytes are initially zero.
+   */
+  @pragma("vm:entry-point")
+  external factory ByteData(int length);
+
+  /**
+   * Creates an [ByteData] _view_ of the specified region in [buffer].
+   *
+   * Changes in the [ByteData] will be visible in the byte
+   * buffer and vice versa.
+   * If the [offsetInBytes] index of the region is not specified,
+   * it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to `null`,
+   * which indicates that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   */
+  factory ByteData.view(ByteBuffer buffer,
+      [int offsetInBytes = 0, int length]) {
+    return buffer.asByteData(offsetInBytes, length);
+  }
+
+  /**
+   * Returns the (possibly negative) integer represented by the byte at the
+   * specified [byteOffset] in this object, in two's complement binary
+   * representation.
+   *
+   * The return value will be between -128 and 127, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * greater than or equal to the length of this object.
+   */
+  int getInt8(int byteOffset);
+
+  /**
+   * Sets the byte at the specified [byteOffset] in this object to the
+   * two's complement binary representation of the specified [value], which
+   * must fit in a single byte.
+   *
+   * In other words, [value] must be between -128 and 127, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * greater than or equal to the length of this object.
+   */
+  void setInt8(int byteOffset, int value);
+
+  /**
+   * Returns the positive integer represented by the byte at the specified
+   * [byteOffset] in this object, in unsigned binary form.
+   *
+   * The return value will be between 0 and 255, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * greater than or equal to the length of this object.
+   */
+  int getUint8(int byteOffset);
+
+  /**
+   * Sets the byte at the specified [byteOffset] in this object to the
+   * unsigned binary representation of the specified [value], which must fit
+   * in a single byte.
+   *
+   * In other words, [value] must be between 0 and 255, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative,
+   * or greater than or equal to the length of this object.
+   */
+  void setUint8(int byteOffset, int value);
+
+  /**
+   * Returns the (possibly negative) integer represented by the two bytes at
+   * the specified [byteOffset] in this object, in two's complement binary
+   * form.
+   *
+   * The return value will be between -2<sup>15</sup> and 2<sup>15</sup> - 1,
+   * inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 2` is greater than the length of this object.
+   */
+  int getInt16(int byteOffset, [Endian endian = Endian.big]);
+
+  /**
+   * Sets the two bytes starting at the specified [byteOffset] in this
+   * object to the two's complement binary representation of the specified
+   * [value], which must fit in two bytes.
+   *
+   * In other words, [value] must lie
+   * between -2<sup>15</sup> and 2<sup>15</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 2` is greater than the length of this object.
+   */
+  void setInt16(int byteOffset, int value, [Endian endian = Endian.big]);
+
+  /**
+   * Returns the positive integer represented by the two bytes starting
+   * at the specified [byteOffset] in this object, in unsigned binary
+   * form.
+   *
+   * The return value will be between 0 and  2<sup>16</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 2` is greater than the length of this object.
+   */
+  int getUint16(int byteOffset, [Endian endian = Endian.big]);
+
+  /**
+   * Sets the two bytes starting at the specified [byteOffset] in this object
+   * to the unsigned binary representation of the specified [value],
+   * which must fit in two bytes.
+   *
+   * In other words, [value] must be between
+   * 0 and 2<sup>16</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 2` is greater than the length of this object.
+   */
+  void setUint16(int byteOffset, int value, [Endian endian = Endian.big]);
+
+  /**
+   * Returns the (possibly negative) integer represented by the four bytes at
+   * the specified [byteOffset] in this object, in two's complement binary
+   * form.
+   *
+   * The return value will be between -2<sup>31</sup> and 2<sup>31</sup> - 1,
+   * inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
+   */
+  int getInt32(int byteOffset, [Endian endian = Endian.big]);
+
+  /**
+   * Sets the four bytes starting at the specified [byteOffset] in this
+   * object to the two's complement binary representation of the specified
+   * [value], which must fit in four bytes.
+   *
+   * In other words, [value] must lie
+   * between -2<sup>31</sup> and 2<sup>31</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
+   */
+  void setInt32(int byteOffset, int value, [Endian endian = Endian.big]);
+
+  /**
+   * Returns the positive integer represented by the four bytes starting
+   * at the specified [byteOffset] in this object, in unsigned binary
+   * form.
+   *
+   * The return value will be between 0 and  2<sup>32</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
+   */
+  int getUint32(int byteOffset, [Endian endian = Endian.big]);
+
+  /**
+   * Sets the four bytes starting at the specified [byteOffset] in this object
+   * to the unsigned binary representation of the specified [value],
+   * which must fit in four bytes.
+   *
+   * In other words, [value] must be between
+   * 0 and 2<sup>32</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
+   */
+  void setUint32(int byteOffset, int value, [Endian endian = Endian.big]);
+
+  /**
+   * Returns the (possibly negative) integer represented by the eight bytes at
+   * the specified [byteOffset] in this object, in two's complement binary
+   * form.
+   *
+   * The return value will be between -2<sup>63</sup> and 2<sup>63</sup> - 1,
+   * inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 8` is greater than the length of this object.
+   */
+  int getInt64(int byteOffset, [Endian endian = Endian.big]);
+
+  /**
+   * Sets the eight bytes starting at the specified [byteOffset] in this
+   * object to the two's complement binary representation of the specified
+   * [value], which must fit in eight bytes.
+   *
+   * In other words, [value] must lie
+   * between -2<sup>63</sup> and 2<sup>63</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 8` is greater than the length of this object.
+   */
+  void setInt64(int byteOffset, int value, [Endian endian = Endian.big]);
+
+  /**
+   * Returns the positive integer represented by the eight bytes starting
+   * at the specified [byteOffset] in this object, in unsigned binary
+   * form.
+   *
+   * The return value will be between 0 and  2<sup>64</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 8` is greater than the length of this object.
+   */
+  int getUint64(int byteOffset, [Endian endian = Endian.big]);
+
+  /**
+   * Sets the eight bytes starting at the specified [byteOffset] in this object
+   * to the unsigned binary representation of the specified [value],
+   * which must fit in eight bytes.
+   *
+   * In other words, [value] must be between
+   * 0 and 2<sup>64</sup> - 1, inclusive.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 8` is greater than the length of this object.
+   */
+  void setUint64(int byteOffset, int value, [Endian endian = Endian.big]);
+
+  /**
+   * Returns the floating point number represented by the four bytes at
+   * the specified [byteOffset] in this object, in IEEE 754
+   * single-precision binary floating-point format (binary32).
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
+   */
+  double getFloat32(int byteOffset, [Endian endian = Endian.big]);
+
+  /**
+   * Sets the four bytes starting at the specified [byteOffset] in this
+   * object to the IEEE 754 single-precision binary floating-point
+   * (binary32) representation of the specified [value].
+   *
+   * **Note that this method can lose precision.** The input [value] is
+   * a 64-bit floating point value, which will be converted to 32-bit
+   * floating point value by IEEE 754 rounding rules before it is stored.
+   * If [value] cannot be represented exactly as a binary32, it will be
+   * converted to the nearest binary32 value.  If two binary32 values are
+   * equally close, the one whose least significant bit is zero will be used.
+   * Note that finite (but large) values can be converted to infinity, and
+   * small non-zero values can be converted to zero.
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
+   */
+  void setFloat32(int byteOffset, double value, [Endian endian = Endian.big]);
+
+  /**
+   * Returns the floating point number represented by the eight bytes at
+   * the specified [byteOffset] in this object, in IEEE 754
+   * double-precision binary floating-point format (binary64).
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 8` is greater than the length of this object.
+   */
+  double getFloat64(int byteOffset, [Endian endian = Endian.big]);
+
+  /**
+   * Sets the eight bytes starting at the specified [byteOffset] in this
+   * object to the IEEE 754 double-precision binary floating-point
+   * (binary64) representation of the specified [value].
+   *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 8` is greater than the length of this object.
+   */
+  void setFloat64(int byteOffset, double value, [Endian endian = Endian.big]);
+}
+
+/**
+ * A fixed-length list of 8-bit signed integers.
+ *
+ * For long lists, this implementation can be considerably
+ * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low eight bits,
+ * interpreted as a signed 8-bit two's complement integer with values in the
+ * range -128 to +127.
+ */
+abstract class Int8List implements List<int>, _TypedIntList {
+  /**
+   * Creates an [Int8List] of the specified length (in elements), all of
+   * whose elements are initially zero.
+   */
+  external factory Int8List(int length);
+
+  /**
+   * Creates a [Int8List] with the same length as the [elements] list
+   * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
+   */
+  external factory Int8List.fromList(List<int> elements);
+
+  /**
+   * Creates an [Int8List] _view_ of the specified region in [buffer].
+   *
+   * Changes in the [Int8List] will be visible in the byte
+   * buffer and vice versa.
+   * If the [offsetInBytes] index of the region is not specified,
+   * it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to `null`,
+   * which indicates that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   */
+  factory Int8List.view(ByteBuffer buffer,
+      [int offsetInBytes = 0, int length]) {
+    return buffer.asInt8List(offsetInBytes, length);
+  }
+
+  /**
+   * Returns a new list containing the elements between [start] and [end].
+   *
+   * The new list is an `Int8List` containing the elements of this list at
+   * positions greater than or equal to [start] and less than [end] in the same
+   * order as they occur in this list.
+   *
+   * ```dart
+   * var numbers = Int8List.fromList([0, 1, 2, 3, 4]);
+   * print(numbers.sublist(1, 3)); // [1, 2]
+   * print(numbers.sublist(1, 3).runtimeType); // Int8List
+   * ```
+   *
+   * If [end] is omitted, it defaults to the [length] of this list.
+   *
+   * ```dart
+   * print(numbers.sublist(1)); // [1, 2, 3, 4]
+   * ```
+   *
+   * The `start` and `end` positions must satisfy the relations
+   * 0 ≤ `start` ≤ `end` ≤ `this.length`
+   * If `end` is equal to `start`, then the returned list is empty.
+   */
+  Int8List sublist(int start, [int end]);
+
+  static const int bytesPerElement = 1;
+}
+
+/**
+ * A fixed-length list of 8-bit unsigned integers.
+ *
+ * For long lists, this implementation can be considerably
+ * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low eight bits,
+ * interpreted as an unsigned 8-bit integer with values in the
+ * range 0 to 255.
+ */
+abstract class Uint8List implements List<int>, _TypedIntList {
+  /**
+   * Creates a [Uint8List] of the specified length (in elements), all of
+   * whose elements are initially zero.
+   */
+  external factory Uint8List(int length);
+
+  /**
+   * Creates a [Uint8List] with the same length as the [elements] list
+   * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
+   */
+  external factory Uint8List.fromList(List<int> elements);
+
+  /**
+   * Creates a [Uint8List] _view_ of the specified region in [buffer].
+   *
+   * Changes in the [Uint8List] will be visible in the byte
+   * buffer and vice versa.
+   * If the [offsetInBytes] index of the region is not specified,
+   * it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to `null`,
+   * which indicates that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   */
+  factory Uint8List.view(ByteBuffer buffer,
+      [int offsetInBytes = 0, int length]) {
+    return buffer.asUint8List(offsetInBytes, length);
+  }
+
+  /**
+   * Returns a concatenation of this list and [other].
+   *
+   * If [other] is also a typed-data list, then the return list will be a
+   * typed data list capable of holding both unsigned 8-bit integers and
+   * the elements of [other], otherwise it'll be a normal list of integers.
+   */
+  List<int> operator +(List<int> other);
+
+  /**
+   * Returns a new list containing the elements between [start] and [end].
+   *
+   * The new list is a `Uint8List` containing the elements of this list at
+   * positions greater than or equal to [start] and less than [end] in the same
+   * order as they occur in this list.
+   *
+   * ```dart
+   * var numbers = Uint8List.fromList([0, 1, 2, 3, 4]);
+   * print(numbers.sublist(1, 3)); // [1, 2]
+   * print(numbers.sublist(1, 3).runtimeType); // Uint8List
+   * ```
+   *
+   * If [end] is omitted, it defaults to the [length] of this list.
+   *
+   * ```dart
+   * print(numbers.sublist(1)); // [1, 2, 3, 4]
+   * ```
+   *
+   * The `start` and `end` positions must satisfy the relations
+   * 0 ≤ `start` ≤ `end` ≤ `this.length`
+   * If `end` is equal to `start`, then the returned list is empty.
+   */
+  Uint8List sublist(int start, [int end]);
+
+  static const int bytesPerElement = 1;
+}
+
+/**
+ * A fixed-length list of 8-bit unsigned integers.
+ *
+ * For long lists, this implementation can be considerably
+ * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are clamped to an unsigned eight bit value.
+ * That is, all values below zero are stored as zero
+ * and all values above 255 are stored as 255.
+ */
+abstract class Uint8ClampedList implements List<int>, _TypedIntList {
+  /**
+   * Creates a [Uint8ClampedList] of the specified length (in elements), all of
+   * whose elements are initially zero.
+   */
+  external factory Uint8ClampedList(int length);
+
+  /**
+   * Creates a [Uint8ClampedList] of the same size as the [elements]
+   * list and copies over the values clamping when needed.
+   *
+   * Values are clamped to fit in the list when they are copied,
+   * the same way storing values clamps them.
+   */
+  external factory Uint8ClampedList.fromList(List<int> elements);
+
+  /**
+   * Creates a [Uint8ClampedList] _view_ of the specified region in the
+   * specified byte [buffer].
+   *
+   * Changes in the [Uint8List] will be visible in the byte buffer
+   * and vice versa.
+   * If the [offsetInBytes] index of the region is not specified,
+   * it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to `null`,
+   * which indicates that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   */
+  factory Uint8ClampedList.view(ByteBuffer buffer,
+      [int offsetInBytes = 0, int length]) {
+    return buffer.asUint8ClampedList(offsetInBytes, length);
+  }
+
+  /**
+   * Returns a new list containing the elements between [start] and [end].
+   *
+   * The new list is a `Uint8ClampedList` containing the elements of this
+   * list at positions greater than or equal to [start] and less than [end] in
+   * the same order as they occur in this list.
+   *
+   * ```dart
+   * var numbers = Uint8ClampedList.fromList([0, 1, 2, 3, 4]);
+   * print(numbers.sublist(1, 3)); // [1, 2]
+   * print(numbers.sublist(1, 3).runtimeType); // Uint8ClampedList
+   * ```
+   *
+   * If [end] is omitted, it defaults to the [length] of this list.
+   *
+   * ```dart
+   * print(numbers.sublist(1)); // [1, 2, 3, 4]
+   * ```
+   *
+   * The `start` and `end` positions must satisfy the relations
+   * 0 ≤ `start` ≤ `end` ≤ `this.length`
+   * If `end` is equal to `start`, then the returned list is empty.
+   */
+  Uint8ClampedList sublist(int start, [int end]);
+
+  static const int bytesPerElement = 1;
+}
+
+/**
+ * A fixed-length list of 16-bit signed integers that is viewable as a
+ * [TypedData].
+ *
+ * For long lists, this implementation can be considerably
+ * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low 16 bits,
+ * interpreted as a signed 16-bit two's complement integer with values in the
+ * range -32768 to +32767.
+ */
+abstract class Int16List implements List<int>, _TypedIntList {
+  /**
+   * Creates an [Int16List] of the specified length (in elements), all of
+   * whose elements are initially zero.
+   */
+  external factory Int16List(int length);
+
+  /**
+   * Creates a [Int16List] with the same length as the [elements] list
+   * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
+   */
+  external factory Int16List.fromList(List<int> elements);
+
+  /**
+   * Creates an [Int16List] _view_ of the specified region in [buffer].
+   *
+   * Changes in the [Int16List] will be visible in the byte
+   * buffer and vice versa.
+   * If the [offsetInBytes] index of the region is not specified,
+   * it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to `null`,
+   * which indicates that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * [bytesPerElement].
+   */
+  factory Int16List.view(ByteBuffer buffer,
+      [int offsetInBytes = 0, int length]) {
+    return buffer.asInt16List(offsetInBytes, length);
+  }
+
+  /**
+   * Returns a new list containing the elements between [start] and [end].
+   *
+   * The new list is an `Int16List` containing the elements of this
+   * list at positions greater than or equal to [start] and less than [end] in
+   * the same order as they occur in this list.
+   *
+   * ```dart
+   * var numbers = Int16List.fromList([0, 1, 2, 3, 4]);
+   * print(numbers.sublist(1, 3)); // [1, 2]
+   * print(numbers.sublist(1, 3).runtimeType); // Int16List
+   * ```
+   *
+   * If [end] is omitted, it defaults to the [length] of this list.
+   *
+   * ```dart
+   * print(numbers.sublist(1)); // [1, 2, 3, 4]
+   * ```
+   *
+   * The `start` and `end` positions must satisfy the relations
+   * 0 ≤ `start` ≤ `end` ≤ `this.length`
+   * If `end` is equal to `start`, then the returned list is empty.
+   */
+  Int16List sublist(int start, [int end]);
+
+  static const int bytesPerElement = 2;
+}
+
+/**
+ * A fixed-length list of 16-bit unsigned integers that is viewable as a
+ * [TypedData].
+ *
+ * For long lists, this implementation can be considerably
+ * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low 16 bits,
+ * interpreted as an unsigned 16-bit integer with values in the
+ * range 0 to 65535.
+ */
+abstract class Uint16List implements List<int>, _TypedIntList {
+  /**
+   * Creates a [Uint16List] of the specified length (in elements), all
+   * of whose elements are initially zero.
+   */
+  external factory Uint16List(int length);
+
+  /**
+   * Creates a [Uint16List] with the same length as the [elements] list
+   * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
+   */
+  external factory Uint16List.fromList(List<int> elements);
+
+  /**
+   * Creates a [Uint16List] _view_ of the specified region in
+   * the specified byte buffer.
+   *
+   * Changes in the [Uint16List] will be visible in the byte buffer
+   * and vice versa.
+   * If the [offsetInBytes] index of the region is not specified,
+   * it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to `null`,
+   * which indicates that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * [bytesPerElement].
+   */
+  factory Uint16List.view(ByteBuffer buffer,
+      [int offsetInBytes = 0, int length]) {
+    return buffer.asUint16List(offsetInBytes, length);
+  }
+
+  /**
+   * Returns a new list containing the elements between [start] and [end].
+   *
+   * The new list is a `Uint16List` containing the elements of this
+   * list at positions greater than or equal to [start] and less than [end] in
+   * the same order as they occur in this list.
+   *
+   * ```dart
+   * var numbers = Uint16List.fromList([0, 1, 2, 3, 4]);
+   * print(numbers.sublist(1, 3)); // [1, 2]
+   * print(numbers.sublist(1, 3).runtimeType); // Uint16List
+   * ```
+   *
+   * If [end] is omitted, it defaults to the [length] of this list.
+   *
+   * ```dart
+   * print(numbers.sublist(1)); // [1, 2, 3, 4]
+   * ```
+   *
+   * The `start` and `end` positions must satisfy the relations
+   * 0 ≤ `start` ≤ `end` ≤ `this.length`
+   * If `end` is equal to `start`, then the returned list is empty.
+   */
+  Uint16List sublist(int start, [int end]);
+
+  static const int bytesPerElement = 2;
+}
+
+/**
+ * A fixed-length list of 32-bit signed integers that is viewable as a
+ * [TypedData].
+ *
+ * For long lists, this implementation can be considerably
+ * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low 32 bits,
+ * interpreted as a signed 32-bit two's complement integer with values in the
+ * range -2147483648 to 2147483647.
+ */
+abstract class Int32List implements List<int>, _TypedIntList {
+  /**
+   * Creates an [Int32List] of the specified length (in elements), all of
+   * whose elements are initially zero.
+   */
+  external factory Int32List(int length);
+
+  /**
+   * Creates a [Int32List] with the same length as the [elements] list
+   * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
+   */
+  external factory Int32List.fromList(List<int> elements);
+
+  /**
+   * Creates an [Int32List] _view_ of the specified region in [buffer].
+   *
+   * Changes in the [Int32List] will be visible in the byte
+   * buffer and vice versa.
+   * If the [offsetInBytes] index of the region is not specified,
+   * it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to `null`,
+   * which indicates that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * [bytesPerElement].
+   */
+  factory Int32List.view(ByteBuffer buffer,
+      [int offsetInBytes = 0, int length]) {
+    return buffer.asInt32List(offsetInBytes, length);
+  }
+
+  /**
+   * Returns a new list containing the elements between [start] and [end].
+   *
+   * The new list is an `Int32List` containing the elements of this
+   * list at positions greater than or equal to [start] and less than [end] in
+   * the same order as they occur in this list.
+   *
+   * ```dart
+   * var numbers = Int32List.fromList([0, 1, 2, 3, 4]);
+   * print(numbers.sublist(1, 3)); // [1, 2]
+   * print(numbers.sublist(1, 3).runtimeType); // Int32List
+   * ```
+   *
+   * If [end] is omitted, it defaults to the [length] of this list.
+   *
+   * ```dart
+   * print(numbers.sublist(1)); // [1, 2, 3, 4]
+   * ```
+   *
+   * The `start` and `end` positions must satisfy the relations
+   * 0 ≤ `start` ≤ `end` ≤ `this.length`
+   * If `end` is equal to `start`, then the returned list is empty.
+   */
+  Int32List sublist(int start, [int end]);
+
+  static const int bytesPerElement = 4;
+}
+
+/**
+ * A fixed-length list of 32-bit unsigned integers that is viewable as a
+ * [TypedData].
+ *
+ * For long lists, this implementation can be considerably
+ * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low 32 bits,
+ * interpreted as an unsigned 32-bit integer with values in the
+ * range 0 to 4294967295.
+ */
+abstract class Uint32List implements List<int>, _TypedIntList {
+  /**
+   * Creates a [Uint32List] of the specified length (in elements), all
+   * of whose elements are initially zero.
+   */
+  external factory Uint32List(int length);
+
+  /**
+   * Creates a [Uint32List] with the same length as the [elements] list
+   * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
+   */
+  external factory Uint32List.fromList(List<int> elements);
+
+  /**
+   * Creates a [Uint32List] _view_ of the specified region in
+   * the specified byte buffer.
+   *
+   * Changes in the [Uint32List] will be visible in the byte buffer
+   * and vice versa.
+   * If the [offsetInBytes] index of the region is not specified,
+   * it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to `null`,
+   * which indicates that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * [bytesPerElement].
+   */
+  factory Uint32List.view(ByteBuffer buffer,
+      [int offsetInBytes = 0, int length]) {
+    return buffer.asUint32List(offsetInBytes, length);
+  }
+
+  /**
+   * Returns a new list containing the elements between [start] and [end].
+   *
+   * The new list is a `Uint32List` containing the elements of this
+   * list at positions greater than or equal to [start] and less than [end] in
+   * the same order as they occur in this list.
+   *
+   * ```dart
+   * var numbers = Uint32List.fromList([0, 1, 2, 3, 4]);
+   * print(numbers.sublist(1, 3)); // [1, 2]
+   * print(numbers.sublist(1, 3).runtimeType); // Uint32List
+   * ```
+   *
+   * If [end] is omitted, it defaults to the [length] of this list.
+   *
+   * ```dart
+   * print(numbers.sublist(1)); // [1, 2, 3, 4]
+   * ```
+   *
+   * The `start` and `end` positions must satisfy the relations
+   * 0 ≤ `start` ≤ `end` ≤ `this.length`
+   * If `end` is equal to `start`, then the returned list is empty.
+   */
+  Uint32List sublist(int start, [int end]);
+
+  static const int bytesPerElement = 4;
+}
+
+/**
+ * A fixed-length list of 64-bit signed integers that is viewable as a
+ * [TypedData].
+ *
+ * For long lists, this implementation can be considerably
+ * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low 64 bits,
+ * interpreted as a signed 64-bit two's complement integer with values in the
+ * range -9223372036854775808 to +9223372036854775807.
+ */
+abstract class Int64List implements List<int>, _TypedIntList {
+  /**
+   * Creates an [Int64List] of the specified length (in elements), all of
+   * whose elements are initially zero.
+   */
+  external factory Int64List(int length);
+
+  /**
+   * Creates a [Int64List] with the same length as the [elements] list
+   * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
+   */
+  external factory Int64List.fromList(List<int> elements);
+
+  /**
+   * Creates an [Int64List] _view_ of the specified region in [buffer].
+   *
+   * Changes in the [Int64List] will be visible in the byte buffer
+   * and vice versa.
+   * If the [offsetInBytes] index of the region is not specified,
+   * it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to `null`,
+   * which indicates that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * [bytesPerElement].
+   */
+  factory Int64List.view(ByteBuffer buffer,
+      [int offsetInBytes = 0, int length]) {
+    return buffer.asInt64List(offsetInBytes, length);
+  }
+
+  /**
+   * Returns a new list containing the elements between [start] and [end].
+   *
+   * The new list is an `Int64List` containing the elements of this
+   * list at positions greater than or equal to [start] and less than [end] in
+   * the same order as they occur in this list.
+   *
+   * ```dart
+   * var numbers = Int64List.fromList([0, 1, 2, 3, 4]);
+   * print(numbers.sublist(1, 3)); // [1, 2]
+   * print(numbers.sublist(1, 3).runtimeType); // Int64List
+   * ```
+   *
+   * If [end] is omitted, it defaults to the [length] of this list.
+   *
+   * ```dart
+   * print(numbers.sublist(1)); // [1, 2, 3, 4]
+   * ```
+   *
+   * The `start` and `end` positions must satisfy the relations
+   * 0 ≤ `start` ≤ `end` ≤ `this.length`
+   * If `end` is equal to `start`, then the returned list is empty.
+   */
+  Int64List sublist(int start, [int end]);
+
+  static const int bytesPerElement = 8;
+}
+
+/**
+ * A fixed-length list of 64-bit unsigned integers that is viewable as a
+ * [TypedData].
+ *
+ * For long lists, this implementation can be considerably
+ * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low 64 bits,
+ * interpreted as an unsigned 64-bit integer with values in the
+ * range 0 to 18446744073709551615.
+ */
+abstract class Uint64List implements List<int>, _TypedIntList {
+  /**
+   * Creates a [Uint64List] of the specified length (in elements), all
+   * of whose elements are initially zero.
+   */
+  external factory Uint64List(int length);
+
+  /**
+   * Creates a [Uint64List] with the same length as the [elements] list
+   * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
+   */
+  external factory Uint64List.fromList(List<int> elements);
+
+  /**
+   * Creates an [Uint64List] _view_ of the specified region in
+   * the specified byte buffer.
+   *
+   * Changes in the [Uint64List] will be visible in the byte buffer
+   * and vice versa.
+   * If the [offsetInBytes] index of the region is not specified,
+   * it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to `null`,
+   * which indicates that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * [bytesPerElement].
+   */
+  factory Uint64List.view(ByteBuffer buffer,
+      [int offsetInBytes = 0, int length]) {
+    return buffer.asUint64List(offsetInBytes, length);
+  }
+
+  /**
+   * Returns a new list containing the elements between [start] and [end].
+   *
+   * The new list is a `Uint64List` containing the elements of this
+   * list at positions greater than or equal to [start] and less than [end] in
+   * the same order as they occur in this list.
+   *
+   * ```dart
+   * var numbers = Uint64List.fromList([0, 1, 2, 3, 4]);
+   * print(numbers.sublist(1, 3)); // [1, 2]
+   * print(numbers.sublist(1, 3).runtimeType); // Uint64List
+   * ```
+   *
+   * If [end] is omitted, it defaults to the [length] of this list.
+   *
+   * ```dart
+   * print(numbers.sublist(1)); // [1, 2, 3, 4]
+   * ```
+   *
+   * The `start` and `end` positions must satisfy the relations
+   * 0 ≤ `start` ≤ `end` ≤ `this.length`
+   * If `end` is equal to `start`, then the returned list is empty.
+   */
+  Uint64List sublist(int start, [int end]);
+
+  static const int bytesPerElement = 8;
+}
+
+/**
+ * A fixed-length list of IEEE 754 single-precision binary floating-point
+ * numbers that is viewable as a [TypedData].
+ *
+ * For long lists, this
+ * implementation can be considerably more space- and time-efficient than
+ * the default [List] implementation.
+ *
+ * Double values stored in the list are converted to the nearest
+ * single-precision value. Values read are converted to a double
+ * value with the same value.
+ */
+abstract class Float32List implements List<double>, _TypedFloatList {
+  /**
+   * Creates a [Float32List] of the specified length (in elements), all of
+   * whose elements are initially zero.
+   */
+  external factory Float32List(int length);
+
+  /**
+   * Creates a [Float32List] with the same length as the [elements] list
+   * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
+   */
+  external factory Float32List.fromList(List<double> elements);
+
+  /**
+   * Creates a [Float32List] _view_ of the specified region in [buffer].
+   *
+   * Changes in the [Float32List] will be visible in the byte
+   * buffer and vice versa.
+   * If the [offsetInBytes] index of the region is not specified,
+   * it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to `null`,
+   * which indicates that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * [bytesPerElement].
+   */
+  factory Float32List.view(ByteBuffer buffer,
+      [int offsetInBytes = 0, int length]) {
+    return buffer.asFloat32List(offsetInBytes, length);
+  }
+
+  /**
+   * Returns a new list containing the elements between [start] and [end].
+   *
+   * The new list is a `Float32List` containing the elements of this
+   * list at positions greater than or equal to [start] and less than [end] in
+   * the same order as they occur in this list.
+   *
+   * ```dart
+   * var numbers = Float32List.fromList([0, 1, 2, 3, 4]);
+   * print(numbers.sublist(1, 3)); // [1, 2]
+   * print(numbers.sublist(1, 3).runtimeType); // Float32List
+   * ```
+   *
+   * If [end] is omitted, it defaults to the [length] of this list.
+   *
+   * ```dart
+   * print(numbers.sublist(1)); // [1, 2, 3, 4]
+   * ```
+   *
+   * The `start` and `end` positions must satisfy the relations
+   * 0 ≤ `start` ≤ `end` ≤ `this.length`
+   * If `end` is equal to `start`, then the returned list is empty.
+   */
+  Float32List sublist(int start, [int end]);
+
+  static const int bytesPerElement = 4;
+}
+
+/**
+ * A fixed-length list of IEEE 754 double-precision binary floating-point
+ * numbers  that is viewable as a [TypedData].
+ *
+ * For long lists, this
+ * implementation can be considerably more space- and time-efficient than
+ * the default [List] implementation.
+ */
+abstract class Float64List implements List<double>, _TypedFloatList {
+  /**
+   * Creates a [Float64List] of the specified length (in elements), all of
+   * whose elements are initially zero.
+   */
+  external factory Float64List(int length);
+
+  /**
+   * Creates a [Float64List] with the same length as the [elements] list
+   * and copies over the elements.
+   */
+  external factory Float64List.fromList(List<double> elements);
+
+  /**
+   * Creates a [Float64List] _view_ of the specified region in [buffer].
+   *
+   * Changes in the [Float64List] will be visible in the byte
+   * buffer and vice versa.
+   * If the [offsetInBytes] index of the region is not specified,
+   * it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to `null`,
+   * which indicates that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * [bytesPerElement].
+   */
+  factory Float64List.view(ByteBuffer buffer,
+      [int offsetInBytes = 0, int length]) {
+    return buffer.asFloat64List(offsetInBytes, length);
+  }
+
+  /**
+   * Returns a new list containing the elements between [start] and [end].
+   *
+   * The new list is a `Float64List` containing the elements of this
+   * list at positions greater than or equal to [start] and less than [end] in
+   * the same order as they occur in this list.
+   *
+   * ```dart
+   * var numbers = Float64List.fromList([0, 1, 2, 3, 4]);
+   * print(numbers.sublist(1, 3)); // [1, 2]
+   * print(numbers.sublist(1, 3).runtimeType); // Float64List
+   * ```
+   *
+   * If [end] is omitted, it defaults to the [length] of this list.
+   *
+   * ```dart
+   * print(numbers.sublist(1)); // [1, 2, 3, 4]
+   * ```
+   *
+   * The `start` and `end` positions must satisfy the relations
+   * 0 ≤ `start` ≤ `end` ≤ `this.length`
+   * If `end` is equal to `start`, then the returned list is empty.
+   */
+  Float64List sublist(int start, [int end]);
+
+  static const int bytesPerElement = 8;
+}
+
+/**
+ * A fixed-length list of Float32x4 numbers that is viewable as a
+ * [TypedData].
+ *
+ * For long lists, this implementation will be considerably more
+ * space- and time-efficient than the default [List] implementation.
+ */
+abstract class Float32x4List implements List<Float32x4>, TypedData {
+  /**
+   * Creates a [Float32x4List] of the specified length (in elements),
+   * all of whose elements are initially zero.
+   */
+  external factory Float32x4List(int length);
+
+  /**
+   * Creates a [Float32x4List] with the same length as the [elements] list
+   * and copies over the elements.
+   */
+  external factory Float32x4List.fromList(List<Float32x4> elements);
+
+  /**
+   * Creates a [Float32x4List] _view_ of the specified region in [buffer].
+   *
+   * Changes in the [Float32x4List] will be visible in the byte
+   * buffer and vice versa.
+   * If the [offsetInBytes] index of the region is not specified,
+   * it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to `null`,
+   * which indicates that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * [bytesPerElement].
+   */
+  factory Float32x4List.view(ByteBuffer buffer,
+      [int offsetInBytes = 0, int length]) {
+    return buffer.asFloat32x4List(offsetInBytes, length);
+  }
+
+  /**
+   * Returns the concatenation of this list and [other].
+   *
+   * If [other] is also a [Float32x4List], the result is a new [Float32x4List],
+   * otherwise the result is a normal growable `List<Float32x4>`.
+   */
+  List<Float32x4> operator +(List<Float32x4> other);
+
+  /**
+   * Returns a new list containing the elements between [start] and [end].
+   *
+   * The new list is a `Float32x4List` containing the elements of this
+   * list at positions greater than or equal to [start] and less than [end] in
+   * the same order as they occur in this list.
+   *
+   * ```dart
+   * var numbers = Float32x4List.fromList([0, 1, 2, 3, 4]);
+   * print(numbers.sublist(1, 3)); // [1, 2]
+   * print(numbers.sublist(1, 3).runtimeType); // Float32x4List
+   * ```
+   *
+   * If [end] is omitted, it defaults to the [length] of this list.
+   *
+   * ```dart
+   * print(numbers.sublist(1)); // [1, 2, 3, 4]
+   * ```
+   *
+   * The `start` and `end` positions must satisfy the relations
+   * 0 ≤ `start` ≤ `end` ≤ `this.length`
+   * If `end` is equal to `start`, then the returned list is empty.
+   */
+  Float32x4List sublist(int start, [int end]);
+
+  static const int bytesPerElement = 16;
+}
+
+/**
+ * A fixed-length list of Int32x4 numbers that is viewable as a
+ * [TypedData].
+ *
+ * For long lists, this implementation will be considerably more
+ * space- and time-efficient than the default [List] implementation.
+ */
+abstract class Int32x4List implements List<Int32x4>, TypedData {
+  /**
+   * Creates a [Int32x4List] of the specified length (in elements),
+   * all of whose elements are initially zero.
+   */
+  external factory Int32x4List(int length);
+
+  /**
+   * Creates a [Int32x4List] with the same length as the [elements] list
+   * and copies over the elements.
+   */
+  external factory Int32x4List.fromList(List<Int32x4> elements);
+
+  /**
+   * Creates a [Int32x4List] _view_ of the specified region in [buffer].
+   *
+   * Changes in the [Int32x4List] will be visible in the byte
+   * buffer and vice versa.
+   * If the [offsetInBytes] index of the region is not specified,
+   * it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to `null`,
+   * which indicates that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * [bytesPerElement].
+   */
+  factory Int32x4List.view(ByteBuffer buffer,
+      [int offsetInBytes = 0, int length]) {
+    return buffer.asInt32x4List(offsetInBytes, length);
+  }
+
+  /**
+   * Returns the concatenation of this list and [other].
+   *
+   * If [other] is also a [Int32x4List], the result is a new [Int32x4List],
+   * otherwise the result is a normal growable `List<Int32x4>`.
+   */
+  List<Int32x4> operator +(List<Int32x4> other);
+
+  /**
+   * Returns a new list containing the elements between [start] and [end].
+   *
+   * The new list is an `Int32x4list` containing the elements of this
+   * list at positions greater than or equal to [start] and less than [end] in
+   * the same order as they occur in this list.
+   *
+   * ```dart
+   * var numbers = Int32x4list.fromList([0, 1, 2, 3, 4]);
+   * print(numbers.sublist(1, 3)); // [1, 2]
+   * print(numbers.sublist(1, 3).runtimeType); // Int32x4list
+   * ```
+   *
+   * If [end] is omitted, it defaults to the [length] of this list.
+   *
+   * ```dart
+   * print(numbers.sublist(1)); // [1, 2, 3, 4]
+   * ```
+   *
+   * The `start` and `end` positions must satisfy the relations
+   * 0 ≤ `start` ≤ `end` ≤ `this.length`
+   * If `end` is equal to `start`, then the returned list is empty.
+   */
+  Int32x4List sublist(int start, [int end]);
+
+  static const int bytesPerElement = 16;
+}
+
+/**
+ * A fixed-length list of Float64x2 numbers that is viewable as a
+ * [TypedData].
+ *
+ * For long lists, this implementation will be considerably more
+ * space- and time-efficient than the default [List] implementation.
+ */
+abstract class Float64x2List implements List<Float64x2>, TypedData {
+  /**
+   * Creates a [Float64x2List] of the specified length (in elements),
+   * all of whose elements have all lanes set to zero.
+   */
+  external factory Float64x2List(int length);
+
+  /**
+   * Creates a [Float64x2List] with the same length as the [elements] list
+   * and copies over the elements.
+   */
+  external factory Float64x2List.fromList(List<Float64x2> elements);
+
+  /**
+   * Returns the concatenation of this list and [other].
+   *
+   * If [other] is also a [Float64x2List], the result is a new [Float64x2List],
+   * otherwise the result is a normal growable `List<Float64x2>`.
+   */
+  List<Float64x2> operator +(List<Float64x2> other);
+
+  /**
+   * Creates a [Float64x2List] _view_ of the specified region in [buffer].
+   *
+   * Changes in the [Float64x2List] will be visible in the byte
+   * buffer and vice versa.
+   * If the [offsetInBytes] index of the region is not specified,
+   * it defaults to zero (the first byte in the byte buffer).
+   * If the length is not specified, it defaults to `null`,
+   * which indicates that the view extends to the end of the byte buffer.
+   *
+   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
+   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
+   * the length of [buffer].
+   *
+   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
+   * [bytesPerElement].
+   */
+  factory Float64x2List.view(ByteBuffer buffer,
+      [int offsetInBytes = 0, int length]) {
+    return buffer.asFloat64x2List(offsetInBytes, length);
+  }
+
+  /**
+   * Returns a new list containing the elements between [start] and [end].
+   *
+   * The new list is a `Float64x2List` containing the elements of this
+   * list at positions greater than or equal to [start] and less than [end] in
+   * the same order as they occur in this list.
+   *
+   * ```dart
+   * var numbers = Float64x2List.fromList([0, 1, 2, 3, 4]);
+   * print(numbers.sublist(1, 3)); // [1, 2]
+   * print(numbers.sublist(1, 3).runtimeType); // Float64x2List
+   * ```
+   *
+   * If [end] is omitted, it defaults to the [length] of this list.
+   *
+   * ```dart
+   * print(numbers.sublist(1)); // [1, 2, 3, 4]
+   * ```
+   *
+   * The `start` and `end` positions must satisfy the relations
+   * 0 ≤ `start` ≤ `end` ≤ `this.length`
+   * If `end` is equal to `start`, then the returned list is empty.
+   */
+  Float64x2List sublist(int start, [int end]);
+
+  static const int bytesPerElement = 16;
+}
+
+/**
+ * Float32x4 immutable value type and operations.
+ *
+ * Float32x4 stores 4 32-bit floating point values in "lanes".
+ * The lanes are "x", "y", "z", and "w" respectively.
+ */
+abstract class Float32x4 {
+  external factory Float32x4(double x, double y, double z, double w);
+  external factory Float32x4.splat(double v);
+  external factory Float32x4.zero();
+  external factory Float32x4.fromInt32x4Bits(Int32x4 x);
+
+  /// Sets the x and y lanes to their respective values in [v] and sets the z
+  /// and w lanes to 0.0.
+  external factory Float32x4.fromFloat64x2(Float64x2 v);
+
+  /// Addition operator.
+  Float32x4 operator +(Float32x4 other);
+
+  /// Negate operator.
+  Float32x4 operator -();
+
+  /// Subtraction operator.
+  Float32x4 operator -(Float32x4 other);
+
+  /// Multiplication operator.
+  Float32x4 operator *(Float32x4 other);
+
+  /// Division operator.
+  Float32x4 operator /(Float32x4 other);
+
+  /// Relational less than.
+  Int32x4 lessThan(Float32x4 other);
+
+  /// Relational less than or equal.
+  Int32x4 lessThanOrEqual(Float32x4 other);
+
+  /// Relational greater than.
+  Int32x4 greaterThan(Float32x4 other);
+
+  /// Relational greater than or equal.
+  Int32x4 greaterThanOrEqual(Float32x4 other);
+
+  /// Relational equal.
+  Int32x4 equal(Float32x4 other);
+
+  /// Relational not-equal.
+  Int32x4 notEqual(Float32x4 other);
+
+  /// Returns a copy of [this] each lane being scaled by [s].
+  /// Equivalent to this * new Float32x4.splat(s)
+  Float32x4 scale(double s);
+
+  /// Returns the lane-wise absolute value of this [Float32x4].
+  Float32x4 abs();
+
+  /// Lane-wise clamp [this] to be in the range [lowerLimit]-[upperLimit].
+  Float32x4 clamp(Float32x4 lowerLimit, Float32x4 upperLimit);
+
+  /// Extracted x value.
+  double get x;
+
+  /// Extracted y value.
+  double get y;
+
+  /// Extracted z value.
+  double get z;
+
+  /// Extracted w value.
+  double get w;
+
+  /// Extract the sign bits from each lane return them in the first 4 bits.
+  /// "x" lane is bit 0.
+  /// "y" lane is bit 1.
+  /// "z" lane is bit 2.
+  /// "w" lane is bit 3.
+  int get signMask;
+
+  /// Mask passed to [shuffle] or [shuffleMix].
+  static const int xxxx = 0x0;
+  static const int xxxy = 0x40;
+  static const int xxxz = 0x80;
+  static const int xxxw = 0xC0;
+  static const int xxyx = 0x10;
+  static const int xxyy = 0x50;
+  static const int xxyz = 0x90;
+  static const int xxyw = 0xD0;
+  static const int xxzx = 0x20;
+  static const int xxzy = 0x60;
+  static const int xxzz = 0xA0;
+  static const int xxzw = 0xE0;
+  static const int xxwx = 0x30;
+  static const int xxwy = 0x70;
+  static const int xxwz = 0xB0;
+  static const int xxww = 0xF0;
+  static const int xyxx = 0x4;
+  static const int xyxy = 0x44;
+  static const int xyxz = 0x84;
+  static const int xyxw = 0xC4;
+  static const int xyyx = 0x14;
+  static const int xyyy = 0x54;
+  static const int xyyz = 0x94;
+  static const int xyyw = 0xD4;
+  static const int xyzx = 0x24;
+  static const int xyzy = 0x64;
+  static const int xyzz = 0xA4;
+  static const int xyzw = 0xE4;
+  static const int xywx = 0x34;
+  static const int xywy = 0x74;
+  static const int xywz = 0xB4;
+  static const int xyww = 0xF4;
+  static const int xzxx = 0x8;
+  static const int xzxy = 0x48;
+  static const int xzxz = 0x88;
+  static const int xzxw = 0xC8;
+  static const int xzyx = 0x18;
+  static const int xzyy = 0x58;
+  static const int xzyz = 0x98;
+  static const int xzyw = 0xD8;
+  static const int xzzx = 0x28;
+  static const int xzzy = 0x68;
+  static const int xzzz = 0xA8;
+  static const int xzzw = 0xE8;
+  static const int xzwx = 0x38;
+  static const int xzwy = 0x78;
+  static const int xzwz = 0xB8;
+  static const int xzww = 0xF8;
+  static const int xwxx = 0xC;
+  static const int xwxy = 0x4C;
+  static const int xwxz = 0x8C;
+  static const int xwxw = 0xCC;
+  static const int xwyx = 0x1C;
+  static const int xwyy = 0x5C;
+  static const int xwyz = 0x9C;
+  static const int xwyw = 0xDC;
+  static const int xwzx = 0x2C;
+  static const int xwzy = 0x6C;
+  static const int xwzz = 0xAC;
+  static const int xwzw = 0xEC;
+  static const int xwwx = 0x3C;
+  static const int xwwy = 0x7C;
+  static const int xwwz = 0xBC;
+  static const int xwww = 0xFC;
+  static const int yxxx = 0x1;
+  static const int yxxy = 0x41;
+  static const int yxxz = 0x81;
+  static const int yxxw = 0xC1;
+  static const int yxyx = 0x11;
+  static const int yxyy = 0x51;
+  static const int yxyz = 0x91;
+  static const int yxyw = 0xD1;
+  static const int yxzx = 0x21;
+  static const int yxzy = 0x61;
+  static const int yxzz = 0xA1;
+  static const int yxzw = 0xE1;
+  static const int yxwx = 0x31;
+  static const int yxwy = 0x71;
+  static const int yxwz = 0xB1;
+  static const int yxww = 0xF1;
+  static const int yyxx = 0x5;
+  static const int yyxy = 0x45;
+  static const int yyxz = 0x85;
+  static const int yyxw = 0xC5;
+  static const int yyyx = 0x15;
+  static const int yyyy = 0x55;
+  static const int yyyz = 0x95;
+  static const int yyyw = 0xD5;
+  static const int yyzx = 0x25;
+  static const int yyzy = 0x65;
+  static const int yyzz = 0xA5;
+  static const int yyzw = 0xE5;
+  static const int yywx = 0x35;
+  static const int yywy = 0x75;
+  static const int yywz = 0xB5;
+  static const int yyww = 0xF5;
+  static const int yzxx = 0x9;
+  static const int yzxy = 0x49;
+  static const int yzxz = 0x89;
+  static const int yzxw = 0xC9;
+  static const int yzyx = 0x19;
+  static const int yzyy = 0x59;
+  static const int yzyz = 0x99;
+  static const int yzyw = 0xD9;
+  static const int yzzx = 0x29;
+  static const int yzzy = 0x69;
+  static const int yzzz = 0xA9;
+  static const int yzzw = 0xE9;
+  static const int yzwx = 0x39;
+  static const int yzwy = 0x79;
+  static const int yzwz = 0xB9;
+  static const int yzww = 0xF9;
+  static const int ywxx = 0xD;
+  static const int ywxy = 0x4D;
+  static const int ywxz = 0x8D;
+  static const int ywxw = 0xCD;
+  static const int ywyx = 0x1D;
+  static const int ywyy = 0x5D;
+  static const int ywyz = 0x9D;
+  static const int ywyw = 0xDD;
+  static const int ywzx = 0x2D;
+  static const int ywzy = 0x6D;
+  static const int ywzz = 0xAD;
+  static const int ywzw = 0xED;
+  static const int ywwx = 0x3D;
+  static const int ywwy = 0x7D;
+  static const int ywwz = 0xBD;
+  static const int ywww = 0xFD;
+  static const int zxxx = 0x2;
+  static const int zxxy = 0x42;
+  static const int zxxz = 0x82;
+  static const int zxxw = 0xC2;
+  static const int zxyx = 0x12;
+  static const int zxyy = 0x52;
+  static const int zxyz = 0x92;
+  static const int zxyw = 0xD2;
+  static const int zxzx = 0x22;
+  static const int zxzy = 0x62;
+  static const int zxzz = 0xA2;
+  static const int zxzw = 0xE2;
+  static const int zxwx = 0x32;
+  static const int zxwy = 0x72;
+  static const int zxwz = 0xB2;
+  static const int zxww = 0xF2;
+  static const int zyxx = 0x6;
+  static const int zyxy = 0x46;
+  static const int zyxz = 0x86;
+  static const int zyxw = 0xC6;
+  static const int zyyx = 0x16;
+  static const int zyyy = 0x56;
+  static const int zyyz = 0x96;
+  static const int zyyw = 0xD6;
+  static const int zyzx = 0x26;
+  static const int zyzy = 0x66;
+  static const int zyzz = 0xA6;
+  static const int zyzw = 0xE6;
+  static const int zywx = 0x36;
+  static const int zywy = 0x76;
+  static const int zywz = 0xB6;
+  static const int zyww = 0xF6;
+  static const int zzxx = 0xA;
+  static const int zzxy = 0x4A;
+  static const int zzxz = 0x8A;
+  static const int zzxw = 0xCA;
+  static const int zzyx = 0x1A;
+  static const int zzyy = 0x5A;
+  static const int zzyz = 0x9A;
+  static const int zzyw = 0xDA;
+  static const int zzzx = 0x2A;
+  static const int zzzy = 0x6A;
+  static const int zzzz = 0xAA;
+  static const int zzzw = 0xEA;
+  static const int zzwx = 0x3A;
+  static const int zzwy = 0x7A;
+  static const int zzwz = 0xBA;
+  static const int zzww = 0xFA;
+  static const int zwxx = 0xE;
+  static const int zwxy = 0x4E;
+  static const int zwxz = 0x8E;
+  static const int zwxw = 0xCE;
+  static const int zwyx = 0x1E;
+  static const int zwyy = 0x5E;
+  static const int zwyz = 0x9E;
+  static const int zwyw = 0xDE;
+  static const int zwzx = 0x2E;
+  static const int zwzy = 0x6E;
+  static const int zwzz = 0xAE;
+  static const int zwzw = 0xEE;
+  static const int zwwx = 0x3E;
+  static const int zwwy = 0x7E;
+  static const int zwwz = 0xBE;
+  static const int zwww = 0xFE;
+  static const int wxxx = 0x3;
+  static const int wxxy = 0x43;
+  static const int wxxz = 0x83;
+  static const int wxxw = 0xC3;
+  static const int wxyx = 0x13;
+  static const int wxyy = 0x53;
+  static const int wxyz = 0x93;
+  static const int wxyw = 0xD3;
+  static const int wxzx = 0x23;
+  static const int wxzy = 0x63;
+  static const int wxzz = 0xA3;
+  static const int wxzw = 0xE3;
+  static const int wxwx = 0x33;
+  static const int wxwy = 0x73;
+  static const int wxwz = 0xB3;
+  static const int wxww = 0xF3;
+  static const int wyxx = 0x7;
+  static const int wyxy = 0x47;
+  static const int wyxz = 0x87;
+  static const int wyxw = 0xC7;
+  static const int wyyx = 0x17;
+  static const int wyyy = 0x57;
+  static const int wyyz = 0x97;
+  static const int wyyw = 0xD7;
+  static const int wyzx = 0x27;
+  static const int wyzy = 0x67;
+  static const int wyzz = 0xA7;
+  static const int wyzw = 0xE7;
+  static const int wywx = 0x37;
+  static const int wywy = 0x77;
+  static const int wywz = 0xB7;
+  static const int wyww = 0xF7;
+  static const int wzxx = 0xB;
+  static const int wzxy = 0x4B;
+  static const int wzxz = 0x8B;
+  static const int wzxw = 0xCB;
+  static const int wzyx = 0x1B;
+  static const int wzyy = 0x5B;
+  static const int wzyz = 0x9B;
+  static const int wzyw = 0xDB;
+  static const int wzzx = 0x2B;
+  static const int wzzy = 0x6B;
+  static const int wzzz = 0xAB;
+  static const int wzzw = 0xEB;
+  static const int wzwx = 0x3B;
+  static const int wzwy = 0x7B;
+  static const int wzwz = 0xBB;
+  static const int wzww = 0xFB;
+  static const int wwxx = 0xF;
+  static const int wwxy = 0x4F;
+  static const int wwxz = 0x8F;
+  static const int wwxw = 0xCF;
+  static const int wwyx = 0x1F;
+  static const int wwyy = 0x5F;
+  static const int wwyz = 0x9F;
+  static const int wwyw = 0xDF;
+  static const int wwzx = 0x2F;
+  static const int wwzy = 0x6F;
+  static const int wwzz = 0xAF;
+  static const int wwzw = 0xEF;
+  static const int wwwx = 0x3F;
+  static const int wwwy = 0x7F;
+  static const int wwwz = 0xBF;
+  static const int wwww = 0xFF;
+
+  /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
+  Float32x4 shuffle(int mask);
+
+  /// Shuffle the lane values in [this] and [other]. The returned
+  /// Float32x4 will have XY lanes from [this] and ZW lanes from [other].
+  /// Uses the same [mask] as [shuffle].
+  Float32x4 shuffleMix(Float32x4 other, int mask);
+
+  /// Returns a new [Float32x4] copied from [this] with a new x value.
+  Float32x4 withX(double x);
+
+  /// Returns a new [Float32x4] copied from [this] with a new y value.
+  Float32x4 withY(double y);
+
+  /// Returns a new [Float32x4] copied from [this] with a new z value.
+  Float32x4 withZ(double z);
+
+  /// Returns a new [Float32x4] copied from [this] with a new w value.
+  Float32x4 withW(double w);
+
+  /// Returns the lane-wise minimum value in [this] or [other].
+  Float32x4 min(Float32x4 other);
+
+  /// Returns the lane-wise maximum value in [this] or [other].
+  Float32x4 max(Float32x4 other);
+
+  /// Returns the square root of [this].
+  Float32x4 sqrt();
+
+  /// Returns the reciprocal of [this].
+  Float32x4 reciprocal();
+
+  /// Returns the square root of the reciprocal of [this].
+  Float32x4 reciprocalSqrt();
+}
+
+/**
+ * Int32x4 and operations.
+ *
+ * Int32x4 stores 4 32-bit bit-masks in "lanes".
+ * The lanes are "x", "y", "z", and "w" respectively.
+ */
+abstract class Int32x4 {
+  external factory Int32x4(int x, int y, int z, int w);
+  external factory Int32x4.bool(bool x, bool y, bool z, bool w);
+  external factory Int32x4.fromFloat32x4Bits(Float32x4 x);
+
+  /// The bit-wise or operator.
+  Int32x4 operator |(Int32x4 other);
+
+  /// The bit-wise and operator.
+  Int32x4 operator &(Int32x4 other);
+
+  /// The bit-wise xor operator.
+  Int32x4 operator ^(Int32x4 other);
+
+  /// Addition operator.
+  Int32x4 operator +(Int32x4 other);
+
+  /// Subtraction operator.
+  Int32x4 operator -(Int32x4 other);
+
+  /// Extract 32-bit mask from x lane.
+  int get x;
+
+  /// Extract 32-bit mask from y lane.
+  int get y;
+
+  /// Extract 32-bit mask from z lane.
+  int get z;
+
+  /// Extract 32-bit mask from w lane.
+  int get w;
+
+  /// Extract the top bit from each lane return them in the first 4 bits.
+  /// "x" lane is bit 0.
+  /// "y" lane is bit 1.
+  /// "z" lane is bit 2.
+  /// "w" lane is bit 3.
+  int get signMask;
+
+  /// Mask passed to [shuffle] or [shuffleMix].
+  static const int xxxx = 0x0;
+  static const int xxxy = 0x40;
+  static const int xxxz = 0x80;
+  static const int xxxw = 0xC0;
+  static const int xxyx = 0x10;
+  static const int xxyy = 0x50;
+  static const int xxyz = 0x90;
+  static const int xxyw = 0xD0;
+  static const int xxzx = 0x20;
+  static const int xxzy = 0x60;
+  static const int xxzz = 0xA0;
+  static const int xxzw = 0xE0;
+  static const int xxwx = 0x30;
+  static const int xxwy = 0x70;
+  static const int xxwz = 0xB0;
+  static const int xxww = 0xF0;
+  static const int xyxx = 0x4;
+  static const int xyxy = 0x44;
+  static const int xyxz = 0x84;
+  static const int xyxw = 0xC4;
+  static const int xyyx = 0x14;
+  static const int xyyy = 0x54;
+  static const int xyyz = 0x94;
+  static const int xyyw = 0xD4;
+  static const int xyzx = 0x24;
+  static const int xyzy = 0x64;
+  static const int xyzz = 0xA4;
+  static const int xyzw = 0xE4;
+  static const int xywx = 0x34;
+  static const int xywy = 0x74;
+  static const int xywz = 0xB4;
+  static const int xyww = 0xF4;
+  static const int xzxx = 0x8;
+  static const int xzxy = 0x48;
+  static const int xzxz = 0x88;
+  static const int xzxw = 0xC8;
+  static const int xzyx = 0x18;
+  static const int xzyy = 0x58;
+  static const int xzyz = 0x98;
+  static const int xzyw = 0xD8;
+  static const int xzzx = 0x28;
+  static const int xzzy = 0x68;
+  static const int xzzz = 0xA8;
+  static const int xzzw = 0xE8;
+  static const int xzwx = 0x38;
+  static const int xzwy = 0x78;
+  static const int xzwz = 0xB8;
+  static const int xzww = 0xF8;
+  static const int xwxx = 0xC;
+  static const int xwxy = 0x4C;
+  static const int xwxz = 0x8C;
+  static const int xwxw = 0xCC;
+  static const int xwyx = 0x1C;
+  static const int xwyy = 0x5C;
+  static const int xwyz = 0x9C;
+  static const int xwyw = 0xDC;
+  static const int xwzx = 0x2C;
+  static const int xwzy = 0x6C;
+  static const int xwzz = 0xAC;
+  static const int xwzw = 0xEC;
+  static const int xwwx = 0x3C;
+  static const int xwwy = 0x7C;
+  static const int xwwz = 0xBC;
+  static const int xwww = 0xFC;
+  static const int yxxx = 0x1;
+  static const int yxxy = 0x41;
+  static const int yxxz = 0x81;
+  static const int yxxw = 0xC1;
+  static const int yxyx = 0x11;
+  static const int yxyy = 0x51;
+  static const int yxyz = 0x91;
+  static const int yxyw = 0xD1;
+  static const int yxzx = 0x21;
+  static const int yxzy = 0x61;
+  static const int yxzz = 0xA1;
+  static const int yxzw = 0xE1;
+  static const int yxwx = 0x31;
+  static const int yxwy = 0x71;
+  static const int yxwz = 0xB1;
+  static const int yxww = 0xF1;
+  static const int yyxx = 0x5;
+  static const int yyxy = 0x45;
+  static const int yyxz = 0x85;
+  static const int yyxw = 0xC5;
+  static const int yyyx = 0x15;
+  static const int yyyy = 0x55;
+  static const int yyyz = 0x95;
+  static const int yyyw = 0xD5;
+  static const int yyzx = 0x25;
+  static const int yyzy = 0x65;
+  static const int yyzz = 0xA5;
+  static const int yyzw = 0xE5;
+  static const int yywx = 0x35;
+  static const int yywy = 0x75;
+  static const int yywz = 0xB5;
+  static const int yyww = 0xF5;
+  static const int yzxx = 0x9;
+  static const int yzxy = 0x49;
+  static const int yzxz = 0x89;
+  static const int yzxw = 0xC9;
+  static const int yzyx = 0x19;
+  static const int yzyy = 0x59;
+  static const int yzyz = 0x99;
+  static const int yzyw = 0xD9;
+  static const int yzzx = 0x29;
+  static const int yzzy = 0x69;
+  static const int yzzz = 0xA9;
+  static const int yzzw = 0xE9;
+  static const int yzwx = 0x39;
+  static const int yzwy = 0x79;
+  static const int yzwz = 0xB9;
+  static const int yzww = 0xF9;
+  static const int ywxx = 0xD;
+  static const int ywxy = 0x4D;
+  static const int ywxz = 0x8D;
+  static const int ywxw = 0xCD;
+  static const int ywyx = 0x1D;
+  static const int ywyy = 0x5D;
+  static const int ywyz = 0x9D;
+  static const int ywyw = 0xDD;
+  static const int ywzx = 0x2D;
+  static const int ywzy = 0x6D;
+  static const int ywzz = 0xAD;
+  static const int ywzw = 0xED;
+  static const int ywwx = 0x3D;
+  static const int ywwy = 0x7D;
+  static const int ywwz = 0xBD;
+  static const int ywww = 0xFD;
+  static const int zxxx = 0x2;
+  static const int zxxy = 0x42;
+  static const int zxxz = 0x82;
+  static const int zxxw = 0xC2;
+  static const int zxyx = 0x12;
+  static const int zxyy = 0x52;
+  static const int zxyz = 0x92;
+  static const int zxyw = 0xD2;
+  static const int zxzx = 0x22;
+  static const int zxzy = 0x62;
+  static const int zxzz = 0xA2;
+  static const int zxzw = 0xE2;
+  static const int zxwx = 0x32;
+  static const int zxwy = 0x72;
+  static const int zxwz = 0xB2;
+  static const int zxww = 0xF2;
+  static const int zyxx = 0x6;
+  static const int zyxy = 0x46;
+  static const int zyxz = 0x86;
+  static const int zyxw = 0xC6;
+  static const int zyyx = 0x16;
+  static const int zyyy = 0x56;
+  static const int zyyz = 0x96;
+  static const int zyyw = 0xD6;
+  static const int zyzx = 0x26;
+  static const int zyzy = 0x66;
+  static const int zyzz = 0xA6;
+  static const int zyzw = 0xE6;
+  static const int zywx = 0x36;
+  static const int zywy = 0x76;
+  static const int zywz = 0xB6;
+  static const int zyww = 0xF6;
+  static const int zzxx = 0xA;
+  static const int zzxy = 0x4A;
+  static const int zzxz = 0x8A;
+  static const int zzxw = 0xCA;
+  static const int zzyx = 0x1A;
+  static const int zzyy = 0x5A;
+  static const int zzyz = 0x9A;
+  static const int zzyw = 0xDA;
+  static const int zzzx = 0x2A;
+  static const int zzzy = 0x6A;
+  static const int zzzz = 0xAA;
+  static const int zzzw = 0xEA;
+  static const int zzwx = 0x3A;
+  static const int zzwy = 0x7A;
+  static const int zzwz = 0xBA;
+  static const int zzww = 0xFA;
+  static const int zwxx = 0xE;
+  static const int zwxy = 0x4E;
+  static const int zwxz = 0x8E;
+  static const int zwxw = 0xCE;
+  static const int zwyx = 0x1E;
+  static const int zwyy = 0x5E;
+  static const int zwyz = 0x9E;
+  static const int zwyw = 0xDE;
+  static const int zwzx = 0x2E;
+  static const int zwzy = 0x6E;
+  static const int zwzz = 0xAE;
+  static const int zwzw = 0xEE;
+  static const int zwwx = 0x3E;
+  static const int zwwy = 0x7E;
+  static const int zwwz = 0xBE;
+  static const int zwww = 0xFE;
+  static const int wxxx = 0x3;
+  static const int wxxy = 0x43;
+  static const int wxxz = 0x83;
+  static const int wxxw = 0xC3;
+  static const int wxyx = 0x13;
+  static const int wxyy = 0x53;
+  static const int wxyz = 0x93;
+  static const int wxyw = 0xD3;
+  static const int wxzx = 0x23;
+  static const int wxzy = 0x63;
+  static const int wxzz = 0xA3;
+  static const int wxzw = 0xE3;
+  static const int wxwx = 0x33;
+  static const int wxwy = 0x73;
+  static const int wxwz = 0xB3;
+  static const int wxww = 0xF3;
+  static const int wyxx = 0x7;
+  static const int wyxy = 0x47;
+  static const int wyxz = 0x87;
+  static const int wyxw = 0xC7;
+  static const int wyyx = 0x17;
+  static const int wyyy = 0x57;
+  static const int wyyz = 0x97;
+  static const int wyyw = 0xD7;
+  static const int wyzx = 0x27;
+  static const int wyzy = 0x67;
+  static const int wyzz = 0xA7;
+  static const int wyzw = 0xE7;
+  static const int wywx = 0x37;
+  static const int wywy = 0x77;
+  static const int wywz = 0xB7;
+  static const int wyww = 0xF7;
+  static const int wzxx = 0xB;
+  static const int wzxy = 0x4B;
+  static const int wzxz = 0x8B;
+  static const int wzxw = 0xCB;
+  static const int wzyx = 0x1B;
+  static const int wzyy = 0x5B;
+  static const int wzyz = 0x9B;
+  static const int wzyw = 0xDB;
+  static const int wzzx = 0x2B;
+  static const int wzzy = 0x6B;
+  static const int wzzz = 0xAB;
+  static const int wzzw = 0xEB;
+  static const int wzwx = 0x3B;
+  static const int wzwy = 0x7B;
+  static const int wzwz = 0xBB;
+  static const int wzww = 0xFB;
+  static const int wwxx = 0xF;
+  static const int wwxy = 0x4F;
+  static const int wwxz = 0x8F;
+  static const int wwxw = 0xCF;
+  static const int wwyx = 0x1F;
+  static const int wwyy = 0x5F;
+  static const int wwyz = 0x9F;
+  static const int wwyw = 0xDF;
+  static const int wwzx = 0x2F;
+  static const int wwzy = 0x6F;
+  static const int wwzz = 0xAF;
+  static const int wwzw = 0xEF;
+  static const int wwwx = 0x3F;
+  static const int wwwy = 0x7F;
+  static const int wwwz = 0xBF;
+  static const int wwww = 0xFF;
+
+  /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
+  Int32x4 shuffle(int mask);
+
+  /// Shuffle the lane values in [this] and [other]. The returned
+  /// Int32x4 will have XY lanes from [this] and ZW lanes from [other].
+  /// Uses the same [mask] as [shuffle].
+  Int32x4 shuffleMix(Int32x4 other, int mask);
+
+  /// Returns a new [Int32x4] copied from [this] with a new x value.
+  Int32x4 withX(int x);
+
+  /// Returns a new [Int32x4] copied from [this] with a new y value.
+  Int32x4 withY(int y);
+
+  /// Returns a new [Int32x4] copied from [this] with a new z value.
+  Int32x4 withZ(int z);
+
+  /// Returns a new [Int32x4] copied from [this] with a new w value.
+  Int32x4 withW(int w);
+
+  /// Extracted x value. Returns false for 0, true for any other value.
+  bool get flagX;
+
+  /// Extracted y value. Returns false for 0, true for any other value.
+  bool get flagY;
+
+  /// Extracted z value. Returns false for 0, true for any other value.
+  bool get flagZ;
+
+  /// Extracted w value. Returns false for 0, true for any other value.
+  bool get flagW;
+
+  /// Returns a new [Int32x4] copied from [this] with a new x value.
+  Int32x4 withFlagX(bool x);
+
+  /// Returns a new [Int32x4] copied from [this] with a new y value.
+  Int32x4 withFlagY(bool y);
+
+  /// Returns a new [Int32x4] copied from [this] with a new z value.
+  Int32x4 withFlagZ(bool z);
+
+  /// Returns a new [Int32x4] copied from [this] with a new w value.
+  Int32x4 withFlagW(bool w);
+
+  /// Merge [trueValue] and [falseValue] based on [this]' bit mask:
+  /// Select bit from [trueValue] when bit in [this] is on.
+  /// Select bit from [falseValue] when bit in [this] is off.
+  Float32x4 select(Float32x4 trueValue, Float32x4 falseValue);
+}
+
+/**
+ * Float64x2 immutable value type and operations.
+ *
+ * Float64x2 stores 2 64-bit floating point values in "lanes".
+ * The lanes are "x" and "y" respectively.
+ */
+abstract class Float64x2 {
+  external factory Float64x2(double x, double y);
+  external factory Float64x2.splat(double v);
+  external factory Float64x2.zero();
+
+  /// Uses the "x" and "y" lanes from [v].
+  external factory Float64x2.fromFloat32x4(Float32x4 v);
+
+  /// Addition operator.
+  Float64x2 operator +(Float64x2 other);
+
+  /// Negate operator.
+  Float64x2 operator -();
+
+  /// Subtraction operator.
+  Float64x2 operator -(Float64x2 other);
+
+  /// Multiplication operator.
+  Float64x2 operator *(Float64x2 other);
+
+  /// Division operator.
+  Float64x2 operator /(Float64x2 other);
+
+  /// Returns a copy of [this] each lane being scaled by [s].
+  /// Equivalent to this * new Float64x2.splat(s)
+  Float64x2 scale(double s);
+
+  /// Returns the lane-wise absolute value of this [Float64x2].
+  Float64x2 abs();
+
+  /// Lane-wise clamp [this] to be in the range [lowerLimit]-[upperLimit].
+  Float64x2 clamp(Float64x2 lowerLimit, Float64x2 upperLimit);
+
+  /// Extracted x value.
+  double get x;
+
+  /// Extracted y value.
+  double get y;
+
+  /// Extract the sign bits from each lane return them in the first 2 bits.
+  /// "x" lane is bit 0.
+  /// "y" lane is bit 1.
+  int get signMask;
+
+  /// Returns a new [Float64x2] copied from [this] with a new x value.
+  Float64x2 withX(double x);
+
+  /// Returns a new [Float64x2] copied from [this] with a new y value.
+  Float64x2 withY(double y);
+
+  /// Returns the lane-wise minimum value in [this] or [other].
+  Float64x2 min(Float64x2 other);
+
+  /// Returns the lane-wise maximum value in [this] or [other].
+  Float64x2 max(Float64x2 other);
+
+  /// Returns the lane-wise square root of [this].
+  Float64x2 sqrt();
+}
diff --git a/sdk_nnbd/lib/typed_data/typed_data_sources.gni b/sdk_nnbd/lib/typed_data/typed_data_sources.gni
new file mode 100644
index 0000000..23ba0f0
--- /dev/null
+++ b/sdk_nnbd/lib/typed_data/typed_data_sources.gni
@@ -0,0 +1,9 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+typed_data_sdk_sources = [
+  "typed_data.dart",
+  # The above file needs to be first if additional parts are added to the lib.
+  "unmodifiable_typed_data.dart",
+]
diff --git a/sdk_nnbd/lib/typed_data/unmodifiable_typed_data.dart b/sdk_nnbd/lib/typed_data/unmodifiable_typed_data.dart
new file mode 100644
index 0000000..3549041
--- /dev/null
+++ b/sdk_nnbd/lib/typed_data/unmodifiable_typed_data.dart
@@ -0,0 +1,341 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart.typed_data;
+
+/**
+ * A read-only view of a [ByteBuffer].
+ */
+class UnmodifiableByteBufferView implements ByteBuffer {
+  final ByteBuffer _data;
+
+  UnmodifiableByteBufferView(ByteBuffer data) : _data = data;
+
+  int get lengthInBytes => _data.lengthInBytes;
+
+  Uint8List asUint8List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableUint8ListView(_data.asUint8List(offsetInBytes, length));
+
+  Int8List asInt8List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableInt8ListView(_data.asInt8List(offsetInBytes, length));
+
+  Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableUint8ClampedListView(
+          _data.asUint8ClampedList(offsetInBytes, length));
+
+  Uint16List asUint16List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableUint16ListView(_data.asUint16List(offsetInBytes, length));
+
+  Int16List asInt16List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableInt16ListView(_data.asInt16List(offsetInBytes, length));
+
+  Uint32List asUint32List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableUint32ListView(_data.asUint32List(offsetInBytes, length));
+
+  Int32List asInt32List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableInt32ListView(_data.asInt32List(offsetInBytes, length));
+
+  Uint64List asUint64List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableUint64ListView(_data.asUint64List(offsetInBytes, length));
+
+  Int64List asInt64List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableInt64ListView(_data.asInt64List(offsetInBytes, length));
+
+  Int32x4List asInt32x4List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableInt32x4ListView(
+          _data.asInt32x4List(offsetInBytes, length));
+
+  Float32List asFloat32List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableFloat32ListView(
+          _data.asFloat32List(offsetInBytes, length));
+
+  Float64List asFloat64List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableFloat64ListView(
+          _data.asFloat64List(offsetInBytes, length));
+
+  Float32x4List asFloat32x4List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableFloat32x4ListView(
+          _data.asFloat32x4List(offsetInBytes, length));
+
+  Float64x2List asFloat64x2List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableFloat64x2ListView(
+          _data.asFloat64x2List(offsetInBytes, length));
+
+  ByteData asByteData([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableByteDataView(_data.asByteData(offsetInBytes, length));
+}
+
+/**
+ * A read-only view of a [ByteData].
+ */
+class UnmodifiableByteDataView implements ByteData {
+  final ByteData _data;
+
+  UnmodifiableByteDataView(ByteData data) : _data = data;
+
+  int getInt8(int byteOffset) => _data.getInt8(byteOffset);
+
+  void setInt8(int byteOffset, int value) => _unsupported();
+
+  int getUint8(int byteOffset) => _data.getUint8(byteOffset);
+
+  void setUint8(int byteOffset, int value) => _unsupported();
+
+  int getInt16(int byteOffset, [Endian endian = Endian.big]) =>
+      _data.getInt16(byteOffset, endian);
+
+  void setInt16(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _unsupported();
+
+  int getUint16(int byteOffset, [Endian endian = Endian.big]) =>
+      _data.getUint16(byteOffset, endian);
+
+  void setUint16(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _unsupported();
+
+  int getInt32(int byteOffset, [Endian endian = Endian.big]) =>
+      _data.getInt32(byteOffset, endian);
+
+  void setInt32(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _unsupported();
+
+  int getUint32(int byteOffset, [Endian endian = Endian.big]) =>
+      _data.getUint32(byteOffset, endian);
+
+  void setUint32(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _unsupported();
+
+  int getInt64(int byteOffset, [Endian endian = Endian.big]) =>
+      _data.getInt64(byteOffset, endian);
+
+  void setInt64(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _unsupported();
+
+  int getUint64(int byteOffset, [Endian endian = Endian.big]) =>
+      _data.getUint64(byteOffset, endian);
+
+  void setUint64(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _unsupported();
+
+  double getFloat32(int byteOffset, [Endian endian = Endian.big]) =>
+      _data.getFloat32(byteOffset, endian);
+
+  void setFloat32(int byteOffset, double value, [Endian endian = Endian.big]) =>
+      _unsupported();
+
+  double getFloat64(int byteOffset, [Endian endian = Endian.big]) =>
+      _data.getFloat64(byteOffset, endian);
+
+  void setFloat64(int byteOffset, double value, [Endian endian = Endian.big]) =>
+      _unsupported();
+
+  int get elementSizeInBytes => _data.elementSizeInBytes;
+
+  int get offsetInBytes => _data.offsetInBytes;
+
+  int get lengthInBytes => _data.lengthInBytes;
+
+  ByteBuffer get buffer => new UnmodifiableByteBufferView(_data.buffer);
+
+  void _unsupported() {
+    throw new UnsupportedError(
+        "An UnmodifiableByteDataView may not be modified");
+  }
+}
+
+abstract class _UnmodifiableListMixin<N, L extends List<N>,
+    TD extends TypedData> {
+  L get _list;
+  TD get _data => (_list as TD);
+
+  int get length => _list.length;
+
+  N operator [](int index) => _list[index];
+
+  int get elementSizeInBytes => _data.elementSizeInBytes;
+
+  int get offsetInBytes => _data.offsetInBytes;
+
+  int get lengthInBytes => _data.lengthInBytes;
+
+  ByteBuffer get buffer => new UnmodifiableByteBufferView(_data.buffer);
+
+  L _createList(int length);
+
+  L sublist(int start, [int end]) {
+    end = RangeError.checkValidRange(start, end, length);
+    int sublistLength = end - start;
+    L result = _createList(sublistLength);
+    result.setRange(0, sublistLength, _list, start);
+    return result;
+  }
+}
+
+/**
+ * View of a [Uint8List] that disallows modification.
+ */
+class UnmodifiableUint8ListView extends UnmodifiableListBase<int>
+    with _UnmodifiableListMixin<int, Uint8List, Uint8List>
+    implements Uint8List {
+  final Uint8List _list;
+  UnmodifiableUint8ListView(Uint8List list) : _list = list;
+
+  Uint8List _createList(int length) => Uint8List(length);
+}
+
+/**
+ * View of a [Int8List] that disallows modification.
+ */
+class UnmodifiableInt8ListView extends UnmodifiableListBase<int>
+    with _UnmodifiableListMixin<int, Int8List, Int8List>
+    implements Int8List {
+  final Int8List _list;
+  UnmodifiableInt8ListView(Int8List list) : _list = list;
+
+  Int8List _createList(int length) => Int8List(length);
+}
+
+/**
+ * View of a [Uint8ClampedList] that disallows modification.
+ */
+class UnmodifiableUint8ClampedListView extends UnmodifiableListBase<int>
+    with _UnmodifiableListMixin<int, Uint8ClampedList, Uint8ClampedList>
+    implements Uint8ClampedList {
+  final Uint8ClampedList _list;
+  UnmodifiableUint8ClampedListView(Uint8ClampedList list) : _list = list;
+
+  Uint8ClampedList _createList(int length) => Uint8ClampedList(length);
+}
+
+/**
+ * View of a [Uint16List] that disallows modification.
+ */
+class UnmodifiableUint16ListView extends UnmodifiableListBase<int>
+    with _UnmodifiableListMixin<int, Uint16List, Uint16List>
+    implements Uint16List {
+  final Uint16List _list;
+  UnmodifiableUint16ListView(Uint16List list) : _list = list;
+
+  Uint16List _createList(int length) => Uint16List(length);
+}
+
+/**
+ * View of a [Int16List] that disallows modification.
+ */
+class UnmodifiableInt16ListView extends UnmodifiableListBase<int>
+    with _UnmodifiableListMixin<int, Int16List, Int16List>
+    implements Int16List {
+  final Int16List _list;
+  UnmodifiableInt16ListView(Int16List list) : _list = list;
+
+  Int16List _createList(int length) => Int16List(length);
+}
+
+/**
+ * View of a [Uint32List] that disallows modification.
+ */
+class UnmodifiableUint32ListView extends UnmodifiableListBase<int>
+    with _UnmodifiableListMixin<int, Uint32List, Uint32List>
+    implements Uint32List {
+  final Uint32List _list;
+  UnmodifiableUint32ListView(Uint32List list) : _list = list;
+
+  Uint32List _createList(int length) => Uint32List(length);
+}
+
+/**
+ * View of a [Int32List] that disallows modification.
+ */
+class UnmodifiableInt32ListView extends UnmodifiableListBase<int>
+    with _UnmodifiableListMixin<int, Int32List, Int32List>
+    implements Int32List {
+  final Int32List _list;
+  UnmodifiableInt32ListView(Int32List list) : _list = list;
+
+  Int32List _createList(int length) => Int32List(length);
+}
+
+/**
+ * View of a [Uint64List] that disallows modification.
+ */
+class UnmodifiableUint64ListView extends UnmodifiableListBase<int>
+    with _UnmodifiableListMixin<int, Uint64List, Uint64List>
+    implements Uint64List {
+  final Uint64List _list;
+  UnmodifiableUint64ListView(Uint64List list) : _list = list;
+
+  Uint64List _createList(int length) => Uint64List(length);
+}
+
+/**
+ * View of a [Int64List] that disallows modification.
+ */
+class UnmodifiableInt64ListView extends UnmodifiableListBase<int>
+    with _UnmodifiableListMixin<int, Int64List, Int64List>
+    implements Int64List {
+  final Int64List _list;
+  UnmodifiableInt64ListView(Int64List list) : _list = list;
+
+  Int64List _createList(int length) => Int64List(length);
+}
+
+/**
+ * View of a [Int32x4List] that disallows modification.
+ */
+class UnmodifiableInt32x4ListView extends UnmodifiableListBase<Int32x4>
+    with _UnmodifiableListMixin<Int32x4, Int32x4List, Int32x4List>
+    implements Int32x4List {
+  final Int32x4List _list;
+  UnmodifiableInt32x4ListView(Int32x4List list) : _list = list;
+
+  Int32x4List _createList(int length) => Int32x4List(length);
+}
+
+/**
+ * View of a [Float32x4List] that disallows modification.
+ */
+class UnmodifiableFloat32x4ListView extends UnmodifiableListBase<Float32x4>
+    with _UnmodifiableListMixin<Float32x4, Float32x4List, Float32x4List>
+    implements Float32x4List {
+  final Float32x4List _list;
+  UnmodifiableFloat32x4ListView(Float32x4List list) : _list = list;
+
+  Float32x4List _createList(int length) => Float32x4List(length);
+}
+
+/**
+ * View of a [Float64x2List] that disallows modification.
+ */
+class UnmodifiableFloat64x2ListView extends UnmodifiableListBase<Float64x2>
+    with _UnmodifiableListMixin<Float64x2, Float64x2List, Float64x2List>
+    implements Float64x2List {
+  final Float64x2List _list;
+  UnmodifiableFloat64x2ListView(Float64x2List list) : _list = list;
+
+  Float64x2List _createList(int length) => Float64x2List(length);
+}
+
+/**
+ * View of a [Float32List] that disallows modification.
+ */
+class UnmodifiableFloat32ListView extends UnmodifiableListBase<double>
+    with _UnmodifiableListMixin<double, Float32List, Float32List>
+    implements Float32List {
+  final Float32List _list;
+  UnmodifiableFloat32ListView(Float32List list) : _list = list;
+
+  Float32List _createList(int length) => Float32List(length);
+}
+
+/**
+ * View of a [Float64List] that disallows modification.
+ */
+class UnmodifiableFloat64ListView extends UnmodifiableListBase<double>
+    with _UnmodifiableListMixin<double, Float64List, Float64List>
+    implements Float64List {
+  final Float64List _list;
+  UnmodifiableFloat64ListView(Float64List list) : _list = list;
+
+  Float64List _createList(int length) => Float64List(length);
+}
diff --git a/sdk_nnbd/lib/vmservice/asset.dart b/sdk_nnbd/lib/vmservice/asset.dart
new file mode 100644
index 0000000..d5772e2
--- /dev/null
+++ b/sdk_nnbd/lib/vmservice/asset.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart._vmservice;
+
+class Asset {
+  final String name;
+  final Uint8List data;
+
+  Asset(this.name, this.data);
+
+  String get mimeType {
+    var extensionStart = name.lastIndexOf('.');
+    var extension = name.substring(extensionStart + 1);
+    switch (extension) {
+      case 'html':
+        return 'text/html; charset=UTF-8';
+      case 'dart':
+        return 'application/dart; charset=UTF-8';
+      case 'js':
+        return 'application/javascript; charset=UTF-8';
+      case 'css':
+        return 'text/css; charset=UTF-8';
+      case 'gif':
+        return 'image/gif';
+      case 'png':
+        return 'image/png';
+      case 'jpg':
+        return 'image/jpeg';
+      case 'jpeg':
+        return 'image/jpeg';
+      case 'svg':
+        return 'image/svg+xml';
+      default:
+        return 'text/plain';
+    }
+  }
+
+  static Map<String, Asset> request() {
+    Uint8List tarBytes = _requestAssets();
+    if (tarBytes == null) {
+      return null;
+    }
+    List assetList = _decodeAssets(tarBytes);
+    Map<String, Asset> assets = new HashMap<String, Asset>();
+    for (int i = 0; i < assetList.length; i += 2) {
+      var a = new Asset(assetList[i], assetList[i + 1]);
+      assets[a.name] = a;
+    }
+    return assets;
+  }
+
+  String toString() => '$name ($mimeType)';
+}
+
+List _decodeAssets(Uint8List data) native "VMService_DecodeAssets";
+
+Map<String, Asset> _assets;
+Map<String, Asset> get assets {
+  if (_assets == null) {
+    try {
+      _assets = Asset.request();
+    } catch (e) {
+      print('Could not load Observatory assets: $e');
+    }
+  }
+  return _assets;
+}
diff --git a/sdk_nnbd/lib/vmservice/client.dart b/sdk_nnbd/lib/vmservice/client.dart
new file mode 100644
index 0000000..efe33c0
--- /dev/null
+++ b/sdk_nnbd/lib/vmservice/client.dart
@@ -0,0 +1,65 @@
+// 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 dart._vmservice;
+
+typedef void ClientServiceHandle(Message response);
+
+// A service client.
+abstract class Client {
+  final VMService service;
+  final bool sendEvents;
+
+  /// A set streamIds which describes the streams the client is connected to
+  final Set<String> streams = new Set<String>();
+
+  /// Services registered and their aliases
+  /// key: service
+  /// value: alias
+  final Map<String, String> services = new Map<String, String>();
+
+  /// Callbacks registered for service invocations set to the client
+  /// key: RPC id used for the request
+  /// value: callback that should be invoked
+  final Map<String, ClientServiceHandle> serviceHandles =
+      new Map<String, ClientServiceHandle>();
+
+  Client(this.service, {bool sendEvents: true}) : this.sendEvents = sendEvents {
+    service._addClient(this);
+  }
+
+  // Disconnects the client.
+  disconnect();
+
+  /// When implementing, call [close] when the network connection closes.
+  void close() {
+    service._removeClient(this);
+  }
+
+  /// Call to process a request. Response will be posted with 'seq'.
+  void onRequest(Message message) {
+    // In JSON-RPC 2.0 messages with and id are Request and must be answered
+    // http://www.jsonrpc.org/specification#notification
+    service.routeRequest(service, message).then(post);
+  }
+
+  void onResponse(Message message) {
+    service.routeResponse(message);
+  }
+
+  /// Call to process a notification. Response will not be posted.
+  void onNotification(Message message) {
+    // In JSON-RPC 2.0 messages without an id are Notification
+    // and should not be answered
+    // http://www.jsonrpc.org/specification#notification
+    service.routeRequest(service, message);
+  }
+
+  // Sends a result to the client.  Implemented in subclasses.
+  void post(Response result);
+
+  dynamic toJson() {
+    return {};
+  }
+}
diff --git a/sdk_nnbd/lib/vmservice/constants.dart b/sdk_nnbd/lib/vmservice/constants.dart
new file mode 100644
index 0000000..914576b
--- /dev/null
+++ b/sdk_nnbd/lib/vmservice/constants.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.
+
+part of dart._vmservice;
+
+// These must be kept in sync with runtime/vm/service.cc.
+class Constants {
+  static const int SERVICE_EXIT_MESSAGE_ID = 0;
+  static const int ISOLATE_STARTUP_MESSAGE_ID = 1;
+  static const int ISOLATE_SHUTDOWN_MESSAGE_ID = 2;
+  static const int WEB_SERVER_CONTROL_MESSAGE_ID = 3;
+  static const int SERVER_INFO_MESSAGE_ID = 4;
+
+  /// Signals an RPC coming from native code (instead of from a websocket
+  /// connection).  These calls are limited to simple request-response and do
+  /// not allow arbitrary json-rpc messages.
+  ///
+  /// The messages are an array of length 3:
+  ///   (METHOD_CALL_FROM_NATIVE, String jsonRequest, PortId replyPort).
+  static const int METHOD_CALL_FROM_NATIVE = 5;
+}
diff --git a/sdk_nnbd/lib/vmservice/devfs.dart b/sdk_nnbd/lib/vmservice/devfs.dart
new file mode 100644
index 0000000..20e0573
--- /dev/null
+++ b/sdk_nnbd/lib/vmservice/devfs.dart
@@ -0,0 +1,399 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart._vmservice;
+
+String _encodeDevFSDisabledError(Message message) {
+  return encodeRpcError(message, kFeatureDisabled,
+      details: "DevFS is not supported by this Dart implementation");
+}
+
+String _encodeFileSystemAlreadyExistsError(Message message, String fsName) {
+  return encodeRpcError(message, kFileSystemAlreadyExists,
+      details: "${message.method}: file system '${fsName}' already exists");
+}
+
+String _encodeFileSystemDoesNotExistError(Message message, String fsName) {
+  return encodeRpcError(message, kFileSystemDoesNotExist,
+      details: "${message.method}: file system '${fsName}' does not exist");
+}
+
+class _FileSystem {
+  _FileSystem(this.name, this.uri);
+
+  final String name;
+  final Uri uri;
+
+  Uri resolvePath(String path) {
+    if (path.startsWith('/')) {
+      path = path.substring(1);
+    }
+    if (path.isEmpty) {
+      return null;
+    }
+    Uri pathUri;
+    try {
+      pathUri = new Uri.file(path);
+    } on FormatException catch (e) {
+      return null;
+    }
+
+    return resolve(pathUri);
+  }
+
+  Uri resolve(Uri pathUri) {
+    try {
+      // Make sure that this pathUri can be converted to a file path.
+      pathUri.toFilePath();
+    } on UnsupportedError catch (e) {
+      return null;
+    }
+
+    Uri resolvedUri = uri.resolveUri(pathUri);
+    if (!resolvedUri.toString().startsWith(uri.toString())) {
+      // Resolved uri must be within the filesystem's base uri.
+      return null;
+    }
+    return resolvedUri;
+  }
+
+  Map toMap() {
+    return {
+      'type': 'FileSystem',
+      'name': name,
+      'uri': uri.toString(),
+    };
+  }
+}
+
+class DevFS {
+  DevFS();
+
+  Map<String, _FileSystem> _fsMap = {};
+
+  final Set _rpcNames = new Set.from([
+    '_listDevFS',
+    '_createDevFS',
+    '_deleteDevFS',
+    '_readDevFSFile',
+    '_writeDevFSFile',
+    '_writeDevFSFiles',
+    '_listDevFSFiles',
+  ]);
+
+  void cleanup() {
+    var deleteDir = VMServiceEmbedderHooks.deleteDir;
+    if (deleteDir == null) {
+      return;
+    }
+    var deletions = <Future>[];
+    for (var fs in _fsMap.values) {
+      deletions.add(deleteDir(fs.uri));
+    }
+    Future.wait(deletions);
+    _fsMap.clear();
+  }
+
+  bool shouldHandleMessage(Message message) {
+    return _rpcNames.contains(message.method);
+  }
+
+  Future<String> handleMessage(Message message) async {
+    switch (message.method) {
+      case '_listDevFS':
+        return _listDevFS(message);
+      case '_createDevFS':
+        return _createDevFS(message);
+      case '_deleteDevFS':
+        return _deleteDevFS(message);
+      case '_readDevFSFile':
+        return _readDevFSFile(message);
+      case '_writeDevFSFile':
+        return _writeDevFSFile(message);
+      case '_writeDevFSFiles':
+        return _writeDevFSFiles(message);
+      case '_listDevFSFiles':
+        return _listDevFSFiles(message);
+      default:
+        return encodeRpcError(message, kInternalError,
+            details: 'Unexpected rpc ${message.method}');
+    }
+  }
+
+  Future<String> handlePutStream(
+      Object fsName, Object path, Uri fsUri, Stream<List<int>> bytes) async {
+    // A dummy Message for error message construction.
+    Message message = new Message.forMethod('_writeDevFSFile');
+    var writeStreamFile = VMServiceEmbedderHooks.writeStreamFile;
+    if (writeStreamFile == null) {
+      return _encodeDevFSDisabledError(message);
+    }
+    if (fsName == null) {
+      return encodeMissingParamError(message, 'fsName');
+    }
+    if (fsName is! String) {
+      return encodeInvalidParamError(message, 'fsName');
+    }
+    var fs = _fsMap[fsName];
+    if (fs == null) {
+      return _encodeFileSystemDoesNotExistError(message, fsName);
+    }
+    Uri uri = fsUri;
+    if (uri == null) {
+      if (path == null) {
+        return encodeMissingParamError(message, 'path');
+      }
+      if (path is! String) {
+        return encodeInvalidParamError(message, 'path');
+      }
+      uri = fs.resolvePath(path);
+      if (uri == null) {
+        return encodeInvalidParamError(message, 'path');
+      }
+    } else {
+      uri = fs.resolve(uri);
+      if (uri == null) {
+        return encodeInvalidParamError(message, 'uri');
+      }
+    }
+    await writeStreamFile(uri, bytes);
+    return encodeSuccess(message);
+  }
+
+  Future<String> _listDevFS(Message message) async {
+    var result = {};
+    result['type'] = 'FileSystemList';
+    result['fsNames'] = _fsMap.keys.toList();
+    return encodeResult(message, result);
+  }
+
+  Future<String> _createDevFS(Message message) async {
+    var createTempDir = VMServiceEmbedderHooks.createTempDir;
+    if (createTempDir == null) {
+      return _encodeDevFSDisabledError(message);
+    }
+    var fsName = message.params['fsName'];
+    if (fsName == null) {
+      return encodeMissingParamError(message, 'fsName');
+    }
+    if (fsName is! String) {
+      return encodeInvalidParamError(message, 'fsName');
+    }
+    var fs = _fsMap[fsName];
+    if (fs != null) {
+      return _encodeFileSystemAlreadyExistsError(message, fsName);
+    }
+    var tempDir = await createTempDir(fsName);
+    fs = new _FileSystem(fsName, tempDir);
+    _fsMap[fsName] = fs;
+    return encodeResult(message, fs.toMap());
+  }
+
+  Future<String> _deleteDevFS(Message message) async {
+    var deleteDir = VMServiceEmbedderHooks.deleteDir;
+    if (deleteDir == null) {
+      return _encodeDevFSDisabledError(message);
+    }
+    var fsName = message.params['fsName'];
+    if (fsName == null) {
+      return encodeMissingParamError(message, 'fsName');
+    }
+    if (fsName is! String) {
+      return encodeInvalidParamError(message, 'fsName');
+    }
+    var fs = _fsMap.remove(fsName);
+    if (fs == null) {
+      return _encodeFileSystemDoesNotExistError(message, fsName);
+    }
+    await deleteDir(fs.uri);
+    return encodeSuccess(message);
+  }
+
+  Future<String> _readDevFSFile(Message message) async {
+    var readFile = VMServiceEmbedderHooks.readFile;
+    if (readFile == null) {
+      return _encodeDevFSDisabledError(message);
+    }
+    var fsName = message.params['fsName'];
+    if (fsName == null) {
+      return encodeMissingParamError(message, 'fsName');
+    }
+    if (fsName is! String) {
+      return encodeInvalidParamError(message, 'fsName');
+    }
+    var fs = _fsMap[fsName];
+    if (fs == null) {
+      return _encodeFileSystemDoesNotExistError(message, fsName);
+    }
+    Uri uri;
+    if (message.params['uri'] != null) {
+      try {
+        var uriParam = message.params['uri'];
+        if (uriParam is! String) {
+          return encodeInvalidParamError(message, 'uri');
+        }
+        Uri parsedUri = Uri.parse(uriParam);
+        uri = fs.resolve(parsedUri);
+        if (uri == null) {
+          return encodeInvalidParamError(message, 'uri');
+        }
+      } catch (e) {
+        return encodeInvalidParamError(message, 'uri');
+      }
+    } else {
+      var path = message.params['path'];
+      if (path == null) {
+        return encodeMissingParamError(message, 'path');
+      }
+      if (path is! String) {
+        return encodeInvalidParamError(message, 'path');
+      }
+      uri = fs.resolvePath(path);
+      if (uri == null) {
+        return encodeInvalidParamError(message, 'path');
+      }
+    }
+    try {
+      List<int> bytes = await readFile(uri);
+      var result = {'type': 'FSFile', 'fileContents': base64.encode(bytes)};
+      return encodeResult(message, result);
+    } catch (e) {
+      return encodeRpcError(message, kFileDoesNotExist,
+          details: "_readDevFSFile: $e");
+    }
+  }
+
+  Future<String> _writeDevFSFile(Message message) async {
+    var writeFile = VMServiceEmbedderHooks.writeFile;
+    if (writeFile == null) {
+      return _encodeDevFSDisabledError(message);
+    }
+    var fsName = message.params['fsName'];
+    if (fsName == null) {
+      return encodeMissingParamError(message, 'fsName');
+    }
+    if (fsName is! String) {
+      return encodeInvalidParamError(message, 'fsName');
+    }
+    var fs = _fsMap[fsName];
+    if (fs == null) {
+      return _encodeFileSystemDoesNotExistError(message, fsName);
+    }
+    Uri uri;
+    if (message.params['uri'] != null) {
+      try {
+        var uriParam = message.params['uri'];
+        if (uriParam is! String) {
+          return encodeInvalidParamError(message, 'uri');
+        }
+        Uri parsedUri = Uri.parse(uriParam);
+        uri = fs.resolve(parsedUri);
+        if (uri == null) {
+          return encodeInvalidParamError(message, 'uri');
+        }
+      } catch (e) {
+        return encodeInvalidParamError(message, 'uri');
+      }
+    } else {
+      var path = message.params['path'];
+      if (path == null) {
+        return encodeMissingParamError(message, 'path');
+      }
+      if (path is! String) {
+        return encodeInvalidParamError(message, 'path');
+      }
+      uri = fs.resolvePath(path);
+      if (uri == null) {
+        return encodeInvalidParamError(message, 'path');
+      }
+    }
+    var fileContents = message.params['fileContents'];
+    if (fileContents == null) {
+      return encodeMissingParamError(message, 'fileContents');
+    }
+    if (fileContents is! String) {
+      return encodeInvalidParamError(message, 'fileContents');
+    }
+    List<int> decodedFileContents = base64.decode(fileContents);
+
+    await writeFile(uri, decodedFileContents);
+    return encodeSuccess(message);
+  }
+
+  Future<String> _writeDevFSFiles(Message message) async {
+    var writeFile = VMServiceEmbedderHooks.writeFile;
+    if (writeFile == null) {
+      return _encodeDevFSDisabledError(message);
+    }
+    var fsName = message.params['fsName'];
+    if (fsName == null) {
+      return encodeMissingParamError(message, 'fsName');
+    }
+    if (fsName is! String) {
+      return encodeInvalidParamError(message, 'fsName');
+    }
+    var fs = _fsMap[fsName];
+    if (fs == null) {
+      return _encodeFileSystemDoesNotExistError(message, fsName);
+    }
+    var files = message.params['files'];
+    if (files == null) {
+      return encodeMissingParamError(message, 'files');
+    }
+    if (files is! List) {
+      return encodeInvalidParamError(message, 'files');
+    }
+    var uris = [];
+    for (int i = 0; i < files.length; i++) {
+      var fileInfo = files[i];
+      if (fileInfo is! List ||
+          fileInfo.length != 2 ||
+          fileInfo[0] is! String ||
+          fileInfo[1] is! String) {
+        return encodeRpcError(message, kInvalidParams,
+            details: "${message.method}: invalid 'files' parameter "
+                "at index ${i}: ${fileInfo}");
+      }
+      var uri = fs.resolvePath(fileInfo[0]);
+      if (uri == null) {
+        return encodeRpcError(message, kInvalidParams,
+            details: "${message.method}: invalid 'files' parameter "
+                "at index ${i}: ${fileInfo}");
+      }
+      uris.add(uri);
+    }
+    var pendingWrites = <Future>[];
+    for (int i = 0; i < uris.length; i++) {
+      List<int> decodedFileContents = base64.decode(files[i][1]);
+      pendingWrites.add(writeFile(uris[i], decodedFileContents));
+    }
+    await Future.wait(pendingWrites);
+    return encodeSuccess(message);
+  }
+
+  Future<String> _listDevFSFiles(Message message) async {
+    var listFiles = VMServiceEmbedderHooks.listFiles;
+    if (listFiles == null) {
+      return _encodeDevFSDisabledError(message);
+    }
+    var fsName = message.params['fsName'];
+    if (fsName == null) {
+      return encodeMissingParamError(message, 'fsName');
+    }
+    if (fsName is! String) {
+      return encodeInvalidParamError(message, 'fsName');
+    }
+    var fs = _fsMap[fsName];
+    if (fs == null) {
+      return _encodeFileSystemDoesNotExistError(message, fsName);
+    }
+    var fileList = await listFiles(fs.uri);
+    // Remove any url-encoding in the filenames.
+    for (int i = 0; i < fileList.length; i++) {
+      fileList[i]['name'] = Uri.decodeFull(fileList[i]['name']);
+    }
+    var result = {'type': 'FSFileList', 'files': fileList};
+    return encodeResult(message, result);
+  }
+}
diff --git a/sdk_nnbd/lib/vmservice/message.dart b/sdk_nnbd/lib/vmservice/message.dart
new file mode 100644
index 0000000..9e4375a
--- /dev/null
+++ b/sdk_nnbd/lib/vmservice/message.dart
@@ -0,0 +1,267 @@
+// 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 dart._vmservice;
+
+enum MessageType { Request, Notification, Response }
+
+class Message {
+  final Completer<Response> _completer = new Completer<Response>.sync();
+  bool get completed => _completer.isCompleted;
+
+  /// Future of response.
+  Future<Response> get response => _completer.future;
+  Client client;
+
+  // Is a notification message (no serial)
+  final MessageType type;
+
+  // Client-side identifier for this message.
+  final serial;
+
+  final String method;
+
+  final Map params = new Map();
+  final Map result = new Map();
+  final Map error = new Map();
+
+  factory Message.fromJsonRpc(Client client, Map map) {
+    if (map.containsKey('id')) {
+      final id = map['id'];
+      if (id != null && id is! num && id is! String) {
+        throw new Exception('"id" must be a number, string, or null.');
+      }
+      if (map.containsKey('method')) {
+        return new Message._fromJsonRpcRequest(client, map);
+      }
+      if (map.containsKey('result')) {
+        return new Message._fromJsonRpcResult(client, map);
+      }
+      if (map.containsKey('error')) {
+        return new Message._fromJsonRpcError(client, map);
+      }
+    } else if (map.containsKey('method')) {
+      return new Message._fromJsonRpcNotification(client, map);
+    }
+    throw new Exception('Invalid message format');
+  }
+
+  // http://www.jsonrpc.org/specification#request_object
+  Message._fromJsonRpcRequest(Client client, Map map)
+      : client = client,
+        type = MessageType.Request,
+        serial = map['id'],
+        method = map['method'] {
+    if (map['params'] != null) {
+      params.addAll(map['params']);
+    }
+  }
+
+  // http://www.jsonrpc.org/specification#notification
+  Message._fromJsonRpcNotification(Client client, Map map)
+      : client = client,
+        type = MessageType.Notification,
+        method = map['method'],
+        serial = null {
+    if (map['params'] != null) {
+      params.addAll(map['params']);
+    }
+  }
+
+  // http://www.jsonrpc.org/specification#response_object
+  Message._fromJsonRpcResult(Client client, Map map)
+      : client = client,
+        type = MessageType.Response,
+        serial = map['id'],
+        method = null {
+    result.addAll(map['result']);
+  }
+
+  // http://www.jsonrpc.org/specification#response_object
+  Message._fromJsonRpcError(Client client, Map map)
+      : client = client,
+        type = MessageType.Response,
+        serial = map['id'],
+        method = null {
+    error.addAll(map['error']);
+  }
+
+  static String _methodNameFromUri(Uri uri) {
+    if (uri == null) {
+      return '';
+    }
+    if (uri.pathSegments.length == 0) {
+      return '';
+    }
+    return uri.pathSegments[0];
+  }
+
+  Message.forMethod(String method)
+      : client = null,
+        method = method,
+        type = MessageType.Request,
+        serial = '';
+
+  Message.fromUri(this.client, Uri uri)
+      : type = MessageType.Request,
+        serial = '',
+        method = _methodNameFromUri(uri) {
+    params.addAll(uri.queryParameters);
+  }
+
+  Message.forIsolate(this.client, Uri uri, RunningIsolate isolate)
+      : type = MessageType.Request,
+        serial = '',
+        method = _methodNameFromUri(uri) {
+    params.addAll(uri.queryParameters);
+    params['isolateId'] = isolate.serviceId;
+  }
+
+  Uri toUri() {
+    return new Uri(path: method, queryParameters: params);
+  }
+
+  dynamic toJson() {
+    throw 'unsupported';
+  }
+
+  dynamic forwardToJson([Map overloads]) {
+    Map<dynamic, dynamic> json = {'jsonrpc': '2.0', 'id': serial};
+    switch (type) {
+      case MessageType.Request:
+      case MessageType.Notification:
+        json['method'] = method;
+        if (params.isNotEmpty) {
+          json['params'] = params;
+        }
+        break;
+      case MessageType.Response:
+        if (result.isNotEmpty) {
+          json['result'] = result;
+        }
+        if (error.isNotEmpty) {
+          json['error'] = error;
+        }
+    }
+    if (overloads != null) {
+      json.addAll(overloads);
+    }
+    return json;
+  }
+
+  // Calls toString on all non-String elements of [list]. We do this so all
+  // elements in the list are strings, making consumption by C++ simpler.
+  // This has a side effect that boolean literal values like true become 'true'
+  // and thus indistinguishable from the string literal 'true'.
+  List<String> _makeAllString(List list) {
+    if (list == null) {
+      return null;
+    }
+    var new_list = new List<String>(list.length);
+    for (var i = 0; i < list.length; i++) {
+      new_list[i] = list[i].toString();
+    }
+    return new_list;
+  }
+
+  Future<Response> sendToIsolate(SendPort sendPort) {
+    final receivePort = new RawReceivePort();
+    receivePort.handler = (value) {
+      receivePort.close();
+      _setResponseFromPort(value);
+    };
+    var keys = _makeAllString(params.keys.toList(growable: false));
+    var values = _makeAllString(params.values.toList(growable: false));
+    var request = new List(6)
+      ..[0] = 0 // Make room for OOB message type.
+      ..[1] = receivePort.sendPort
+      ..[2] = serial
+      ..[3] = method
+      ..[4] = keys
+      ..[5] = values;
+    if (!sendIsolateServiceMessage(sendPort, request)) {
+      receivePort.close();
+      _completer.complete(new Response.internalError(
+          'could not send message [${serial}] to isolate'));
+    }
+    return _completer.future;
+  }
+
+  // We currently support two ways of passing parameters from Dart code to C
+  // code. The original way always converts the parameters to strings before
+  // passing them over. Our goal is to convert all C handlers to take the
+  // parameters as Dart objects but until the conversion is complete, we
+  // maintain the list of supported methods below.
+  bool _methodNeedsObjectParameters(String method) {
+    switch (method) {
+      case '_listDevFS':
+      case '_listDevFSFiles':
+      case '_createDevFS':
+      case '_deleteDevFS':
+      case '_writeDevFSFile':
+      case '_writeDevFSFiles':
+      case '_readDevFSFile':
+      case '_spawnUri':
+        return true;
+      default:
+        return false;
+    }
+  }
+
+  Future<Response> sendToVM() {
+    final receivePort = new RawReceivePort();
+    receivePort.handler = (value) {
+      receivePort.close();
+      _setResponseFromPort(value);
+    };
+    var keys = params.keys.toList(growable: false);
+    var values = params.values.toList(growable: false);
+    if (!_methodNeedsObjectParameters(method)) {
+      keys = _makeAllString(keys);
+      values = _makeAllString(values);
+    }
+
+    final request = new List(6)
+      ..[0] = 0 // Make room for OOB message type.
+      ..[1] = receivePort.sendPort
+      ..[2] = serial
+      ..[3] = method
+      ..[4] = keys
+      ..[5] = values;
+
+    if (_methodNeedsObjectParameters(method)) {
+      // We use a different method invocation path here.
+      sendObjectRootServiceMessage(request);
+    } else {
+      sendRootServiceMessage(request);
+    }
+
+    return _completer.future;
+  }
+
+  void _setResponseFromPort(dynamic response) {
+    if (response == null) {
+      // We should only have a null response for Notifications.
+      assert(type == MessageType.Notification);
+      return null;
+    }
+    _completer.complete(Response.from(response));
+  }
+
+  void setResponse(String response) {
+    _completer.complete(new Response(ResponsePayloadKind.String, response));
+  }
+
+  void setErrorResponse(int code, String details) {
+    setResponse(encodeRpcError(this, code, details: '$method: $details'));
+  }
+}
+
+bool sendIsolateServiceMessage(SendPort sp, List m)
+    native "VMService_SendIsolateServiceMessage";
+
+void sendRootServiceMessage(List m) native "VMService_SendRootServiceMessage";
+
+void sendObjectRootServiceMessage(List m)
+    native "VMService_SendObjectRootServiceMessage";
diff --git a/sdk_nnbd/lib/vmservice/message_router.dart b/sdk_nnbd/lib/vmservice/message_router.dart
new file mode 100644
index 0000000..4c1b307
--- /dev/null
+++ b/sdk_nnbd/lib/vmservice/message_router.dart
@@ -0,0 +1,85 @@
+// 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 dart._vmservice;
+
+abstract class MessageRouter {
+  Future<Response> routeRequest(VMService service, Message message);
+  void routeResponse(Message message);
+}
+
+enum ResponsePayloadKind {
+  /// Response payload is a Dart string.
+  String,
+
+  /// Response payload is a binary (Uint8List).
+  Binary,
+
+  /// Response payload is a string encoded as UTF8 bytes (Uint8List).
+  Utf8String,
+}
+
+class Response {
+  final ResponsePayloadKind kind;
+  final payload;
+
+  /// Construct response object with the given [payload] and [kind].
+  Response(this.kind, this.payload) {
+    assert(() {
+      switch (kind) {
+        case ResponsePayloadKind.String:
+          return payload is String;
+        case ResponsePayloadKind.Binary:
+        case ResponsePayloadKind.Utf8String:
+          return payload is Uint8List;
+      }
+    }());
+  }
+
+  /// Construct a string response from the given [value] by encoding it
+  /// as JSON.
+  Response.json(Object value)
+      : this(ResponsePayloadKind.String, json.encode(value));
+
+  factory Response.internalError(String message) {
+    return new Response.json({
+      'type': 'ServiceError',
+      'id': '',
+      'kind': 'InternalError',
+      'message': message,
+    });
+  }
+
+  /// Construct response from the response [value] which can be either:
+  ///     String: a string
+  ///     Binary: a Uint8List
+  ///     Utf8String: a single element list containing Uint8List
+  factory Response.from(Object value) {
+    if (value is String) {
+      return new Response(ResponsePayloadKind.String, value);
+    } else if (value is Uint8List) {
+      return new Response(ResponsePayloadKind.Binary, value);
+    } else if (value is List) {
+      assert(value.length == 1);
+      return new Response(
+          ResponsePayloadKind.Utf8String, value[0] as Uint8List);
+    } else if (value is Response) {
+      return value;
+    } else {
+      throw 'Unrecognized response: ${value}';
+    }
+  }
+
+  /// Decode JSON contained in this response.
+  dynamic decodeJson() {
+    switch (kind) {
+      case ResponsePayloadKind.String:
+        return json.decode(payload);
+      case ResponsePayloadKind.Utf8String:
+        return json.fuse(utf8).decode(payload);
+      case ResponsePayloadKind.Binary:
+        throw 'Binary responses can not be decoded';
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/vmservice/named_lookup.dart b/sdk_nnbd/lib/vmservice/named_lookup.dart
new file mode 100644
index 0000000..7087c94
--- /dev/null
+++ b/sdk_nnbd/lib/vmservice/named_lookup.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart._vmservice;
+
+/// Set like containes which automatically generated String ids for its items
+class NamedLookup<E> extends Object with IterableMixin<E> {
+  final IdGenerator _generator;
+  final Map<String, E> _elements = new Map<String, E>();
+  final Map<E, String> _ids = new Map<E, String>();
+
+  NamedLookup({String prologue = ''})
+      : _generator = new IdGenerator(prologue: prologue);
+
+  void add(E e) {
+    final id = _generator.newId();
+    _elements[id] = e;
+    _ids[e] = id;
+  }
+
+  void remove(E e) {
+    final id = _ids.remove(e);
+    _elements.remove(id);
+    _generator.release(id);
+  }
+
+  E operator [](String id) => _elements[id];
+  String keyOf(E e) => _ids[e];
+
+  Iterator<E> get iterator => _ids.keys.iterator;
+}
+
+/// Generator for unique ids which recycles expired ones
+class IdGenerator {
+  /// Fixed initial part of the id
+  final String prologue;
+  // Ids in use
+  final Set<String> _used = new Set<String>();
+
+  /// Ids that has been released (use these before generate new ones)
+  final Set<String> _free = new Set<String>();
+
+  /// Next id to generate if no one can be recycled (first use _free);
+  int _next = 0;
+
+  IdGenerator({this.prologue = ''});
+
+  /// Returns a new Id (possibly recycled)
+  String newId() {
+    var id;
+    if (_free.isEmpty) {
+      id = prologue + (_next++).toString();
+    } else {
+      id = _free.first;
+    }
+    _free.remove(id);
+    _used.add(id);
+    return id;
+  }
+
+  /// Releases the id and mark it for recycle
+  void release(String id) {
+    if (_used.remove(id)) {
+      _free.add(id);
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/vmservice/running_isolate.dart b/sdk_nnbd/lib/vmservice/running_isolate.dart
new file mode 100644
index 0000000..8a6dd36
--- /dev/null
+++ b/sdk_nnbd/lib/vmservice/running_isolate.dart
@@ -0,0 +1,24 @@
+// 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 dart._vmservice;
+
+class RunningIsolate implements MessageRouter {
+  final int portId;
+  final SendPort sendPort;
+  final String name;
+
+  RunningIsolate(this.portId, this.sendPort, this.name);
+
+  String get serviceId => 'isolates/$portId';
+
+  @override
+  Future<Response> routeRequest(VMService service, Message message) {
+    // Send message to isolate.
+    return message.sendToIsolate(sendPort);
+  }
+
+  @override
+  void routeResponse(Message message) {}
+}
diff --git a/sdk_nnbd/lib/vmservice/running_isolates.dart b/sdk_nnbd/lib/vmservice/running_isolates.dart
new file mode 100644
index 0000000..24b155c
--- /dev/null
+++ b/sdk_nnbd/lib/vmservice/running_isolates.dart
@@ -0,0 +1,214 @@
+// 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 dart._vmservice;
+
+class RunningIsolates implements MessageRouter {
+  final Map<int, RunningIsolate> isolates = new Map<int, RunningIsolate>();
+  int _rootPortId;
+
+  RunningIsolates();
+
+  void isolateStartup(int portId, SendPort sp, String name) {
+    if (_rootPortId == null) {
+      _rootPortId = portId;
+    }
+    var ri = new RunningIsolate(portId, sp, name);
+    isolates[portId] = ri;
+  }
+
+  void isolateShutdown(int portId, SendPort sp) {
+    if (_rootPortId == portId) {
+      _rootPortId = null;
+    }
+    isolates.remove(portId);
+  }
+
+  @override
+  Future<Response> routeRequest(VMService service, Message message) {
+    String isolateParam = message.params['isolateId'];
+    int isolateId;
+    if (!isolateParam.startsWith('isolates/')) {
+      message.setErrorResponse(
+          kInvalidParams, "invalid 'isolateId' parameter: $isolateParam");
+      return message.response;
+    }
+    isolateParam = isolateParam.substring('isolates/'.length);
+    if (isolateParam == 'root') {
+      isolateId = _rootPortId;
+    } else {
+      try {
+        isolateId = int.parse(isolateParam);
+      } catch (e) {
+        message.setErrorResponse(
+            kInvalidParams, "invalid 'isolateId' parameter: $isolateParam");
+        return message.response;
+      }
+    }
+    var isolate = isolates[isolateId];
+    if (isolate == null) {
+      // There is some chance that this isolate may have lived before,
+      // so return a sentinel rather than an error.
+      var result = {
+        'type': 'Sentinel',
+        'kind': 'Collected',
+        'valueAsString': '<collected>',
+      };
+      message.setResponse(encodeResult(message, result));
+      return message.response;
+    }
+
+    if (message.method == 'evaluateInFrame' || message.method == 'evaluate') {
+      return new _Evaluator(message, isolate, service).run();
+    } else {
+      return isolate.routeRequest(service, message);
+    }
+  }
+
+  @override
+  void routeResponse(Message message) {}
+}
+
+/// Class that knows how to orchestrate expression evaluation in dart2 world.
+class _Evaluator {
+  _Evaluator(this._message, this._isolate, this._service);
+
+  Future<Response> run() async {
+    Response buildScopeResponse = await _buildScope();
+    Map<String, dynamic> responseJson = buildScopeResponse.decodeJson();
+
+    if (responseJson.containsKey('error')) {
+      return new Response.from(encodeCompilationError(
+          _message, responseJson['error']['data']['details']));
+    }
+
+    String kernelBase64;
+    try {
+      kernelBase64 = await _compileExpression(responseJson['result']);
+    } catch (e) {
+      return new Response.from(encodeCompilationError(_message, e.toString()));
+    }
+    return _evaluateCompiledExpression(kernelBase64);
+  }
+
+  Message _message;
+  RunningIsolate _isolate;
+  VMService _service;
+
+  Future<Response> _buildScope() {
+    Map<String, dynamic> params = _setupParams();
+    params['isolateId'] = _message.params['isolateId'];
+    Map buildScopeParams = {
+      'method': '_buildExpressionEvaluationScope',
+      'id': _message.serial,
+      'params': params,
+    };
+    if (_message.params['scope'] != null) {
+      buildScopeParams['params']['scope'] = _message.params['scope'];
+    }
+    var buildScope =
+        new Message._fromJsonRpcRequest(_message.client, buildScopeParams);
+
+    // Decode the JSON and and insert it into the map. The map key
+    // is the request Uri.
+    return _isolate.routeRequest(_service, buildScope);
+  }
+
+  Future<String> _compileExpression(
+      Map<String, dynamic> buildScopeResponseResult) {
+    Client externalClient =
+        _service._findFirstClientThatHandlesService('compileExpression');
+
+    Map compileParams = {
+      'isolateId': _message.params['isolateId'],
+      'expression': _message.params['expression'],
+      'definitions': buildScopeResponseResult['param_names'],
+      'typeDefinitions': buildScopeResponseResult['type_params_names'],
+      'libraryUri': buildScopeResponseResult['libraryUri'],
+      'isStatic': buildScopeResponseResult['isStatic'],
+    };
+    dynamic klass = buildScopeResponseResult['klass'];
+    if (klass != null) {
+      compileParams['klass'] = klass;
+    }
+    if (externalClient != null) {
+      var compileExpression = new Message.forMethod('compileExpression');
+      compileExpression.client = externalClient;
+      compileExpression.params.addAll(compileParams);
+
+      final id = _service._serviceRequests.newId();
+      final oldId = _message.serial;
+      final completer = new Completer<String>();
+      externalClient.serviceHandles[id] = (Message m) {
+        if (m != null) {
+          completer.complete(json.encode(m.forwardToJson({'id': oldId})));
+        } else {
+          completer.complete(encodeRpcError(_message, kServiceDisappeared));
+        }
+      };
+      externalClient.post(new Response.json(compileExpression
+          .forwardToJson({'id': id, 'method': 'compileExpression'})));
+      return completer.future
+          .then((String s) => jsonDecode(s))
+          .then((dynamic json) {
+        Map<String, dynamic> jsonMap = json;
+        if (jsonMap.containsKey('error')) {
+          throw jsonMap['error'];
+        }
+        return jsonMap['result']['result']['kernelBytes'];
+      });
+    } else {
+      // fallback to compile using kernel service
+      Map compileExpressionParams = {
+        'method': '_compileExpression',
+        'id': _message.serial,
+        'params': compileParams,
+      };
+      var compileExpression = new Message._fromJsonRpcRequest(
+          _message.client, compileExpressionParams);
+
+      return _isolate
+          .routeRequest(_service, compileExpression)
+          .then((Response response) => response.decodeJson())
+          .then((dynamic json) {
+        if (json['result'] != null) {
+          return json['result']['kernelBytes'];
+        }
+        throw json['error']['data']['details'];
+      });
+    }
+  }
+
+  Future<Response> _evaluateCompiledExpression(String kernelBase64) {
+    if (kernelBase64.isNotEmpty) {
+      Map<String, dynamic> params = _setupParams();
+      params['isolateId'] = _message.params['isolateId'];
+      params['kernelBytes'] = kernelBase64;
+      params['disableBreakpoints'] = _message.params['disableBreakpoints'];
+      Map runParams = {
+        'method': '_evaluateCompiledExpression',
+        'id': _message.serial,
+        'params': params,
+      };
+      if (_message.params['scope'] != null) {
+        runParams['params']['scope'] = _message.params['scope'];
+      }
+      var runExpression =
+          new Message._fromJsonRpcRequest(_message.client, runParams);
+      return _isolate.routeRequest(_service, runExpression); // _message
+    } else {
+      // empty kernel indicates dart1 mode
+      return _isolate.routeRequest(_service, _message);
+    }
+  }
+
+  Map<String, dynamic> _setupParams() {
+    if (_message.method == 'evaluateInFrame') {
+      return <String, dynamic>{'frameIndex': _message.params['frameIndex']};
+    } else {
+      assert(_message.method == 'evaluate');
+      return <String, dynamic>{'targetId': _message.params['targetId']};
+    }
+  }
+}
diff --git a/sdk_nnbd/lib/vmservice/vmservice.dart b/sdk_nnbd/lib/vmservice/vmservice.dart
new file mode 100644
index 0000000..0c340ee
--- /dev/null
+++ b/sdk_nnbd/lib/vmservice/vmservice.dart
@@ -0,0 +1,683 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart._vmservice;
+
+import 'dart:async';
+import 'dart:collection';
+import 'dart:convert';
+import 'dart:isolate';
+import 'dart:math';
+import 'dart:typed_data';
+
+part 'asset.dart';
+part 'client.dart';
+part 'devfs.dart';
+part 'constants.dart';
+part 'running_isolate.dart';
+part 'running_isolates.dart';
+part 'message.dart';
+part 'message_router.dart';
+part 'named_lookup.dart';
+
+final RawReceivePort isolateControlPort = new RawReceivePort();
+final RawReceivePort scriptLoadPort = new RawReceivePort();
+
+abstract class IsolateEmbedderData {
+  void cleanup();
+}
+
+String _makeAuthToken() {
+  final kTokenByteSize = 8;
+  Uint8List bytes = new Uint8List(kTokenByteSize);
+  Random random = new Random.secure();
+  for (int i = 0; i < kTokenByteSize; i++) {
+    bytes[i] = random.nextInt(256);
+  }
+  return base64Url.encode(bytes);
+}
+
+// The randomly generated auth token used to access the VM service.
+final String serviceAuthToken = _makeAuthToken();
+
+// This is for use by the embedder. It is a map from the isolateId to
+// anything implementing IsolateEmbedderData. When an isolate goes away,
+// the cleanup method will be invoked after being removed from the map.
+final Map<int, IsolateEmbedderData> isolateEmbedderData =
+    new Map<int, IsolateEmbedderData>();
+
+// These must be kept in sync with the declarations in vm/json_stream.h.
+const kParseError = -32700;
+const kInvalidRequest = -32600;
+const kMethodNotFound = -32601;
+const kInvalidParams = -32602;
+const kInternalError = -32603;
+
+const kExtensionError = -32000;
+
+const kFeatureDisabled = 100;
+const kCannotAddBreakpoint = 102;
+const kStreamAlreadySubscribed = 103;
+const kStreamNotSubscribed = 104;
+const kIsolateMustBeRunnable = 105;
+const kIsolateMustBePaused = 106;
+const kCannotResume = 107;
+const kIsolateIsReloading = 108;
+const kIsolateReloadBarred = 109;
+const kIsolateMustHaveReloaded = 110;
+const kServiceAlreadyRegistered = 111;
+const kServiceDisappeared = 112;
+const kExpressionCompilationError = 113;
+const kInvalidTimelineRequest = 114;
+
+// Experimental (used in private rpcs).
+const kFileSystemAlreadyExists = 1001;
+const kFileSystemDoesNotExist = 1002;
+const kFileDoesNotExist = 1003;
+
+var _errorMessages = {
+  kInvalidParams: 'Invalid params',
+  kInternalError: 'Internal error',
+  kFeatureDisabled: 'Feature is disabled',
+  kStreamAlreadySubscribed: 'Stream already subscribed',
+  kStreamNotSubscribed: 'Stream not subscribed',
+  kFileSystemAlreadyExists: 'File system already exists',
+  kFileSystemDoesNotExist: 'File system does not exist',
+  kFileDoesNotExist: 'File does not exist',
+  kServiceAlreadyRegistered: 'Service already registered',
+  kServiceDisappeared: 'Service has disappeared',
+  kExpressionCompilationError: 'Expression compilation error',
+  kInvalidTimelineRequest: 'The timeline related request could not be completed'
+      'due to the current configuration',
+};
+
+String encodeRpcError(Message message, int code, {String details}) {
+  var response = {
+    'jsonrpc': '2.0',
+    'id': message.serial,
+    'error': {
+      'code': code,
+      'message': _errorMessages[code],
+    },
+  };
+  if (details != null) {
+    response['error']['data'] = {
+      'details': details,
+    };
+  }
+  return json.encode(response);
+}
+
+String encodeMissingParamError(Message message, String param) {
+  return encodeRpcError(message, kInvalidParams,
+      details: "${message.method} expects the '${param}' parameter");
+}
+
+String encodeInvalidParamError(Message message, String param) {
+  var value = message.params[param];
+  return encodeRpcError(message, kInvalidParams,
+      details: "${message.method}: invalid '${param}' parameter: ${value}");
+}
+
+String encodeCompilationError(Message message, String diagnostic) {
+  return encodeRpcError(message, kExpressionCompilationError,
+      details: diagnostic);
+}
+
+String encodeResult(Message message, Map result) {
+  var response = {
+    'jsonrpc': '2.0',
+    'id': message.serial,
+    'result': result,
+  };
+  return json.encode(response);
+}
+
+String encodeSuccess(Message message) {
+  return encodeResult(message, {'type': 'Success'});
+}
+
+const shortDelay = const Duration(milliseconds: 10);
+
+/// Called when the server should be started.
+typedef Future ServerStartCallback();
+
+/// Called when the server should be stopped.
+typedef Future ServerStopCallback();
+
+/// Called when the service is exiting.
+typedef Future CleanupCallback();
+
+/// Called to create a temporary directory
+typedef Future<Uri> CreateTempDirCallback(String base);
+
+/// Called to delete a directory
+typedef Future DeleteDirCallback(Uri path);
+
+/// Called to write a file.
+typedef Future WriteFileCallback(Uri path, List<int> bytes);
+
+/// Called to write a stream into a file.
+typedef Future WriteStreamFileCallback(Uri path, Stream<List<int>> bytes);
+
+/// Called to read a file.
+typedef Future<List<int>> ReadFileCallback(Uri path);
+
+/// Called to list all files under some path.
+typedef Future<List<Map<String, dynamic>>> ListFilesCallback(Uri path);
+
+/// Called when we need information about the server.
+typedef Future<Uri> ServerInformamessage_routertionCallback();
+
+/// Called when we need information about the server.
+typedef Future<Uri> ServerInformationCallback();
+
+/// Called when we want to [enable] or disable the web server.
+typedef Future<Uri> WebServerControlCallback(bool enable);
+
+/// Hooks that are setup by the embedder.
+class VMServiceEmbedderHooks {
+  static ServerStartCallback serverStart;
+  static ServerStopCallback serverStop;
+  static CleanupCallback cleanup;
+  static CreateTempDirCallback createTempDir;
+  static DeleteDirCallback deleteDir;
+  static WriteFileCallback writeFile;
+  static WriteStreamFileCallback writeStreamFile;
+  static ReadFileCallback readFile;
+  static ListFilesCallback listFiles;
+  static ServerInformationCallback serverInformation;
+  static WebServerControlCallback webServerControl;
+}
+
+class VMService extends MessageRouter {
+  static VMService _instance;
+
+  static const serviceNamespace = 's';
+
+  /// Collection of currently connected clients.
+  final NamedLookup<Client> clients =
+      new NamedLookup<Client>(prologue: serviceNamespace);
+  final IdGenerator _serviceRequests = new IdGenerator(prologue: 'sr');
+
+  /// Collection of currently running isolates.
+  RunningIsolates runningIsolates = new RunningIsolates();
+
+  /// Flag to indicate VM service is exiting.
+  bool isExiting = false;
+
+  /// A port used to receive events from the VM.
+  final RawReceivePort eventPort;
+
+  final devfs = new DevFS();
+
+  void _addClient(Client client) {
+    assert(client.streams.isEmpty);
+    assert(client.services.isEmpty);
+    clients.add(client);
+  }
+
+  void _removeClient(Client client) {
+    final namespace = clients.keyOf(client);
+    clients.remove(client);
+    for (var streamId in client.streams) {
+      if (!_isAnyClientSubscribed(streamId)) {
+        _vmCancelStream(streamId);
+      }
+    }
+    for (var service in client.services.keys) {
+      _eventMessageHandler(
+          'Service',
+          new Response.json({
+            'jsonrpc': '2.0',
+            'method': 'streamNotify',
+            'params': {
+              'streamId': 'Service',
+              'event': {
+                "type": "Event",
+                "kind": "ServiceUnregistered",
+                'timestamp': new DateTime.now().millisecondsSinceEpoch,
+                'service': service,
+                'method': namespace + '.' + service,
+              }
+            }
+          }));
+    }
+    // Complete all requests as failed
+    for (var handle in client.serviceHandles.values) {
+      handle(null);
+    }
+  }
+
+  void _eventMessageHandler(String streamId, Response event) {
+    for (var client in clients) {
+      if (client.sendEvents && client.streams.contains(streamId)) {
+        client.post(event);
+      }
+    }
+  }
+
+  void _controlMessageHandler(int code, int portId, SendPort sp, String name) {
+    switch (code) {
+      case Constants.ISOLATE_STARTUP_MESSAGE_ID:
+        runningIsolates.isolateStartup(portId, sp, name);
+        break;
+      case Constants.ISOLATE_SHUTDOWN_MESSAGE_ID:
+        runningIsolates.isolateShutdown(portId, sp);
+        IsolateEmbedderData ied = isolateEmbedderData.remove(portId);
+        if (ied != null) {
+          ied.cleanup();
+        }
+        break;
+    }
+  }
+
+  Future<Null> _serverMessageHandler(int code, SendPort sp, bool enable) async {
+    switch (code) {
+      case Constants.WEB_SERVER_CONTROL_MESSAGE_ID:
+        if (VMServiceEmbedderHooks.webServerControl == null) {
+          sp.send(null);
+          return;
+        }
+        Uri uri = await VMServiceEmbedderHooks.webServerControl(enable);
+        sp.send(uri);
+        break;
+      case Constants.SERVER_INFO_MESSAGE_ID:
+        if (VMServiceEmbedderHooks.serverInformation == null) {
+          sp.send(null);
+          return;
+        }
+        Uri uri = await VMServiceEmbedderHooks.serverInformation();
+        sp.send(uri);
+        break;
+    }
+  }
+
+  Future<Null> _handleNativeRpcCall(message, SendPort replyPort) async {
+    // Keep in sync with "runtime/vm/service_isolate.cc:InvokeServiceRpc".
+    Response response;
+
+    try {
+      final Message rpc = new Message.fromJsonRpc(
+          null, json.decode(utf8.decode(message as List<int>)));
+      if (rpc.type != MessageType.Request) {
+        response = new Response.internalError(
+            'The client sent a non-request json-rpc message.');
+      } else {
+        response = await routeRequest(this, rpc);
+      }
+    } catch (exception) {
+      response = new Response.internalError(
+          'The rpc call resulted in exception: $exception.');
+    }
+    List<int> bytes;
+    switch (response.kind) {
+      case ResponsePayloadKind.String:
+        bytes = utf8.encode(response.payload);
+        bytes = bytes is Uint8List ? bytes : new Uint8List.fromList(bytes);
+        break;
+      case ResponsePayloadKind.Binary:
+      case ResponsePayloadKind.Utf8String:
+        bytes = response.payload as Uint8List;
+        break;
+    }
+    replyPort.send(bytes);
+  }
+
+  Future _exit() async {
+    isExiting = true;
+
+    // Stop the server.
+    if (VMServiceEmbedderHooks.serverStop != null) {
+      await VMServiceEmbedderHooks.serverStop();
+    }
+
+    // Close receive ports.
+    isolateControlPort.close();
+    scriptLoadPort.close();
+
+    // Create a copy of the set as a list because client.disconnect() will
+    // alter the connected clients set.
+    var clientsList = clients.toList();
+    for (var client in clientsList) {
+      client.disconnect();
+    }
+    devfs.cleanup();
+    if (VMServiceEmbedderHooks.cleanup != null) {
+      await VMServiceEmbedderHooks.cleanup();
+    }
+
+    // Notify the VM that we have exited.
+    _onExit();
+  }
+
+  void messageHandler(message) {
+    if (message is List) {
+      if (message.length == 2) {
+        // This is an event.
+        _eventMessageHandler(message[0], new Response.from(message[1]));
+        return;
+      }
+      if (message.length == 1) {
+        // This is a control message directing the vm service to exit.
+        assert(message[0] == Constants.SERVICE_EXIT_MESSAGE_ID);
+        _exit();
+        return;
+      }
+      if (message.length == 3) {
+        final opcode = message[0];
+        if (opcode == Constants.METHOD_CALL_FROM_NATIVE) {
+          _handleNativeRpcCall(message[1], message[2]);
+          return;
+        } else {
+          // This is a message interacting with the web server.
+          assert((opcode == Constants.WEB_SERVER_CONTROL_MESSAGE_ID) ||
+              (opcode == Constants.SERVER_INFO_MESSAGE_ID));
+          _serverMessageHandler(message[0], message[1], message[2]);
+          return;
+        }
+      }
+      if (message.length == 4) {
+        // This is a message informing us of the birth or death of an
+        // isolate.
+        _controlMessageHandler(message[0], message[1], message[2], message[3]);
+        return;
+      }
+    }
+    print('Internal vm-service error: ignoring illegal message: $message');
+  }
+
+  VMService._internal() : eventPort = isolateControlPort {
+    eventPort.handler = messageHandler;
+  }
+
+  factory VMService() {
+    if (VMService._instance == null) {
+      VMService._instance = new VMService._internal();
+      _onStart();
+    }
+    return _instance;
+  }
+
+  bool _isAnyClientSubscribed(String streamId) {
+    for (var client in clients) {
+      if (client.streams.contains(streamId)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  Client _findFirstClientThatHandlesService(String service) {
+    if (clients != null) {
+      for (Client c in clients) {
+        if (c.services.containsKey(service)) {
+          return c;
+        }
+      }
+    }
+    return null;
+  }
+
+  static const kServiceStream = 'Service';
+  static const serviceStreams = const [kServiceStream];
+
+  Future<String> _streamListen(Message message) async {
+    var client = message.client;
+    var streamId = message.params['streamId'];
+
+    if (client.streams.contains(streamId)) {
+      return encodeRpcError(message, kStreamAlreadySubscribed);
+    }
+    if (!_isAnyClientSubscribed(streamId)) {
+      if (!serviceStreams.contains(streamId) && !_vmListenStream(streamId)) {
+        return encodeRpcError(message, kInvalidParams,
+            details: "streamListen: invalid 'streamId' parameter: ${streamId}");
+      }
+    }
+
+    // Some streams can generate events or side effects after registration
+    switch (streamId) {
+      case kServiceStream:
+        for (Client c in clients) {
+          if (c == client) continue;
+          for (String service in c.services.keys) {
+            _sendServiceRegisteredEvent(c, service, target: client);
+          }
+        }
+        ;
+        break;
+    }
+
+    client.streams.add(streamId);
+    return encodeSuccess(message);
+  }
+
+  Future<String> _streamCancel(Message message) async {
+    var client = message.client;
+    var streamId = message.params['streamId'];
+
+    if (!client.streams.contains(streamId)) {
+      return encodeRpcError(message, kStreamNotSubscribed);
+    }
+    client.streams.remove(streamId);
+    if (!serviceStreams.contains(streamId) &&
+        !_isAnyClientSubscribed(streamId)) {
+      _vmCancelStream(streamId);
+    }
+
+    return encodeSuccess(message);
+  }
+
+  static bool _hasNamespace(String method) =>
+      method.contains('.') &&
+      _getNamespace(method).startsWith(serviceNamespace);
+  static String _getNamespace(String method) => method.split('.').first;
+  static String _getMethod(String method) => method.split('.').last;
+
+  Future<String> _registerService(Message message) async {
+    final client = message.client;
+    final service = message.params['service'];
+    final alias = message.params['alias'];
+
+    if (service is! String || service == '') {
+      return encodeRpcError(message, kInvalidParams,
+          details: "registerService: invalid 'service' parameter: ${service}");
+    }
+    if (alias is! String || alias == '') {
+      return encodeRpcError(message, kInvalidParams,
+          details: "registerService: invalid 'alias' parameter: ${alias}");
+    }
+    if (client.services.containsKey(service)) {
+      return encodeRpcError(message, kServiceAlreadyRegistered);
+    }
+    client.services[service] = alias;
+
+    bool removed;
+    try {
+      // Do not send streaming events to the client which registers the service
+      removed = client.streams.remove(kServiceStream);
+      await _sendServiceRegisteredEvent(client, service);
+    } finally {
+      if (removed) client.streams.add(kServiceStream);
+    }
+
+    return encodeSuccess(message);
+  }
+
+  _sendServiceRegisteredEvent(Client client, String service,
+      {Client target}) async {
+    final namespace = clients.keyOf(client);
+    final alias = client.services[service];
+    final event = new Response.json({
+      'jsonrpc': '2.0',
+      'method': 'streamNotify',
+      'params': {
+        'streamId': kServiceStream,
+        'event': {
+          "type": "Event",
+          "kind": "ServiceRegistered",
+          'timestamp': new DateTime.now().millisecondsSinceEpoch,
+          'service': service,
+          'method': namespace + '.' + service,
+          'alias': alias
+        }
+      }
+    });
+    if (target == null) {
+      _eventMessageHandler(kServiceStream, event);
+    } else {
+      target.post(event);
+    }
+  }
+
+  Future<String> _handleService(Message message) async {
+    final namespace = _getNamespace(message.method);
+    final method = _getMethod(message.method);
+    final client = clients[namespace];
+    if (client != null) {
+      if (client.services.containsKey(method)) {
+        final id = _serviceRequests.newId();
+        final oldId = message.serial;
+        final completer = new Completer<String>();
+        client.serviceHandles[id] = (Message m) {
+          if (m != null) {
+            completer.complete(json.encode(m.forwardToJson({'id': oldId})));
+          } else {
+            completer.complete(encodeRpcError(message, kServiceDisappeared));
+          }
+        };
+        client.post(new Response.json(
+            message.forwardToJson({'id': id, 'method': method})));
+        return completer.future;
+      }
+    }
+    return encodeRpcError(message, kMethodNotFound,
+        details: "Unknown service: ${message.method}");
+  }
+
+  Future<String> _spawnUri(Message message) async {
+    var token = message.params['token'];
+    if (token == null) {
+      return encodeMissingParamError(message, 'token');
+    }
+    if (token is! String) {
+      return encodeInvalidParamError(message, 'token');
+    }
+    var uri = message.params['uri'];
+    if (uri == null) {
+      return encodeMissingParamError(message, 'uri');
+    }
+    if (uri is! String) {
+      return encodeInvalidParamError(message, 'uri');
+    }
+    var args = message.params['args'];
+    var argsOfString = new List<String>();
+    if (args != null) {
+      if (args is! List) {
+        return encodeInvalidParamError(message, 'args');
+      }
+      for (var arg in args) {
+        if (arg is! String) {
+          return encodeInvalidParamError(message, 'args');
+        }
+        argsOfString.add(arg);
+      }
+    }
+    var msg = message.params['message'];
+
+    Isolate.spawnUri(Uri.parse(uri), argsOfString, msg).then((isolate) {
+      _spawnUriNotify(isolate.controlPort, token);
+    }).catchError((e) {
+      _spawnUriNotify(e.toString(), token);
+    });
+
+    return encodeSuccess(message);
+  }
+
+  Future<Response> routeRequest(VMService _, Message message) async {
+    final response = await _routeRequestImpl(message);
+    if (response == null) {
+      // We should only have a null response for Notifications.
+      assert(message.type == MessageType.Notification);
+      return null;
+    }
+    return new Response.from(response);
+  }
+
+  Future _routeRequestImpl(Message message) async {
+    try {
+      if (message.completed) {
+        return await message.response;
+      }
+      if (message.method == 'streamListen') {
+        return await _streamListen(message);
+      }
+      if (message.method == 'streamCancel') {
+        return await _streamCancel(message);
+      }
+      if (message.method == 'registerService') {
+        return await _registerService(message);
+      }
+      if (message.method == '_spawnUri') {
+        return await _spawnUri(message);
+      }
+      if (devfs.shouldHandleMessage(message)) {
+        return await devfs.handleMessage(message);
+      }
+      if (_hasNamespace(message.method)) {
+        return await _handleService(message);
+      }
+      if (message.params['isolateId'] != null) {
+        return await runningIsolates.routeRequest(this, message);
+      }
+      return await message.sendToVM();
+    } catch (e, st) {
+      message.setErrorResponse(kInternalError, 'Unexpected exception:$e\n$st');
+      return message.response;
+    }
+  }
+
+  void routeResponse(message) {
+    final client = message.client;
+    if (client.serviceHandles.containsKey(message.serial)) {
+      client.serviceHandles.remove(message.serial)(message);
+      _serviceRequests.release(message.serial);
+    }
+  }
+}
+
+@pragma("vm:entry-point", "call")
+RawReceivePort boot() {
+  // Return the port we expect isolate control messages on.
+  return isolateControlPort;
+}
+
+@pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product"))
+void _registerIsolate(int port_id, SendPort sp, String name) {
+  var service = new VMService();
+  service.runningIsolates.isolateStartup(port_id, sp, name);
+}
+
+/// Notify the VM that the service is running.
+void _onStart() native "VMService_OnStart";
+
+/// Notify the VM that the service is no longer running.
+void _onExit() native "VMService_OnExit";
+
+/// Notify the VM that the server's address has changed.
+void onServerAddressChange(String address)
+    native "VMService_OnServerAddressChange";
+
+/// Subscribe to a service stream.
+bool _vmListenStream(String streamId) native "VMService_ListenStream";
+
+/// Cancel a subscription to a service stream.
+void _vmCancelStream(String streamId) native "VMService_CancelStream";
+
+/// Get the bytes to the tar archive.
+Uint8List _requestAssets() native "VMService_RequestAssets";
+
+/// Notify the vm service that an isolate has been spawned via rpc.
+void _spawnUriNotify(obj, String token) native "VMService_spawnUriNotify";
diff --git a/sdk_nnbd/lib/vmservice/vmservice_sources.gni b/sdk_nnbd/lib/vmservice/vmservice_sources.gni
new file mode 100644
index 0000000..b8cf5bf
--- /dev/null
+++ b/sdk_nnbd/lib/vmservice/vmservice_sources.gni
@@ -0,0 +1,19 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Sources that make up the library "dart:_vmservice".
+vmservice_sdk_sources = [
+  "vmservice.dart",
+
+  # The above file needs to be first as it imports required libraries.
+  "asset.dart",
+  "client.dart",
+  "constants.dart",
+  "devfs.dart",
+  "running_isolate.dart",
+  "running_isolates.dart",
+  "message.dart",
+  "message_router.dart",
+  "named_lookup.dart",
+]
diff --git a/sdk_nnbd/lib/vmservice_libraries.json b/sdk_nnbd/lib/vmservice_libraries.json
new file mode 100644
index 0000000..c25ffe5
--- /dev/null
+++ b/sdk_nnbd/lib/vmservice_libraries.json
@@ -0,0 +1,12 @@
+{
+  "vm": {
+    "libraries": {
+      "vmservice_io": {
+        "uri": "../../runtime/bin/vmservice/vmservice_io.dart"
+      },
+      "_vmservice": {
+        "uri": "vmservice/vmservice.dart"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/sdk_nnbd/lib/vmservice_libraries.yaml b/sdk_nnbd/lib/vmservice_libraries.yaml
new file mode 100644
index 0000000..737e361
--- /dev/null
+++ b/sdk_nnbd/lib/vmservice_libraries.yaml
@@ -0,0 +1,20 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Note: if you edit this file, you must also edit libraries.json in this
+# directory:
+#
+#     python ./tools/yaml2json.py sdk/lib/vmservice_libraries.yaml sdk/lib/vmservice_libraries.json
+#
+# We currently have several different files that needs to be updated when
+# changing libraries, sources, and patch files.  See
+# https://github.com/dart-lang/sdk/issues/28836.
+
+vm:
+  libraries:
+    _vmservice:
+      uri: "vmservice/vmservice.dart"
+
+    vmservice_io:
+      uri: "../../runtime/bin/vmservice/vmservice_io.dart"
diff --git a/sdk_nnbd/lib/wasm/wasm.dart b/sdk_nnbd/lib/wasm/wasm.dart
new file mode 100644
index 0000000..edf0887
--- /dev/null
+++ b/sdk_nnbd/lib/wasm/wasm.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// {@category VM}
+/// {@nodoc}
+library dart.wasm;
+
+int callWasm(String name, int arg) {
+  return _callWasm(name, arg);
+}
+
+external int _callWasm(String name, int arg);
diff --git a/sdk_nnbd/lib/wasm/wasm_sources.gni b/sdk_nnbd/lib/wasm/wasm_sources.gni
new file mode 100644
index 0000000..dcd359a
--- /dev/null
+++ b/sdk_nnbd/lib/wasm/wasm_sources.gni
@@ -0,0 +1,7 @@
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+wasm_sdk_sources = [
+  "wasm.dart",
+]
diff --git a/sdk_nnbd/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk_nnbd/lib/web_audio/dart2js/web_audio_dart2js.dart
new file mode 100644
index 0000000..ef2ee67
--- /dev/null
+++ b/sdk_nnbd/lib/web_audio/dart2js/web_audio_dart2js.dart
@@ -0,0 +1,1246 @@
+/**
+ * High-fidelity audio programming in the browser.
+ *
+ * {@category Web}
+ */
+library dart.dom.web_audio;
+
+import 'dart:async';
+import 'dart:collection' hide LinkedList, LinkedListEntry;
+import 'dart:_internal' show FixedLengthListMixin;
+import 'dart:html';
+import 'dart:html_common';
+import 'dart:_native_typed_data';
+import 'dart:typed_data';
+import 'dart:_foreign_helper' show JS;
+import 'dart:_interceptors' show Interceptor;
+// DO NOT EDIT - unless you are editing documentation as per:
+// https://code.google.com/p/dart/wiki/ContributingHTMLDocumentation
+// Auto-generated dart:audio library.
+
+import 'dart:_js_helper'
+    show
+        Creates,
+        JavaScriptIndexingBehavior,
+        JSName,
+        Native,
+        Returns,
+        convertDartClosureToJS;
+
+// Copyright (c) 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.
+
+@Native("AnalyserNode,RealtimeAnalyserNode")
+class AnalyserNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory AnalyserNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory AnalyserNode(BaseAudioContext context, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return AnalyserNode._create_1(context, options_1);
+    }
+    return AnalyserNode._create_2(context);
+  }
+  static AnalyserNode _create_1(context, options) =>
+      JS('AnalyserNode', 'new AnalyserNode(#,#)', context, options);
+  static AnalyserNode _create_2(context) =>
+      JS('AnalyserNode', 'new AnalyserNode(#)', context);
+
+  int fftSize;
+
+  final int frequencyBinCount;
+
+  num maxDecibels;
+
+  num minDecibels;
+
+  num smoothingTimeConstant;
+
+  void getByteFrequencyData(Uint8List array) native;
+
+  void getByteTimeDomainData(Uint8List array) native;
+
+  void getFloatFrequencyData(Float32List array) native;
+
+  void getFloatTimeDomainData(Float32List array) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("AudioBuffer")
+class AudioBuffer extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AudioBuffer._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory AudioBuffer(Map options) {
+    var options_1 = convertDartToNative_Dictionary(options);
+    return AudioBuffer._create_1(options_1);
+  }
+  static AudioBuffer _create_1(options) =>
+      JS('AudioBuffer', 'new AudioBuffer(#)', options);
+
+  final num duration;
+
+  final int length;
+
+  final int numberOfChannels;
+
+  final num sampleRate;
+
+  void copyFromChannel(Float32List destination, int channelNumber,
+      [int startInChannel]) native;
+
+  void copyToChannel(Float32List source, int channelNumber,
+      [int startInChannel]) native;
+
+  Float32List getChannelData(int channelIndex) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@Native("AudioBufferSourceNode")
+class AudioBufferSourceNode extends AudioScheduledSourceNode {
+  // To suppress missing implicit constructor warnings.
+  factory AudioBufferSourceNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory AudioBufferSourceNode(BaseAudioContext context, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return AudioBufferSourceNode._create_1(context, options_1);
+    }
+    return AudioBufferSourceNode._create_2(context);
+  }
+  static AudioBufferSourceNode _create_1(context, options) => JS(
+      'AudioBufferSourceNode',
+      'new AudioBufferSourceNode(#,#)',
+      context,
+      options);
+  static AudioBufferSourceNode _create_2(context) =>
+      JS('AudioBufferSourceNode', 'new AudioBufferSourceNode(#)', context);
+
+  AudioBuffer buffer;
+
+  final AudioParam detune;
+
+  bool loop;
+
+  num loopEnd;
+
+  num loopStart;
+
+  final AudioParam playbackRate;
+
+  void start([num when, num grainOffset, num grainDuration]) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@Native("AudioContext,webkitAudioContext")
+class AudioContext extends BaseAudioContext {
+  // To suppress missing implicit constructor warnings.
+  factory AudioContext._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported =>
+      JS('bool', '!!(window.AudioContext || window.webkitAudioContext)');
+
+  final num baseLatency;
+
+  Future close() => promiseToFuture(JS("", "#.close()", this));
+
+  Map getOutputTimestamp() {
+    return convertNativeToDart_Dictionary(_getOutputTimestamp_1());
+  }
+
+  @JSName('getOutputTimestamp')
+  _getOutputTimestamp_1() native;
+
+  Future suspend() => promiseToFuture(JS("", "#.suspend()", this));
+
+  factory AudioContext() => JS('AudioContext',
+      'new (window.AudioContext || window.webkitAudioContext)()');
+
+  GainNode createGain() {
+    if (JS('bool', '#.createGain !== undefined', this)) {
+      return JS('GainNode', '#.createGain()', this);
+    } else {
+      return JS('GainNode', '#.createGainNode()', this);
+    }
+  }
+
+  ScriptProcessorNode createScriptProcessor(
+      [int bufferSize, int numberOfInputChannels, int numberOfOutputChannels]) {
+    var function = JS(
+        '=Object',
+        '#.createScriptProcessor || '
+            '#.createJavaScriptNode',
+        this,
+        this);
+    if (numberOfOutputChannels != null) {
+      return JS('ScriptProcessorNode', '#.call(#, #, #, #)', function, this,
+          bufferSize, numberOfInputChannels, numberOfOutputChannels);
+    } else if (numberOfInputChannels != null) {
+      return JS('ScriptProcessorNode', '#.call(#, #, #)', function, this,
+          bufferSize, numberOfInputChannels);
+    } else if (bufferSize != null) {
+      return JS(
+          'ScriptProcessorNode', '#.call(#, #)', function, this, bufferSize);
+    } else {
+      return JS('ScriptProcessorNode', '#.call(#)', function, this);
+    }
+  }
+
+  @JSName('decodeAudioData')
+  Future _decodeAudioData(ByteBuffer audioData,
+      [DecodeSuccessCallback successCallback,
+      DecodeErrorCallback errorCallback]) native;
+
+  Future<AudioBuffer> decodeAudioData(ByteBuffer audioData,
+      [DecodeSuccessCallback successCallback,
+      DecodeErrorCallback errorCallback]) {
+    if (successCallback != null && errorCallback != null) {
+      return _decodeAudioData(audioData, successCallback, errorCallback);
+    }
+
+    var completer = new Completer<AudioBuffer>();
+    _decodeAudioData(audioData, (value) {
+      completer.complete(value);
+    }, (error) {
+      if (error == null) {
+        completer.completeError('');
+      } else {
+        completer.completeError(error);
+      }
+    });
+    return completer.future;
+  }
+}
+// Copyright (c) 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.
+
+@Native("AudioDestinationNode")
+class AudioDestinationNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory AudioDestinationNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int maxChannelCount;
+}
+// Copyright (c) 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.
+
+@Native("AudioListener")
+class AudioListener extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AudioListener._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final AudioParam forwardX;
+
+  final AudioParam forwardY;
+
+  final AudioParam forwardZ;
+
+  final AudioParam positionX;
+
+  final AudioParam positionY;
+
+  final AudioParam positionZ;
+
+  final AudioParam upX;
+
+  final AudioParam upY;
+
+  final AudioParam upZ;
+
+  void setOrientation(num x, num y, num z, num xUp, num yUp, num zUp) native;
+
+  void setPosition(num x, num y, num z) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("AudioNode")
+class AudioNode extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory AudioNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int channelCount;
+
+  String channelCountMode;
+
+  String channelInterpretation;
+
+  final BaseAudioContext context;
+
+  final int numberOfInputs;
+
+  final int numberOfOutputs;
+
+  @JSName('connect')
+  AudioNode _connect(destination, [int output, int input]) native;
+
+  void disconnect([destination_OR_output, int output, int input]) native;
+
+  void connectNode(AudioNode destination, [int output = 0, int input = 0]) {
+    _connect(destination, output, input);
+  }
+
+  void connectParam(AudioParam destination, [int output = 0]) {
+    _connect(destination, output);
+  }
+}
+// Copyright (c) 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.
+
+@Native("AudioParam")
+class AudioParam extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AudioParam._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num defaultValue;
+
+  final num maxValue;
+
+  final num minValue;
+
+  num value;
+
+  AudioParam cancelAndHoldAtTime(num startTime) native;
+
+  AudioParam cancelScheduledValues(num startTime) native;
+
+  AudioParam exponentialRampToValueAtTime(num value, num time) native;
+
+  AudioParam linearRampToValueAtTime(num value, num time) native;
+
+  AudioParam setTargetAtTime(num target, num time, num timeConstant) native;
+
+  AudioParam setValueAtTime(num value, num time) native;
+
+  AudioParam setValueCurveAtTime(List<num> values, num time, num duration)
+      native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("AudioParamMap")
+class AudioParamMap extends Interceptor with MapMixin<String, dynamic> {
+  // To suppress missing implicit constructor warnings.
+  factory AudioParamMap._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Map _getItem(String key) =>
+      convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key));
+
+  void addAll(Map<String, dynamic> other) {
+    throw new UnsupportedError("Not supported");
+  }
+
+  bool containsValue(dynamic value) => values.any((e) => e == value);
+
+  bool containsKey(dynamic key) => _getItem(key) != null;
+
+  Map operator [](dynamic key) => _getItem(key);
+
+  void forEach(void f(String key, dynamic value)) {
+    var entries = JS('', '#.entries()', this);
+    while (true) {
+      var entry = JS('', '#.next()', entries);
+      if (JS('bool', '#.done', entry)) return;
+      f(JS('String', '#.value[0]', entry),
+          convertNativeToDart_Dictionary(JS('', '#.value[1]', entry)));
+    }
+  }
+
+  Iterable<String> get keys {
+    final keys = <String>[];
+    forEach((k, v) => keys.add(k));
+    return keys;
+  }
+
+  Iterable<Map> get values {
+    final values = <Map>[];
+    forEach((k, v) => values.add(v));
+    return values;
+  }
+
+  int get length => JS('int', '#.size', this);
+
+  bool get isEmpty => length == 0;
+
+  bool get isNotEmpty => !isEmpty;
+
+  void operator []=(String key, dynamic value) {
+    throw new UnsupportedError("Not supported");
+  }
+
+  dynamic putIfAbsent(String key, dynamic ifAbsent()) {
+    throw new UnsupportedError("Not supported");
+  }
+
+  String remove(dynamic key) {
+    throw new UnsupportedError("Not supported");
+  }
+
+  void clear() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("AudioProcessingEvent")
+class AudioProcessingEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory AudioProcessingEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory AudioProcessingEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return AudioProcessingEvent._create_1(type, eventInitDict_1);
+  }
+  static AudioProcessingEvent _create_1(type, eventInitDict) => JS(
+      'AudioProcessingEvent',
+      'new AudioProcessingEvent(#,#)',
+      type,
+      eventInitDict);
+
+  final AudioBuffer inputBuffer;
+
+  final AudioBuffer outputBuffer;
+
+  final num playbackTime;
+}
+// Copyright (c) 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.
+
+@Native("AudioScheduledSourceNode")
+class AudioScheduledSourceNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory AudioScheduledSourceNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> endedEvent =
+      const EventStreamProvider<Event>('ended');
+
+  @JSName('start')
+  void start2([num when]) native;
+
+  void stop([num when]) native;
+
+  Stream<Event> get onEnded => endedEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("AudioTrack")
+class AudioTrack extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AudioTrack._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  bool enabled;
+
+  final String id;
+
+  final String kind;
+
+  final String label;
+
+  final String language;
+
+  final SourceBuffer sourceBuffer;
+}
+// Copyright (c) 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.
+
+@Native("AudioTrackList")
+class AudioTrackList extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory AudioTrackList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const EventStreamProvider<Event> changeEvent =
+      const EventStreamProvider<Event>('change');
+
+  final int length;
+
+  AudioTrack __getter__(int index) native;
+
+  AudioTrack getTrackById(String id) native;
+
+  Stream<Event> get onChange => changeEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("AudioWorkletGlobalScope")
+class AudioWorkletGlobalScope extends WorkletGlobalScope {
+  // To suppress missing implicit constructor warnings.
+  factory AudioWorkletGlobalScope._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num currentTime;
+
+  final num sampleRate;
+
+  void registerProcessor(String name, Object processorConstructor) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("AudioWorkletNode")
+class AudioWorkletNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory AudioWorkletNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory AudioWorkletNode(BaseAudioContext context, String name,
+      [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return AudioWorkletNode._create_1(context, name, options_1);
+    }
+    return AudioWorkletNode._create_2(context, name);
+  }
+  static AudioWorkletNode _create_1(context, name, options) => JS(
+      'AudioWorkletNode',
+      'new AudioWorkletNode(#,#,#)',
+      context,
+      name,
+      options);
+  static AudioWorkletNode _create_2(context, name) =>
+      JS('AudioWorkletNode', 'new AudioWorkletNode(#,#)', context, name);
+
+  final AudioParamMap parameters;
+}
+// Copyright (c) 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.
+
+@Native("AudioWorkletProcessor")
+class AudioWorkletProcessor extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AudioWorkletProcessor._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("BaseAudioContext")
+class BaseAudioContext extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory BaseAudioContext._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final num currentTime;
+
+  final AudioDestinationNode destination;
+
+  final AudioListener listener;
+
+  final num sampleRate;
+
+  final String state;
+
+  AnalyserNode createAnalyser() native;
+
+  BiquadFilterNode createBiquadFilter() native;
+
+  AudioBuffer createBuffer(
+      int numberOfChannels, int numberOfFrames, num sampleRate) native;
+
+  AudioBufferSourceNode createBufferSource() native;
+
+  ChannelMergerNode createChannelMerger([int numberOfInputs]) native;
+
+  ChannelSplitterNode createChannelSplitter([int numberOfOutputs]) native;
+
+  ConstantSourceNode createConstantSource() native;
+
+  ConvolverNode createConvolver() native;
+
+  DelayNode createDelay([num maxDelayTime]) native;
+
+  DynamicsCompressorNode createDynamicsCompressor() native;
+
+  GainNode createGain() native;
+
+  @JSName('createIIRFilter')
+  IirFilterNode createIirFilter(List<num> feedForward, List<num> feedBack)
+      native;
+
+  MediaElementAudioSourceNode createMediaElementSource(
+      MediaElement mediaElement) native;
+
+  MediaStreamAudioDestinationNode createMediaStreamDestination() native;
+
+  MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream)
+      native;
+
+  OscillatorNode createOscillator() native;
+
+  PannerNode createPanner() native;
+
+  PeriodicWave createPeriodicWave(List<num> real, List<num> imag,
+      [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return _createPeriodicWave_1(real, imag, options_1);
+    }
+    return _createPeriodicWave_2(real, imag);
+  }
+
+  @JSName('createPeriodicWave')
+  PeriodicWave _createPeriodicWave_1(List<num> real, List<num> imag, options)
+      native;
+  @JSName('createPeriodicWave')
+  PeriodicWave _createPeriodicWave_2(List<num> real, List<num> imag) native;
+
+  ScriptProcessorNode createScriptProcessor(
+      [int bufferSize,
+      int numberOfInputChannels,
+      int numberOfOutputChannels]) native;
+
+  StereoPannerNode createStereoPanner() native;
+
+  WaveShaperNode createWaveShaper() native;
+
+  Future<AudioBuffer> decodeAudioData(ByteBuffer audioData,
+          [DecodeSuccessCallback successCallback,
+          DecodeErrorCallback errorCallback]) =>
+      promiseToFuture<AudioBuffer>(JS("", "#.decodeAudioData(#, #, #)", this,
+          audioData, successCallback, errorCallback));
+
+  Future resume() => promiseToFuture(JS("", "#.resume()", this));
+}
+// Copyright (c) 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.
+
+@Native("BiquadFilterNode")
+class BiquadFilterNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory BiquadFilterNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory BiquadFilterNode(BaseAudioContext context, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return BiquadFilterNode._create_1(context, options_1);
+    }
+    return BiquadFilterNode._create_2(context);
+  }
+  static BiquadFilterNode _create_1(context, options) =>
+      JS('BiquadFilterNode', 'new BiquadFilterNode(#,#)', context, options);
+  static BiquadFilterNode _create_2(context) =>
+      JS('BiquadFilterNode', 'new BiquadFilterNode(#)', context);
+
+  final AudioParam Q;
+
+  final AudioParam detune;
+
+  final AudioParam frequency;
+
+  final AudioParam gain;
+
+  String type;
+
+  void getFrequencyResponse(Float32List frequencyHz, Float32List magResponse,
+      Float32List phaseResponse) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("ChannelMergerNode,AudioChannelMerger")
+class ChannelMergerNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory ChannelMergerNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ChannelMergerNode(BaseAudioContext context, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return ChannelMergerNode._create_1(context, options_1);
+    }
+    return ChannelMergerNode._create_2(context);
+  }
+  static ChannelMergerNode _create_1(context, options) =>
+      JS('ChannelMergerNode', 'new ChannelMergerNode(#,#)', context, options);
+  static ChannelMergerNode _create_2(context) =>
+      JS('ChannelMergerNode', 'new ChannelMergerNode(#)', context);
+}
+// Copyright (c) 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.
+
+@Native("ChannelSplitterNode,AudioChannelSplitter")
+class ChannelSplitterNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory ChannelSplitterNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ChannelSplitterNode(BaseAudioContext context, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return ChannelSplitterNode._create_1(context, options_1);
+    }
+    return ChannelSplitterNode._create_2(context);
+  }
+  static ChannelSplitterNode _create_1(context, options) => JS(
+      'ChannelSplitterNode', 'new ChannelSplitterNode(#,#)', context, options);
+  static ChannelSplitterNode _create_2(context) =>
+      JS('ChannelSplitterNode', 'new ChannelSplitterNode(#)', context);
+}
+// Copyright (c) 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.
+
+@Native("ConstantSourceNode")
+class ConstantSourceNode extends AudioScheduledSourceNode {
+  // To suppress missing implicit constructor warnings.
+  factory ConstantSourceNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ConstantSourceNode(BaseAudioContext context, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return ConstantSourceNode._create_1(context, options_1);
+    }
+    return ConstantSourceNode._create_2(context);
+  }
+  static ConstantSourceNode _create_1(context, options) =>
+      JS('ConstantSourceNode', 'new ConstantSourceNode(#,#)', context, options);
+  static ConstantSourceNode _create_2(context) =>
+      JS('ConstantSourceNode', 'new ConstantSourceNode(#)', context);
+
+  final AudioParam offset;
+}
+// Copyright (c) 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.
+
+@Native("ConvolverNode")
+class ConvolverNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory ConvolverNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ConvolverNode(BaseAudioContext context, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return ConvolverNode._create_1(context, options_1);
+    }
+    return ConvolverNode._create_2(context);
+  }
+  static ConvolverNode _create_1(context, options) =>
+      JS('ConvolverNode', 'new ConvolverNode(#,#)', context, options);
+  static ConvolverNode _create_2(context) =>
+      JS('ConvolverNode', 'new ConvolverNode(#)', context);
+
+  AudioBuffer buffer;
+
+  bool normalize;
+}
+// Copyright (c) 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.
+
+@Native("DelayNode")
+class DelayNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory DelayNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DelayNode(BaseAudioContext context, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return DelayNode._create_1(context, options_1);
+    }
+    return DelayNode._create_2(context);
+  }
+  static DelayNode _create_1(context, options) =>
+      JS('DelayNode', 'new DelayNode(#,#)', context, options);
+  static DelayNode _create_2(context) =>
+      JS('DelayNode', 'new DelayNode(#)', context);
+
+  final AudioParam delayTime;
+}
+// Copyright (c) 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.
+
+@Native("DynamicsCompressorNode")
+class DynamicsCompressorNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory DynamicsCompressorNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory DynamicsCompressorNode(BaseAudioContext context, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return DynamicsCompressorNode._create_1(context, options_1);
+    }
+    return DynamicsCompressorNode._create_2(context);
+  }
+  static DynamicsCompressorNode _create_1(context, options) => JS(
+      'DynamicsCompressorNode',
+      'new DynamicsCompressorNode(#,#)',
+      context,
+      options);
+  static DynamicsCompressorNode _create_2(context) =>
+      JS('DynamicsCompressorNode', 'new DynamicsCompressorNode(#)', context);
+
+  final AudioParam attack;
+
+  final AudioParam knee;
+
+  final AudioParam ratio;
+
+  final num reduction;
+
+  final AudioParam release;
+
+  final AudioParam threshold;
+}
+// Copyright (c) 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.
+
+@Native("GainNode,AudioGainNode")
+class GainNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory GainNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory GainNode(BaseAudioContext context, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return GainNode._create_1(context, options_1);
+    }
+    return GainNode._create_2(context);
+  }
+  static GainNode _create_1(context, options) =>
+      JS('GainNode', 'new GainNode(#,#)', context, options);
+  static GainNode _create_2(context) =>
+      JS('GainNode', 'new GainNode(#)', context);
+
+  final AudioParam gain;
+}
+// Copyright (c) 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.
+
+@Native("IIRFilterNode")
+class IirFilterNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory IirFilterNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory IirFilterNode(BaseAudioContext context, Map options) {
+    var options_1 = convertDartToNative_Dictionary(options);
+    return IirFilterNode._create_1(context, options_1);
+  }
+  static IirFilterNode _create_1(context, options) =>
+      JS('IirFilterNode', 'new IIRFilterNode(#,#)', context, options);
+
+  void getFrequencyResponse(Float32List frequencyHz, Float32List magResponse,
+      Float32List phaseResponse) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("MediaElementAudioSourceNode")
+class MediaElementAudioSourceNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory MediaElementAudioSourceNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MediaElementAudioSourceNode(BaseAudioContext context, Map options) {
+    var options_1 = convertDartToNative_Dictionary(options);
+    return MediaElementAudioSourceNode._create_1(context, options_1);
+  }
+  static MediaElementAudioSourceNode _create_1(context, options) => JS(
+      'MediaElementAudioSourceNode',
+      'new MediaElementAudioSourceNode(#,#)',
+      context,
+      options);
+
+  final MediaElement mediaElement;
+}
+// Copyright (c) 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.
+
+@Native("MediaStreamAudioDestinationNode")
+class MediaStreamAudioDestinationNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory MediaStreamAudioDestinationNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MediaStreamAudioDestinationNode(BaseAudioContext context,
+      [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return MediaStreamAudioDestinationNode._create_1(context, options_1);
+    }
+    return MediaStreamAudioDestinationNode._create_2(context);
+  }
+  static MediaStreamAudioDestinationNode _create_1(context, options) => JS(
+      'MediaStreamAudioDestinationNode',
+      'new MediaStreamAudioDestinationNode(#,#)',
+      context,
+      options);
+  static MediaStreamAudioDestinationNode _create_2(context) => JS(
+      'MediaStreamAudioDestinationNode',
+      'new MediaStreamAudioDestinationNode(#)',
+      context);
+
+  final MediaStream stream;
+}
+// Copyright (c) 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.
+
+@Native("MediaStreamAudioSourceNode")
+class MediaStreamAudioSourceNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory MediaStreamAudioSourceNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory MediaStreamAudioSourceNode(BaseAudioContext context, Map options) {
+    var options_1 = convertDartToNative_Dictionary(options);
+    return MediaStreamAudioSourceNode._create_1(context, options_1);
+  }
+  static MediaStreamAudioSourceNode _create_1(context, options) => JS(
+      'MediaStreamAudioSourceNode',
+      'new MediaStreamAudioSourceNode(#,#)',
+      context,
+      options);
+
+  final MediaStream mediaStream;
+}
+// Copyright (c) 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.
+
+@Native("OfflineAudioCompletionEvent")
+class OfflineAudioCompletionEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory OfflineAudioCompletionEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory OfflineAudioCompletionEvent(String type, Map eventInitDict) {
+    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
+    return OfflineAudioCompletionEvent._create_1(type, eventInitDict_1);
+  }
+  static OfflineAudioCompletionEvent _create_1(type, eventInitDict) => JS(
+      'OfflineAudioCompletionEvent',
+      'new OfflineAudioCompletionEvent(#,#)',
+      type,
+      eventInitDict);
+
+  final AudioBuffer renderedBuffer;
+}
+// Copyright (c) 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.
+
+@Native("OfflineAudioContext")
+class OfflineAudioContext extends BaseAudioContext {
+  // To suppress missing implicit constructor warnings.
+  factory OfflineAudioContext._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory OfflineAudioContext(numberOfChannels_OR_options,
+      [int numberOfFrames, num sampleRate]) {
+    if ((sampleRate is num) &&
+        (numberOfFrames is int) &&
+        (numberOfChannels_OR_options is int)) {
+      return OfflineAudioContext._create_1(
+          numberOfChannels_OR_options, numberOfFrames, sampleRate);
+    }
+    if ((numberOfChannels_OR_options is Map) &&
+        numberOfFrames == null &&
+        sampleRate == null) {
+      var options_1 =
+          convertDartToNative_Dictionary(numberOfChannels_OR_options);
+      return OfflineAudioContext._create_2(options_1);
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+  static OfflineAudioContext _create_1(
+          numberOfChannels_OR_options, numberOfFrames, sampleRate) =>
+      JS('OfflineAudioContext', 'new OfflineAudioContext(#,#,#)',
+          numberOfChannels_OR_options, numberOfFrames, sampleRate);
+  static OfflineAudioContext _create_2(numberOfChannels_OR_options) => JS(
+      'OfflineAudioContext',
+      'new OfflineAudioContext(#)',
+      numberOfChannels_OR_options);
+
+  final int length;
+
+  Future<AudioBuffer> startRendering() =>
+      promiseToFuture<AudioBuffer>(JS("", "#.startRendering()", this));
+
+  @JSName('suspend')
+  Future suspendFor(num suspendTime) =>
+      promiseToFuture(JS("", "#.suspendFor(#)", this, suspendTime));
+}
+// Copyright (c) 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.
+
+@Native("OscillatorNode,Oscillator")
+class OscillatorNode extends AudioScheduledSourceNode {
+  // To suppress missing implicit constructor warnings.
+  factory OscillatorNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory OscillatorNode(BaseAudioContext context, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return OscillatorNode._create_1(context, options_1);
+    }
+    return OscillatorNode._create_2(context);
+  }
+  static OscillatorNode _create_1(context, options) =>
+      JS('OscillatorNode', 'new OscillatorNode(#,#)', context, options);
+  static OscillatorNode _create_2(context) =>
+      JS('OscillatorNode', 'new OscillatorNode(#)', context);
+
+  final AudioParam detune;
+
+  final AudioParam frequency;
+
+  String type;
+
+  void setPeriodicWave(PeriodicWave periodicWave) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("PannerNode,AudioPannerNode,webkitAudioPannerNode")
+class PannerNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory PannerNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PannerNode(BaseAudioContext context, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return PannerNode._create_1(context, options_1);
+    }
+    return PannerNode._create_2(context);
+  }
+  static PannerNode _create_1(context, options) =>
+      JS('PannerNode', 'new PannerNode(#,#)', context, options);
+  static PannerNode _create_2(context) =>
+      JS('PannerNode', 'new PannerNode(#)', context);
+
+  num coneInnerAngle;
+
+  num coneOuterAngle;
+
+  num coneOuterGain;
+
+  String distanceModel;
+
+  num maxDistance;
+
+  final AudioParam orientationX;
+
+  final AudioParam orientationY;
+
+  final AudioParam orientationZ;
+
+  String panningModel;
+
+  final AudioParam positionX;
+
+  final AudioParam positionY;
+
+  final AudioParam positionZ;
+
+  num refDistance;
+
+  num rolloffFactor;
+
+  void setOrientation(num x, num y, num z) native;
+
+  void setPosition(num x, num y, num z) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("PeriodicWave")
+class PeriodicWave extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory PeriodicWave._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory PeriodicWave(BaseAudioContext context, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return PeriodicWave._create_1(context, options_1);
+    }
+    return PeriodicWave._create_2(context);
+  }
+  static PeriodicWave _create_1(context, options) =>
+      JS('PeriodicWave', 'new PeriodicWave(#,#)', context, options);
+  static PeriodicWave _create_2(context) =>
+      JS('PeriodicWave', 'new PeriodicWave(#)', context);
+}
+// Copyright (c) 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.
+
+@Native("ScriptProcessorNode,JavaScriptAudioNode")
+class ScriptProcessorNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory ScriptProcessorNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /**
+   * Static factory designed to expose `audioprocess` events to event
+   * handlers that are not necessarily instances of [ScriptProcessorNode].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<AudioProcessingEvent> audioProcessEvent =
+      const EventStreamProvider<AudioProcessingEvent>('audioprocess');
+
+  final int bufferSize;
+
+  void setEventListener(EventListener eventListener) native;
+
+  /// Stream of `audioprocess` events handled by this [ScriptProcessorNode].
+/**
+   * Get a Stream that fires events when AudioProcessingEvents occur.
+   * This particular stream is special in that it only allows one listener to a
+   * given stream. Converting the returned Stream [asBroadcast] will likely ruin
+   * the soft-real-time properties which which these events are fired and can
+   * be processed.
+   */
+  Stream<AudioProcessingEvent> get onAudioProcess =>
+      audioProcessEvent.forTarget(this);
+}
+// Copyright (c) 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.
+
+@Native("StereoPannerNode")
+class StereoPannerNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory StereoPannerNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory StereoPannerNode(BaseAudioContext context, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return StereoPannerNode._create_1(context, options_1);
+    }
+    return StereoPannerNode._create_2(context);
+  }
+  static StereoPannerNode _create_1(context, options) =>
+      JS('StereoPannerNode', 'new StereoPannerNode(#,#)', context, options);
+  static StereoPannerNode _create_2(context) =>
+      JS('StereoPannerNode', 'new StereoPannerNode(#)', context);
+
+  final AudioParam pan;
+}
+// Copyright (c) 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.
+
+@Native("WaveShaperNode")
+class WaveShaperNode extends AudioNode {
+  // To suppress missing implicit constructor warnings.
+  factory WaveShaperNode._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory WaveShaperNode(BaseAudioContext context, [Map options]) {
+    if (options != null) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return WaveShaperNode._create_1(context, options_1);
+    }
+    return WaveShaperNode._create_2(context);
+  }
+  static WaveShaperNode _create_1(context, options) =>
+      JS('WaveShaperNode', 'new WaveShaperNode(#,#)', context, options);
+  static WaveShaperNode _create_2(context) =>
+      JS('WaveShaperNode', 'new WaveShaperNode(#)', context);
+
+  Float32List curve;
+
+  String oversample;
+}
diff --git a/sdk_nnbd/lib/web_gl/dart2js/web_gl_dart2js.dart b/sdk_nnbd/lib/web_gl/dart2js/web_gl_dart2js.dart
new file mode 100644
index 0000000..80e36b1
--- /dev/null
+++ b/sdk_nnbd/lib/web_gl/dart2js/web_gl_dart2js.dart
@@ -0,0 +1,4174 @@
+/**
+ * 3D programming in the browser.
+ *
+ * {@category Web}
+ */
+library dart.dom.web_gl;
+
+import 'dart:async';
+import 'dart:collection' hide LinkedList, LinkedListEntry;
+import 'dart:_internal' show FixedLengthListMixin;
+import 'dart:html';
+import 'dart:html_common';
+import 'dart:_native_typed_data';
+import 'dart:typed_data';
+import 'dart:_js_helper'
+    show Creates, JSName, Native, Returns, convertDartClosureToJS;
+import 'dart:_foreign_helper' show JS;
+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.
+
+// Copyright (c) 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.
+
+@Unstable()
+@Native("WebGLActiveInfo")
+class ActiveInfo extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ActiveInfo._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final String name;
+
+  final int size;
+
+  final int type;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("ANGLEInstancedArrays,ANGLE_instanced_arrays")
+class AngleInstancedArrays extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory AngleInstancedArrays._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE = 0x88FE;
+
+  @JSName('drawArraysInstancedANGLE')
+  void drawArraysInstancedAngle(int mode, int first, int count, int primcount)
+      native;
+
+  @JSName('drawElementsInstancedANGLE')
+  void drawElementsInstancedAngle(
+      int mode, int count, int type, int offset, int primcount) native;
+
+  @JSName('vertexAttribDivisorANGLE')
+  void vertexAttribDivisorAngle(int index, int divisor) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("WebGLBuffer")
+class Buffer extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Buffer._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// 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.
+
+@Native("WebGLCanvas")
+class Canvas extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Canvas._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('canvas')
+  final CanvasElement canvas;
+
+  @JSName('canvas')
+  final OffscreenCanvas offscreenCanvas;
+}
+
+// Copyright (c) 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.
+
+@Native("WebGLColorBufferFloat")
+class ColorBufferFloat extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ColorBufferFloat._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("WebGLCompressedTextureASTC")
+class CompressedTextureAstc extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CompressedTextureAstc._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int COMPRESSED_RGBA_ASTC_10x10_KHR = 0x93BB;
+
+  static const int COMPRESSED_RGBA_ASTC_10x5_KHR = 0x93B8;
+
+  static const int COMPRESSED_RGBA_ASTC_10x6_KHR = 0x93B9;
+
+  static const int COMPRESSED_RGBA_ASTC_10x8_KHR = 0x93BA;
+
+  static const int COMPRESSED_RGBA_ASTC_12x10_KHR = 0x93BC;
+
+  static const int COMPRESSED_RGBA_ASTC_12x12_KHR = 0x93BD;
+
+  static const int COMPRESSED_RGBA_ASTC_4x4_KHR = 0x93B0;
+
+  static const int COMPRESSED_RGBA_ASTC_5x4_KHR = 0x93B1;
+
+  static const int COMPRESSED_RGBA_ASTC_5x5_KHR = 0x93B2;
+
+  static const int COMPRESSED_RGBA_ASTC_6x5_KHR = 0x93B3;
+
+  static const int COMPRESSED_RGBA_ASTC_6x6_KHR = 0x93B4;
+
+  static const int COMPRESSED_RGBA_ASTC_8x5_KHR = 0x93B5;
+
+  static const int COMPRESSED_RGBA_ASTC_8x6_KHR = 0x93B6;
+
+  static const int COMPRESSED_RGBA_ASTC_8x8_KHR = 0x93B7;
+
+  static const int COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR = 0x93DB;
+
+  static const int COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR = 0x93D8;
+
+  static const int COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR = 0x93D9;
+
+  static const int COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR = 0x93DA;
+
+  static const int COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR = 0x93DC;
+
+  static const int COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR = 0x93DD;
+
+  static const int COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR = 0x93D0;
+
+  static const int COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR = 0x93D1;
+
+  static const int COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR = 0x93D2;
+
+  static const int COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR = 0x93D3;
+
+  static const int COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR = 0x93D4;
+
+  static const int COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR = 0x93D5;
+
+  static const int COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR = 0x93D6;
+
+  static const int COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR = 0x93D7;
+}
+// Copyright (c) 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.
+
+@Native("WebGLCompressedTextureATC,WEBGL_compressed_texture_atc")
+class CompressedTextureAtc extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CompressedTextureAtc._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL = 0x8C93;
+
+  static const int COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL = 0x87EE;
+
+  static const int COMPRESSED_RGB_ATC_WEBGL = 0x8C92;
+}
+// Copyright (c) 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.
+
+@Native("WebGLCompressedTextureETC1,WEBGL_compressed_texture_etc1")
+class CompressedTextureETC1 extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CompressedTextureETC1._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int COMPRESSED_RGB_ETC1_WEBGL = 0x8D64;
+}
+// Copyright (c) 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.
+
+@Native("WebGLCompressedTextureETC")
+class CompressedTextureEtc extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CompressedTextureEtc._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int COMPRESSED_R11_EAC = 0x9270;
+
+  static const int COMPRESSED_RG11_EAC = 0x9272;
+
+  static const int COMPRESSED_RGB8_ETC2 = 0x9274;
+
+  static const int COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276;
+
+  static const int COMPRESSED_RGBA8_ETC2_EAC = 0x9278;
+
+  static const int COMPRESSED_SIGNED_R11_EAC = 0x9271;
+
+  static const int COMPRESSED_SIGNED_RG11_EAC = 0x9273;
+
+  static const int COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279;
+
+  static const int COMPRESSED_SRGB8_ETC2 = 0x9275;
+
+  static const int COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9277;
+}
+// Copyright (c) 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.
+
+@Native("WebGLCompressedTexturePVRTC,WEBGL_compressed_texture_pvrtc")
+class CompressedTexturePvrtc extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CompressedTexturePvrtc._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 0x8C03;
+
+  static const int COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02;
+
+  static const int COMPRESSED_RGB_PVRTC_2BPPV1_IMG = 0x8C01;
+
+  static const int COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00;
+}
+// Copyright (c) 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.
+
+@Native("WebGLCompressedTextureS3TC,WEBGL_compressed_texture_s3tc")
+class CompressedTextureS3TC extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CompressedTextureS3TC._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1;
+
+  static const int COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2;
+
+  static const int COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3;
+
+  static const int COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0;
+}
+// Copyright (c) 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.
+
+@Native("WebGLCompressedTextureS3TCsRGB")
+class CompressedTextureS3TCsRgb extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory CompressedTextureS3TCsRgb._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT = 0x8C4D;
+
+  static const int COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT = 0x8C4E;
+
+  static const int COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT = 0x8C4F;
+
+  static const int COMPRESSED_SRGB_S3TC_DXT1_EXT = 0x8C4C;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("WebGLContextEvent")
+class ContextEvent extends Event {
+  // To suppress missing implicit constructor warnings.
+  factory ContextEvent._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  factory ContextEvent(String type, [Map eventInit]) {
+    if (eventInit != null) {
+      var eventInit_1 = convertDartToNative_Dictionary(eventInit);
+      return ContextEvent._create_1(type, eventInit_1);
+    }
+    return ContextEvent._create_2(type);
+  }
+  static ContextEvent _create_1(type, eventInit) =>
+      JS('ContextEvent', 'new WebGLContextEvent(#,#)', type, eventInit);
+  static ContextEvent _create_2(type) =>
+      JS('ContextEvent', 'new WebGLContextEvent(#)', type);
+
+  final String statusMessage;
+}
+// Copyright (c) 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.
+
+@Native("WebGLDebugRendererInfo,WEBGL_debug_renderer_info")
+class DebugRendererInfo extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DebugRendererInfo._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int UNMASKED_RENDERER_WEBGL = 0x9246;
+
+  static const int UNMASKED_VENDOR_WEBGL = 0x9245;
+}
+// Copyright (c) 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.
+
+@Native("WebGLDebugShaders,WEBGL_debug_shaders")
+class DebugShaders extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DebugShaders._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  String getTranslatedShaderSource(Shader shader) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("WebGLDepthTexture,WEBGL_depth_texture")
+class DepthTexture extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DepthTexture._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int UNSIGNED_INT_24_8_WEBGL = 0x84FA;
+}
+// Copyright (c) 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.
+
+@Native("WebGLDrawBuffers,WEBGL_draw_buffers")
+class DrawBuffers extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory DrawBuffers._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('drawBuffersWEBGL')
+  void drawBuffersWebgl(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
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("EXTsRGB,EXT_sRGB")
+class EXTsRgb extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory EXTsRgb._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT = 0x8210;
+
+  static const int SRGB8_ALPHA8_EXT = 0x8C43;
+
+  static const int SRGB_ALPHA_EXT = 0x8C42;
+
+  static const int SRGB_EXT = 0x8C40;
+}
+// Copyright (c) 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.
+
+@Native("EXTBlendMinMax,EXT_blend_minmax")
+class ExtBlendMinMax extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ExtBlendMinMax._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int MAX_EXT = 0x8008;
+
+  static const int MIN_EXT = 0x8007;
+}
+// Copyright (c) 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.
+
+@Native("EXTColorBufferFloat")
+class ExtColorBufferFloat extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ExtColorBufferFloat._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("EXTColorBufferHalfFloat")
+class ExtColorBufferHalfFloat extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ExtColorBufferHalfFloat._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("EXTDisjointTimerQuery")
+class ExtDisjointTimerQuery extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ExtDisjointTimerQuery._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int CURRENT_QUERY_EXT = 0x8865;
+
+  static const int GPU_DISJOINT_EXT = 0x8FBB;
+
+  static const int QUERY_COUNTER_BITS_EXT = 0x8864;
+
+  static const int QUERY_RESULT_AVAILABLE_EXT = 0x8867;
+
+  static const int QUERY_RESULT_EXT = 0x8866;
+
+  static const int TIMESTAMP_EXT = 0x8E28;
+
+  static const int TIME_ELAPSED_EXT = 0x88BF;
+
+  @JSName('beginQueryEXT')
+  void beginQueryExt(int target, TimerQueryExt query) native;
+
+  @JSName('createQueryEXT')
+  TimerQueryExt createQueryExt() native;
+
+  @JSName('deleteQueryEXT')
+  void deleteQueryExt(TimerQueryExt query) native;
+
+  @JSName('endQueryEXT')
+  void endQueryExt(int target) native;
+
+  @JSName('getQueryEXT')
+  Object getQueryExt(int target, int pname) native;
+
+  @JSName('getQueryObjectEXT')
+  Object getQueryObjectExt(TimerQueryExt query, int pname) native;
+
+  @JSName('isQueryEXT')
+  bool isQueryExt(TimerQueryExt query) native;
+
+  @JSName('queryCounterEXT')
+  void queryCounterExt(TimerQueryExt query, int target) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("EXTDisjointTimerQueryWebGL2")
+class ExtDisjointTimerQueryWebGL2 extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ExtDisjointTimerQueryWebGL2._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int GPU_DISJOINT_EXT = 0x8FBB;
+
+  static const int QUERY_COUNTER_BITS_EXT = 0x8864;
+
+  static const int TIMESTAMP_EXT = 0x8E28;
+
+  static const int TIME_ELAPSED_EXT = 0x88BF;
+
+  @JSName('queryCounterEXT')
+  void queryCounterExt(Query query, int target) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("EXTFragDepth,EXT_frag_depth")
+class ExtFragDepth extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ExtFragDepth._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("EXTShaderTextureLOD,EXT_shader_texture_lod")
+class ExtShaderTextureLod extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ExtShaderTextureLod._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("EXTTextureFilterAnisotropic,EXT_texture_filter_anisotropic")
+class ExtTextureFilterAnisotropic extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ExtTextureFilterAnisotropic._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF;
+
+  static const int TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE;
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("WebGLFramebuffer")
+class Framebuffer extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Framebuffer._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("WebGLGetBufferSubDataAsync")
+class GetBufferSubDataAsync extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory GetBufferSubDataAsync._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  Future getBufferSubDataAsync(int target, int srcByteOffset, TypedData dstData,
+          [int dstOffset, int length]) =>
+      promiseToFuture(JS("", "#.getBufferSubDataAsync(#, #, #, #, #)", this,
+          target, srcByteOffset, dstData, dstOffset, length));
+}
+// Copyright (c) 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.
+
+@Native("WebGLLoseContext,WebGLExtensionLoseContext,WEBGL_lose_context")
+class LoseContext extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory LoseContext._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  void loseContext() native;
+
+  void restoreContext() native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Native("OESElementIndexUint,OES_element_index_uint")
+class OesElementIndexUint extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory OesElementIndexUint._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("OESStandardDerivatives,OES_standard_derivatives")
+class OesStandardDerivatives extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory OesStandardDerivatives._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B;
+}
+// Copyright (c) 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.
+
+@Native("OESTextureFloat,OES_texture_float")
+class OesTextureFloat extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory OesTextureFloat._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("OESTextureFloatLinear,OES_texture_float_linear")
+class OesTextureFloatLinear extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory OesTextureFloatLinear._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("OESTextureHalfFloat,OES_texture_half_float")
+class OesTextureHalfFloat extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory OesTextureHalfFloat._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int HALF_FLOAT_OES = 0x8D61;
+}
+// Copyright (c) 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.
+
+@Native("OESTextureHalfFloatLinear,OES_texture_half_float_linear")
+class OesTextureHalfFloatLinear extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory OesTextureHalfFloatLinear._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("OESVertexArrayObject,OES_vertex_array_object")
+class OesVertexArrayObject extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory OesVertexArrayObject._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int VERTEX_ARRAY_BINDING_OES = 0x85B5;
+
+  @JSName('bindVertexArrayOES')
+  void bindVertexArray(VertexArrayObjectOes arrayObject) native;
+
+  @JSName('createVertexArrayOES')
+  VertexArrayObjectOes createVertexArray() native;
+
+  @JSName('deleteVertexArrayOES')
+  void deleteVertexArray(VertexArrayObjectOes arrayObject) native;
+
+  @JSName('isVertexArrayOES')
+  bool isVertexArray(VertexArrayObjectOes arrayObject) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Unstable()
+@Native("WebGLProgram")
+class Program extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Program._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("WebGLQuery")
+class Query extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Query._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Unstable()
+@Native("WebGLRenderbuffer")
+class Renderbuffer extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Renderbuffer._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@Unstable()
+@Native("WebGLRenderingContext")
+class RenderingContext extends Interceptor implements CanvasRenderingContext {
+  // To suppress missing implicit constructor warnings.
+  factory RenderingContext._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(window.WebGLRenderingContext)');
+
+  final CanvasElement canvas;
+
+  // From WebGLRenderingContextBase
+
+  final int drawingBufferHeight;
+
+  final int drawingBufferWidth;
+
+  void activeTexture(int texture) native;
+
+  void attachShader(Program program, Shader shader) native;
+
+  void bindAttribLocation(Program program, int index, String name) native;
+
+  void bindBuffer(int target, Buffer buffer) native;
+
+  void bindFramebuffer(int target, Framebuffer framebuffer) native;
+
+  void bindRenderbuffer(int target, Renderbuffer renderbuffer) native;
+
+  void bindTexture(int target, Texture texture) native;
+
+  void blendColor(num red, num green, num blue, num alpha) native;
+
+  void blendEquation(int mode) native;
+
+  void blendEquationSeparate(int modeRGB, int modeAlpha) native;
+
+  void blendFunc(int sfactor, int dfactor) native;
+
+  void blendFuncSeparate(int srcRGB, int dstRGB, int srcAlpha, int dstAlpha)
+      native;
+
+  void bufferData(int target, data_OR_size, int usage) native;
+
+  void bufferSubData(int target, int offset, data) native;
+
+  int checkFramebufferStatus(int target) native;
+
+  void clear(int mask) native;
+
+  void clearColor(num red, num green, num blue, num alpha) native;
+
+  void clearDepth(num depth) native;
+
+  void clearStencil(int s) native;
+
+  void colorMask(bool red, bool green, bool blue, bool alpha) native;
+
+  Future commit() => promiseToFuture(JS("", "#.commit()", this));
+
+  void compileShader(Shader shader) native;
+
+  void compressedTexImage2D(int target, int level, int internalformat,
+      int width, int height, int border, TypedData data) native;
+
+  void compressedTexSubImage2D(int target, int level, int xoffset, int yoffset,
+      int width, int height, int format, TypedData data) native;
+
+  void copyTexImage2D(int target, int level, int internalformat, int x, int y,
+      int width, int height, int border) native;
+
+  void copyTexSubImage2D(int target, int level, int xoffset, int yoffset, int x,
+      int y, int width, int height) native;
+
+  Buffer createBuffer() native;
+
+  Framebuffer createFramebuffer() native;
+
+  Program createProgram() native;
+
+  Renderbuffer createRenderbuffer() native;
+
+  Shader createShader(int type) native;
+
+  Texture createTexture() native;
+
+  void cullFace(int mode) native;
+
+  void deleteBuffer(Buffer buffer) native;
+
+  void deleteFramebuffer(Framebuffer framebuffer) native;
+
+  void deleteProgram(Program program) native;
+
+  void deleteRenderbuffer(Renderbuffer renderbuffer) native;
+
+  void deleteShader(Shader shader) native;
+
+  void deleteTexture(Texture texture) native;
+
+  void depthFunc(int func) native;
+
+  void depthMask(bool flag) native;
+
+  void depthRange(num zNear, num zFar) native;
+
+  void detachShader(Program program, Shader shader) native;
+
+  void disable(int cap) native;
+
+  void disableVertexAttribArray(int index) native;
+
+  void drawArrays(int mode, int first, int count) native;
+
+  void drawElements(int mode, int count, int type, int offset) native;
+
+  void enable(int cap) native;
+
+  void enableVertexAttribArray(int index) native;
+
+  void finish() native;
+
+  void flush() native;
+
+  void framebufferRenderbuffer(int target, int attachment,
+      int renderbuffertarget, Renderbuffer renderbuffer) native;
+
+  void framebufferTexture2D(int target, int attachment, int textarget,
+      Texture texture, int level) native;
+
+  void frontFace(int mode) native;
+
+  void generateMipmap(int target) native;
+
+  ActiveInfo getActiveAttrib(Program program, int index) native;
+
+  ActiveInfo getActiveUniform(Program program, int index) native;
+
+  List<Shader> getAttachedShaders(Program program) native;
+
+  int getAttribLocation(Program program, String name) native;
+
+  @Creates('int|Null')
+  @Returns('int|Null')
+  Object getBufferParameter(int target, int pname) native;
+
+  @Creates('ContextAttributes|Null')
+  Map getContextAttributes() {
+    return convertNativeToDart_Dictionary(_getContextAttributes_1());
+  }
+
+  @JSName('getContextAttributes')
+  @Creates('ContextAttributes|Null')
+  _getContextAttributes_1() native;
+
+  int getError() native;
+
+  Object getExtension(String name) native;
+
+  @Creates('int|Renderbuffer|Texture|Null')
+  @Returns('int|Renderbuffer|Texture|Null')
+  Object getFramebufferAttachmentParameter(
+      int target, int attachment, int pname) native;
+
+  @Creates(
+      'Null|num|String|bool|JSExtendableArray|NativeFloat32List|NativeInt32List|NativeUint32List|Framebuffer|Renderbuffer|Texture')
+  @Returns(
+      'Null|num|String|bool|JSExtendableArray|NativeFloat32List|NativeInt32List|NativeUint32List|Framebuffer|Renderbuffer|Texture')
+  Object getParameter(int pname) native;
+
+  String getProgramInfoLog(Program program) native;
+
+  @Creates('int|bool|Null')
+  @Returns('int|bool|Null')
+  Object getProgramParameter(Program program, int pname) native;
+
+  @Creates('int|Null')
+  @Returns('int|Null')
+  Object getRenderbufferParameter(int target, int pname) native;
+
+  String getShaderInfoLog(Shader shader) native;
+
+  @Creates('int|bool|Null')
+  @Returns('int|bool|Null')
+  Object getShaderParameter(Shader shader, int pname) native;
+
+  ShaderPrecisionFormat getShaderPrecisionFormat(
+      int shadertype, int precisiontype) native;
+
+  String getShaderSource(Shader shader) native;
+
+  List<String> getSupportedExtensions() native;
+
+  @Creates('int|Null')
+  @Returns('int|Null')
+  Object getTexParameter(int target, int pname) native;
+
+  @Creates(
+      'Null|num|String|bool|JSExtendableArray|NativeFloat32List|NativeInt32List|NativeUint32List')
+  @Returns(
+      'Null|num|String|bool|JSExtendableArray|NativeFloat32List|NativeInt32List|NativeUint32List')
+  Object getUniform(Program program, UniformLocation location) native;
+
+  UniformLocation getUniformLocation(Program program, String name) native;
+
+  @Creates('Null|num|bool|NativeFloat32List|Buffer')
+  @Returns('Null|num|bool|NativeFloat32List|Buffer')
+  Object getVertexAttrib(int index, int pname) native;
+
+  int getVertexAttribOffset(int index, int pname) native;
+
+  void hint(int target, int mode) native;
+
+  bool isBuffer(Buffer buffer) native;
+
+  bool isContextLost() native;
+
+  bool isEnabled(int cap) native;
+
+  bool isFramebuffer(Framebuffer framebuffer) native;
+
+  bool isProgram(Program program) native;
+
+  bool isRenderbuffer(Renderbuffer renderbuffer) native;
+
+  bool isShader(Shader shader) native;
+
+  bool isTexture(Texture texture) native;
+
+  void lineWidth(num width) native;
+
+  void linkProgram(Program program) native;
+
+  void pixelStorei(int pname, int param) native;
+
+  void polygonOffset(num factor, num units) native;
+
+  @JSName('readPixels')
+  void _readPixels(int x, int y, int width, int height, int format, int type,
+      TypedData pixels) native;
+
+  void renderbufferStorage(
+      int target, int internalformat, int width, int height) native;
+
+  void sampleCoverage(num value, bool invert) native;
+
+  void scissor(int x, int y, int width, int height) native;
+
+  void shaderSource(Shader shader, String string) native;
+
+  void stencilFunc(int func, int ref, int mask) native;
+
+  void stencilFuncSeparate(int face, int func, int ref, int mask) native;
+
+  void stencilMask(int mask) native;
+
+  void stencilMaskSeparate(int face, int mask) native;
+
+  void stencilOp(int fail, int zfail, int zpass) native;
+
+  void stencilOpSeparate(int face, int fail, int zfail, int zpass) native;
+
+  void texImage2D(
+      int target,
+      int level,
+      int internalformat,
+      int format_OR_width,
+      int height_OR_type,
+      bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video,
+      [int format,
+      int type,
+      TypedData pixels]) {
+    if (type != null &&
+        format != null &&
+        (bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video is int)) {
+      _texImage2D_1(
+          target,
+          level,
+          internalformat,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video,
+          format,
+          type,
+          pixels);
+      return;
+    }
+    if ((bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video is ImageData) &&
+        format == null &&
+        type == null &&
+        pixels == null) {
+      var pixels_1 = convertDartToNative_ImageData(
+          bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video);
+      _texImage2D_2(target, level, internalformat, format_OR_width,
+          height_OR_type, pixels_1);
+      return;
+    }
+    if ((bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video
+            is ImageElement) &&
+        format == null &&
+        type == null &&
+        pixels == null) {
+      _texImage2D_3(
+          target,
+          level,
+          internalformat,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video
+            is CanvasElement) &&
+        format == null &&
+        type == null &&
+        pixels == null) {
+      _texImage2D_4(
+          target,
+          level,
+          internalformat,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video
+            is VideoElement) &&
+        format == null &&
+        type == null &&
+        pixels == null) {
+      _texImage2D_5(
+          target,
+          level,
+          internalformat,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video
+            is ImageBitmap) &&
+        format == null &&
+        type == null &&
+        pixels == null) {
+      _texImage2D_6(
+          target,
+          level,
+          internalformat,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video);
+      return;
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('texImage2D')
+  void _texImage2D_1(target, level, internalformat, width, height, int border,
+      format, type, TypedData pixels) native;
+  @JSName('texImage2D')
+  void _texImage2D_2(target, level, internalformat, format, type, pixels)
+      native;
+  @JSName('texImage2D')
+  void _texImage2D_3(
+      target, level, internalformat, format, type, ImageElement image) native;
+  @JSName('texImage2D')
+  void _texImage2D_4(
+      target, level, internalformat, format, type, CanvasElement canvas) native;
+  @JSName('texImage2D')
+  void _texImage2D_5(
+      target, level, internalformat, format, type, VideoElement video) native;
+  @JSName('texImage2D')
+  void _texImage2D_6(
+      target, level, internalformat, format, type, ImageBitmap bitmap) native;
+
+  void texParameterf(int target, int pname, num param) native;
+
+  void texParameteri(int target, int pname, int param) native;
+
+  void texSubImage2D(
+      int target,
+      int level,
+      int xoffset,
+      int yoffset,
+      int format_OR_width,
+      int height_OR_type,
+      bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video,
+      [int type,
+      TypedData pixels]) {
+    if (type != null &&
+        (bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video is int)) {
+      _texSubImage2D_1(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video,
+          type,
+          pixels);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video is ImageData) &&
+        type == null &&
+        pixels == null) {
+      var pixels_1 = convertDartToNative_ImageData(
+          bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video);
+      _texSubImage2D_2(target, level, xoffset, yoffset, format_OR_width,
+          height_OR_type, pixels_1);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video
+            is ImageElement) &&
+        type == null &&
+        pixels == null) {
+      _texSubImage2D_3(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video
+            is CanvasElement) &&
+        type == null &&
+        pixels == null) {
+      _texSubImage2D_4(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video
+            is VideoElement) &&
+        type == null &&
+        pixels == null) {
+      _texSubImage2D_5(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video
+            is ImageBitmap) &&
+        type == null &&
+        pixels == null) {
+      _texSubImage2D_6(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video);
+      return;
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('texSubImage2D')
+  void _texSubImage2D_1(target, level, xoffset, yoffset, width, height,
+      int format, type, TypedData pixels) native;
+  @JSName('texSubImage2D')
+  void _texSubImage2D_2(target, level, xoffset, yoffset, format, type, pixels)
+      native;
+  @JSName('texSubImage2D')
+  void _texSubImage2D_3(
+      target, level, xoffset, yoffset, format, type, ImageElement image) native;
+  @JSName('texSubImage2D')
+  void _texSubImage2D_4(target, level, xoffset, yoffset, format, type,
+      CanvasElement canvas) native;
+  @JSName('texSubImage2D')
+  void _texSubImage2D_5(
+      target, level, xoffset, yoffset, format, type, VideoElement video) native;
+  @JSName('texSubImage2D')
+  void _texSubImage2D_6(
+      target, level, xoffset, yoffset, format, type, ImageBitmap bitmap) native;
+
+  void uniform1f(UniformLocation location, num x) native;
+
+  void uniform1fv(UniformLocation location, v) native;
+
+  void uniform1i(UniformLocation location, int x) native;
+
+  void uniform1iv(UniformLocation location, v) native;
+
+  void uniform2f(UniformLocation location, num x, num y) native;
+
+  void uniform2fv(UniformLocation location, v) native;
+
+  void uniform2i(UniformLocation location, int x, int y) native;
+
+  void uniform2iv(UniformLocation location, v) native;
+
+  void uniform3f(UniformLocation location, num x, num y, num z) native;
+
+  void uniform3fv(UniformLocation location, v) native;
+
+  void uniform3i(UniformLocation location, int x, int y, int z) native;
+
+  void uniform3iv(UniformLocation location, v) native;
+
+  void uniform4f(UniformLocation location, num x, num y, num z, num w) native;
+
+  void uniform4fv(UniformLocation location, v) native;
+
+  void uniform4i(UniformLocation location, int x, int y, int z, int w) native;
+
+  void uniform4iv(UniformLocation location, v) native;
+
+  void uniformMatrix2fv(UniformLocation location, bool transpose, array) native;
+
+  void uniformMatrix3fv(UniformLocation location, bool transpose, array) native;
+
+  void uniformMatrix4fv(UniformLocation location, bool transpose, array) native;
+
+  void useProgram(Program program) native;
+
+  void validateProgram(Program program) native;
+
+  void vertexAttrib1f(int indx, num x) native;
+
+  void vertexAttrib1fv(int indx, values) native;
+
+  void vertexAttrib2f(int indx, num x, num y) native;
+
+  void vertexAttrib2fv(int indx, values) native;
+
+  void vertexAttrib3f(int indx, num x, num y, num z) native;
+
+  void vertexAttrib3fv(int indx, values) native;
+
+  void vertexAttrib4f(int indx, num x, num y, num z, num w) native;
+
+  void vertexAttrib4fv(int indx, values) native;
+
+  void vertexAttribPointer(int indx, int size, int type, bool normalized,
+      int stride, int offset) native;
+
+  void viewport(int x, int y, int width, int height) native;
+
+  void readPixels(int x, int y, int width, int height, int format, int type,
+      TypedData pixels) {
+    _readPixels(x, y, width, height, format, type, pixels);
+  }
+
+  /**
+   * Sets the currently bound texture to [data].
+   *
+   * [data] can be either an [ImageElement], a
+   * [CanvasElement], a [VideoElement], [TypedData] or an [ImageData] object.
+   *
+   * This is deprecated in favor of [texImage2D].
+   */
+  @Deprecated("Use texImage2D")
+  void texImage2DUntyped(int targetTexture, int levelOfDetail,
+      int internalFormat, int format, int type, data) {
+    texImage2D(
+        targetTexture, levelOfDetail, internalFormat, format, type, data);
+  }
+
+  /**
+   * Sets the currently bound texture to [data].
+   *
+   * This is deprecated in favour of [texImage2D].
+   */
+  @Deprecated("Use texImage2D")
+  void texImage2DTyped(int targetTexture, int levelOfDetail, int internalFormat,
+      int width, int height, int border, int format, int type, TypedData data) {
+    texImage2D(targetTexture, levelOfDetail, internalFormat, width, height,
+        border, format, type, data);
+  }
+
+  /**
+   * Updates a sub-rectangle of the currently bound texture to [data].
+   *
+   * [data] can be either an [ImageElement], a
+   * [CanvasElement], a [VideoElement], [TypedData] or an [ImageData] object.
+   *
+   */
+  @Deprecated("Use texSubImage2D")
+  void texSubImage2DUntyped(int targetTexture, int levelOfDetail, int xOffset,
+      int yOffset, int format, int type, data) {
+    texSubImage2D(
+        targetTexture, levelOfDetail, xOffset, yOffset, format, type, data);
+  }
+
+  /**
+   * Updates a sub-rectangle of the currently bound texture to [data].
+   */
+  @Deprecated("Use texSubImage2D")
+  void texSubImage2DTyped(
+      int targetTexture,
+      int levelOfDetail,
+      int xOffset,
+      int yOffset,
+      int width,
+      int height,
+      int border,
+      int format,
+      int type,
+      TypedData data) {
+    texSubImage2D(targetTexture, levelOfDetail, xOffset, yOffset, width, height,
+        format, type, data);
+  }
+
+  /**
+   * Set the bufferData to [data].
+   */
+  @Deprecated("Use bufferData")
+  void bufferDataTyped(int target, TypedData data, int usage) {
+    bufferData(target, data, usage);
+  }
+
+  /**
+   * Set the bufferSubData to [data].
+   */
+  @Deprecated("Use bufferSubData")
+  void bufferSubDataTyped(int target, int offset, TypedData data) {
+    bufferSubData(target, offset, data);
+  }
+}
+// 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.
+
+@Native("WebGL2RenderingContext")
+class RenderingContext2 extends Interceptor
+    implements _WebGL2RenderingContextBase, _WebGLRenderingContextBase {
+  // To suppress missing implicit constructor warnings.
+  factory RenderingContext2._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final Canvas canvas;
+
+  // From WebGL2RenderingContextBase
+
+  void beginQuery(int target, Query query) native;
+
+  void beginTransformFeedback(int primitiveMode) native;
+
+  void bindBufferBase(int target, int index, Buffer buffer) native;
+
+  void bindBufferRange(
+      int target, int index, Buffer buffer, int offset, int size) native;
+
+  void bindSampler(int unit, Sampler sampler) native;
+
+  void bindTransformFeedback(int target, TransformFeedback feedback) native;
+
+  void bindVertexArray(VertexArrayObject vertexArray) native;
+
+  void blitFramebuffer(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0,
+      int dstY0, int dstX1, int dstY1, int mask, int filter) native;
+
+  @JSName('bufferData')
+  void bufferData2(int target, TypedData srcData, int usage, int srcOffset,
+      [int length]) native;
+
+  @JSName('bufferSubData')
+  void bufferSubData2(
+      int target, int dstByteOffset, TypedData srcData, int srcOffset,
+      [int length]) native;
+
+  void clearBufferfi(int buffer, int drawbuffer, num depth, int stencil) native;
+
+  void clearBufferfv(int buffer, int drawbuffer, value, [int srcOffset]) native;
+
+  void clearBufferiv(int buffer, int drawbuffer, value, [int srcOffset]) native;
+
+  void clearBufferuiv(int buffer, int drawbuffer, value, [int srcOffset])
+      native;
+
+  int clientWaitSync(Sync sync, int flags, int timeout) native;
+
+  @JSName('compressedTexImage2D')
+  void compressedTexImage2D2(int target, int level, int internalformat,
+      int width, int height, int border, TypedData data, int srcOffset,
+      [int srcLengthOverride]) native;
+
+  @JSName('compressedTexImage2D')
+  void compressedTexImage2D3(int target, int level, int internalformat,
+      int width, int height, int border, int imageSize, int offset) native;
+
+  void compressedTexImage3D(int target, int level, int internalformat,
+      int width, int height, int depth, int border, TypedData data,
+      [int srcOffset, int srcLengthOverride]) native;
+
+  @JSName('compressedTexImage3D')
+  void compressedTexImage3D2(
+      int target,
+      int level,
+      int internalformat,
+      int width,
+      int height,
+      int depth,
+      int border,
+      int imageSize,
+      int offset) native;
+
+  @JSName('compressedTexSubImage2D')
+  void compressedTexSubImage2D2(int target, int level, int xoffset, int yoffset,
+      int width, int height, int format, TypedData data, int srcOffset,
+      [int srcLengthOverride]) native;
+
+  @JSName('compressedTexSubImage2D')
+  void compressedTexSubImage2D3(int target, int level, int xoffset, int yoffset,
+      int width, int height, int format, int imageSize, int offset) native;
+
+  void compressedTexSubImage3D(int target, int level, int xoffset, int yoffset,
+      int zoffset, int width, int height, int depth, int format, TypedData data,
+      [int srcOffset, int srcLengthOverride]) native;
+
+  @JSName('compressedTexSubImage3D')
+  void compressedTexSubImage3D2(
+      int target,
+      int level,
+      int xoffset,
+      int yoffset,
+      int zoffset,
+      int width,
+      int height,
+      int depth,
+      int format,
+      int imageSize,
+      int offset) native;
+
+  void copyBufferSubData(int readTarget, int writeTarget, int readOffset,
+      int writeOffset, int size) native;
+
+  void copyTexSubImage3D(int target, int level, int xoffset, int yoffset,
+      int zoffset, int x, int y, int width, int height) native;
+
+  Query createQuery() native;
+
+  Sampler createSampler() native;
+
+  TransformFeedback createTransformFeedback() native;
+
+  VertexArrayObject createVertexArray() native;
+
+  void deleteQuery(Query query) native;
+
+  void deleteSampler(Sampler sampler) native;
+
+  void deleteSync(Sync sync) native;
+
+  void deleteTransformFeedback(TransformFeedback feedback) native;
+
+  void deleteVertexArray(VertexArrayObject vertexArray) native;
+
+  void drawArraysInstanced(int mode, int first, int count, int instanceCount)
+      native;
+
+  void drawBuffers(List<int> buffers) native;
+
+  void drawElementsInstanced(
+      int mode, int count, int type, int offset, int instanceCount) native;
+
+  void drawRangeElements(
+      int mode, int start, int end, int count, int type, int offset) native;
+
+  void endQuery(int target) native;
+
+  void endTransformFeedback() native;
+
+  Sync fenceSync(int condition, int flags) native;
+
+  void framebufferTextureLayer(
+      int target, int attachment, Texture texture, int level, int layer) native;
+
+  String getActiveUniformBlockName(Program program, int uniformBlockIndex)
+      native;
+
+  Object getActiveUniformBlockParameter(
+      Program program, int uniformBlockIndex, int pname) native;
+
+  Object getActiveUniforms(Program program, List<int> uniformIndices, int pname)
+      native;
+
+  void getBufferSubData(int target, int srcByteOffset, TypedData dstData,
+      [int dstOffset, int length]) native;
+
+  int getFragDataLocation(Program program, String name) native;
+
+  Object getIndexedParameter(int target, int index) native;
+
+  Object getInternalformatParameter(int target, int internalformat, int pname)
+      native;
+
+  Object getQuery(int target, int pname) native;
+
+  Object getQueryParameter(Query query, int pname) native;
+
+  Object getSamplerParameter(Sampler sampler, int pname) native;
+
+  Object getSyncParameter(Sync sync, int pname) native;
+
+  ActiveInfo getTransformFeedbackVarying(Program program, int index) native;
+
+  int getUniformBlockIndex(Program program, String uniformBlockName) native;
+
+  List<int> getUniformIndices(Program program, List<String> uniformNames) {
+    List uniformNames_1 = convertDartToNative_StringArray(uniformNames);
+    return _getUniformIndices_1(program, uniformNames_1);
+  }
+
+  @JSName('getUniformIndices')
+  List<int> _getUniformIndices_1(Program program, List uniformNames) native;
+
+  void invalidateFramebuffer(int target, List<int> attachments) native;
+
+  void invalidateSubFramebuffer(int target, List<int> attachments, int x, int y,
+      int width, int height) native;
+
+  bool isQuery(Query query) native;
+
+  bool isSampler(Sampler sampler) native;
+
+  bool isSync(Sync sync) native;
+
+  bool isTransformFeedback(TransformFeedback feedback) native;
+
+  bool isVertexArray(VertexArrayObject vertexArray) native;
+
+  void pauseTransformFeedback() native;
+
+  void readBuffer(int mode) native;
+
+  @JSName('readPixels')
+  void readPixels2(int x, int y, int width, int height, int format, int type,
+      dstData_OR_offset,
+      [int offset]) native;
+
+  void renderbufferStorageMultisample(int target, int samples,
+      int internalformat, int width, int height) native;
+
+  void resumeTransformFeedback() native;
+
+  void samplerParameterf(Sampler sampler, int pname, num param) native;
+
+  void samplerParameteri(Sampler sampler, int pname, int param) native;
+
+  void texImage2D2(
+      int target,
+      int level,
+      int internalformat,
+      int width,
+      int height,
+      int border,
+      int format,
+      int type,
+      bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video,
+      [int srcOffset]) {
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video
+            is int) &&
+        srcOffset == null) {
+      _texImage2D2_1(
+          target,
+          level,
+          internalformat,
+          width,
+          height,
+          border,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video
+            is ImageData) &&
+        srcOffset == null) {
+      var data_1 = convertDartToNative_ImageData(
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video);
+      _texImage2D2_2(target, level, internalformat, width, height, border,
+          format, type, data_1);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video
+            is ImageElement) &&
+        srcOffset == null) {
+      _texImage2D2_3(
+          target,
+          level,
+          internalformat,
+          width,
+          height,
+          border,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video
+            is CanvasElement) &&
+        srcOffset == null) {
+      _texImage2D2_4(
+          target,
+          level,
+          internalformat,
+          width,
+          height,
+          border,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video
+            is VideoElement) &&
+        srcOffset == null) {
+      _texImage2D2_5(
+          target,
+          level,
+          internalformat,
+          width,
+          height,
+          border,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video
+            is ImageBitmap) &&
+        srcOffset == null) {
+      _texImage2D2_6(
+          target,
+          level,
+          internalformat,
+          width,
+          height,
+          border,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video);
+      return;
+    }
+    if (srcOffset != null &&
+        (bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video
+            is TypedData)) {
+      _texImage2D2_7(
+          target,
+          level,
+          internalformat,
+          width,
+          height,
+          border,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video,
+          srcOffset);
+      return;
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('texImage2D')
+  void _texImage2D2_1(target, level, internalformat, width, height, border,
+      format, type, int offset) native;
+  @JSName('texImage2D')
+  void _texImage2D2_2(target, level, internalformat, width, height, border,
+      format, type, data) native;
+  @JSName('texImage2D')
+  void _texImage2D2_3(target, level, internalformat, width, height, border,
+      format, type, ImageElement image) native;
+  @JSName('texImage2D')
+  void _texImage2D2_4(target, level, internalformat, width, height, border,
+      format, type, CanvasElement canvas) native;
+  @JSName('texImage2D')
+  void _texImage2D2_5(target, level, internalformat, width, height, border,
+      format, type, VideoElement video) native;
+  @JSName('texImage2D')
+  void _texImage2D2_6(target, level, internalformat, width, height, border,
+      format, type, ImageBitmap bitmap) native;
+  @JSName('texImage2D')
+  void _texImage2D2_7(target, level, internalformat, width, height, border,
+      format, type, TypedData srcData, srcOffset) native;
+
+  void texImage3D(
+      int target,
+      int level,
+      int internalformat,
+      int width,
+      int height,
+      int depth,
+      int border,
+      int format,
+      int type,
+      bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video,
+      [int srcOffset]) {
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video
+            is int) &&
+        srcOffset == null) {
+      _texImage3D_1(
+          target,
+          level,
+          internalformat,
+          width,
+          height,
+          depth,
+          border,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video
+            is ImageData) &&
+        srcOffset == null) {
+      var data_1 = convertDartToNative_ImageData(
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video);
+      _texImage3D_2(target, level, internalformat, width, height, depth, border,
+          format, type, data_1);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video
+            is ImageElement) &&
+        srcOffset == null) {
+      _texImage3D_3(
+          target,
+          level,
+          internalformat,
+          width,
+          height,
+          depth,
+          border,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video
+            is CanvasElement) &&
+        srcOffset == null) {
+      _texImage3D_4(
+          target,
+          level,
+          internalformat,
+          width,
+          height,
+          depth,
+          border,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video
+            is VideoElement) &&
+        srcOffset == null) {
+      _texImage3D_5(
+          target,
+          level,
+          internalformat,
+          width,
+          height,
+          depth,
+          border,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video
+            is ImageBitmap) &&
+        srcOffset == null) {
+      _texImage3D_6(
+          target,
+          level,
+          internalformat,
+          width,
+          height,
+          depth,
+          border,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video
+                is TypedData ||
+            bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video ==
+                null) &&
+        srcOffset == null) {
+      _texImage3D_7(
+          target,
+          level,
+          internalformat,
+          width,
+          height,
+          depth,
+          border,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video);
+      return;
+    }
+    if (srcOffset != null &&
+        (bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video
+            is TypedData)) {
+      _texImage3D_8(
+          target,
+          level,
+          internalformat,
+          width,
+          height,
+          depth,
+          border,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video,
+          srcOffset);
+      return;
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('texImage3D')
+  void _texImage3D_1(target, level, internalformat, width, height, depth,
+      border, format, type, int offset) native;
+  @JSName('texImage3D')
+  void _texImage3D_2(target, level, internalformat, width, height, depth,
+      border, format, type, data) native;
+  @JSName('texImage3D')
+  void _texImage3D_3(target, level, internalformat, width, height, depth,
+      border, format, type, ImageElement image) native;
+  @JSName('texImage3D')
+  void _texImage3D_4(target, level, internalformat, width, height, depth,
+      border, format, type, CanvasElement canvas) native;
+  @JSName('texImage3D')
+  void _texImage3D_5(target, level, internalformat, width, height, depth,
+      border, format, type, VideoElement video) native;
+  @JSName('texImage3D')
+  void _texImage3D_6(target, level, internalformat, width, height, depth,
+      border, format, type, ImageBitmap bitmap) native;
+  @JSName('texImage3D')
+  void _texImage3D_7(target, level, internalformat, width, height, depth,
+      border, format, type, TypedData pixels) native;
+  @JSName('texImage3D')
+  void _texImage3D_8(target, level, internalformat, width, height, depth,
+      border, format, type, TypedData pixels, srcOffset) native;
+
+  void texStorage2D(
+      int target, int levels, int internalformat, int width, int height) native;
+
+  void texStorage3D(int target, int levels, int internalformat, int width,
+      int height, int depth) native;
+
+  void texSubImage2D2(
+      int target,
+      int level,
+      int xoffset,
+      int yoffset,
+      int width,
+      int height,
+      int format,
+      int type,
+      bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video,
+      [int srcOffset]) {
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video
+            is int) &&
+        srcOffset == null) {
+      _texSubImage2D2_1(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          width,
+          height,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video
+            is ImageData) &&
+        srcOffset == null) {
+      var data_1 = convertDartToNative_ImageData(
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video);
+      _texSubImage2D2_2(
+          target, level, xoffset, yoffset, width, height, format, type, data_1);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video
+            is ImageElement) &&
+        srcOffset == null) {
+      _texSubImage2D2_3(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          width,
+          height,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video
+            is CanvasElement) &&
+        srcOffset == null) {
+      _texSubImage2D2_4(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          width,
+          height,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video
+            is VideoElement) &&
+        srcOffset == null) {
+      _texSubImage2D2_5(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          width,
+          height,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video
+            is ImageBitmap) &&
+        srcOffset == null) {
+      _texSubImage2D2_6(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          width,
+          height,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video);
+      return;
+    }
+    if (srcOffset != null &&
+        (bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video
+            is TypedData)) {
+      _texSubImage2D2_7(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          width,
+          height,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video,
+          srcOffset);
+      return;
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('texSubImage2D')
+  void _texSubImage2D2_1(target, level, xoffset, yoffset, width, height, format,
+      type, int offset) native;
+  @JSName('texSubImage2D')
+  void _texSubImage2D2_2(target, level, xoffset, yoffset, width, height, format,
+      type, data) native;
+  @JSName('texSubImage2D')
+  void _texSubImage2D2_3(target, level, xoffset, yoffset, width, height, format,
+      type, ImageElement image) native;
+  @JSName('texSubImage2D')
+  void _texSubImage2D2_4(target, level, xoffset, yoffset, width, height, format,
+      type, CanvasElement canvas) native;
+  @JSName('texSubImage2D')
+  void _texSubImage2D2_5(target, level, xoffset, yoffset, width, height, format,
+      type, VideoElement video) native;
+  @JSName('texSubImage2D')
+  void _texSubImage2D2_6(target, level, xoffset, yoffset, width, height, format,
+      type, ImageBitmap bitmap) native;
+  @JSName('texSubImage2D')
+  void _texSubImage2D2_7(target, level, xoffset, yoffset, width, height, format,
+      type, TypedData srcData, srcOffset) native;
+
+  void texSubImage3D(
+      int target,
+      int level,
+      int xoffset,
+      int yoffset,
+      int zoffset,
+      int width,
+      int height,
+      int depth,
+      int format,
+      int type,
+      bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video,
+      [int srcOffset]) {
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video
+            is int) &&
+        srcOffset == null) {
+      _texSubImage3D_1(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          zoffset,
+          width,
+          height,
+          depth,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video
+            is ImageData) &&
+        srcOffset == null) {
+      var data_1 = convertDartToNative_ImageData(
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video);
+      _texSubImage3D_2(target, level, xoffset, yoffset, zoffset, width, height,
+          depth, format, type, data_1);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video
+            is ImageElement) &&
+        srcOffset == null) {
+      _texSubImage3D_3(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          zoffset,
+          width,
+          height,
+          depth,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video
+            is CanvasElement) &&
+        srcOffset == null) {
+      _texSubImage3D_4(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          zoffset,
+          width,
+          height,
+          depth,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video
+            is VideoElement) &&
+        srcOffset == null) {
+      _texSubImage3D_5(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          zoffset,
+          width,
+          height,
+          depth,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video
+            is ImageBitmap) &&
+        srcOffset == null) {
+      _texSubImage3D_6(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          zoffset,
+          width,
+          height,
+          depth,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video
+            is TypedData) &&
+        srcOffset == null) {
+      _texSubImage3D_7(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          zoffset,
+          width,
+          height,
+          depth,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video);
+      return;
+    }
+    if (srcOffset != null &&
+        (bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video
+            is TypedData)) {
+      _texSubImage3D_8(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          zoffset,
+          width,
+          height,
+          depth,
+          format,
+          type,
+          bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video,
+          srcOffset);
+      return;
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('texSubImage3D')
+  void _texSubImage3D_1(target, level, xoffset, yoffset, zoffset, width, height,
+      depth, format, type, int offset) native;
+  @JSName('texSubImage3D')
+  void _texSubImage3D_2(target, level, xoffset, yoffset, zoffset, width, height,
+      depth, format, type, data) native;
+  @JSName('texSubImage3D')
+  void _texSubImage3D_3(target, level, xoffset, yoffset, zoffset, width, height,
+      depth, format, type, ImageElement image) native;
+  @JSName('texSubImage3D')
+  void _texSubImage3D_4(target, level, xoffset, yoffset, zoffset, width, height,
+      depth, format, type, CanvasElement canvas) native;
+  @JSName('texSubImage3D')
+  void _texSubImage3D_5(target, level, xoffset, yoffset, zoffset, width, height,
+      depth, format, type, VideoElement video) native;
+  @JSName('texSubImage3D')
+  void _texSubImage3D_6(target, level, xoffset, yoffset, zoffset, width, height,
+      depth, format, type, ImageBitmap bitmap) native;
+  @JSName('texSubImage3D')
+  void _texSubImage3D_7(target, level, xoffset, yoffset, zoffset, width, height,
+      depth, format, type, TypedData pixels) native;
+  @JSName('texSubImage3D')
+  void _texSubImage3D_8(target, level, xoffset, yoffset, zoffset, width, height,
+      depth, format, type, TypedData pixels, srcOffset) native;
+
+  void transformFeedbackVaryings(
+      Program program, List<String> varyings, int bufferMode) {
+    List varyings_1 = convertDartToNative_StringArray(varyings);
+    _transformFeedbackVaryings_1(program, varyings_1, bufferMode);
+    return;
+  }
+
+  @JSName('transformFeedbackVaryings')
+  void _transformFeedbackVaryings_1(Program program, List varyings, bufferMode)
+      native;
+
+  @JSName('uniform1fv')
+  void uniform1fv2(UniformLocation location, v, int srcOffset, [int srcLength])
+      native;
+
+  @JSName('uniform1iv')
+  void uniform1iv2(UniformLocation location, v, int srcOffset, [int srcLength])
+      native;
+
+  void uniform1ui(UniformLocation location, int v0) native;
+
+  void uniform1uiv(UniformLocation location, v, [int srcOffset, int srcLength])
+      native;
+
+  @JSName('uniform2fv')
+  void uniform2fv2(UniformLocation location, v, int srcOffset, [int srcLength])
+      native;
+
+  @JSName('uniform2iv')
+  void uniform2iv2(UniformLocation location, v, int srcOffset, [int srcLength])
+      native;
+
+  void uniform2ui(UniformLocation location, int v0, int v1) native;
+
+  void uniform2uiv(UniformLocation location, v, [int srcOffset, int srcLength])
+      native;
+
+  @JSName('uniform3fv')
+  void uniform3fv2(UniformLocation location, v, int srcOffset, [int srcLength])
+      native;
+
+  @JSName('uniform3iv')
+  void uniform3iv2(UniformLocation location, v, int srcOffset, [int srcLength])
+      native;
+
+  void uniform3ui(UniformLocation location, int v0, int v1, int v2) native;
+
+  void uniform3uiv(UniformLocation location, v, [int srcOffset, int srcLength])
+      native;
+
+  @JSName('uniform4fv')
+  void uniform4fv2(UniformLocation location, v, int srcOffset, [int srcLength])
+      native;
+
+  @JSName('uniform4iv')
+  void uniform4iv2(UniformLocation location, v, int srcOffset, [int srcLength])
+      native;
+
+  void uniform4ui(UniformLocation location, int v0, int v1, int v2, int v3)
+      native;
+
+  void uniform4uiv(UniformLocation location, v, [int srcOffset, int srcLength])
+      native;
+
+  void uniformBlockBinding(
+      Program program, int uniformBlockIndex, int uniformBlockBinding) native;
+
+  @JSName('uniformMatrix2fv')
+  void uniformMatrix2fv2(
+      UniformLocation location, bool transpose, array, int srcOffset,
+      [int srcLength]) native;
+
+  void uniformMatrix2x3fv(UniformLocation location, bool transpose, value,
+      [int srcOffset, int srcLength]) native;
+
+  void uniformMatrix2x4fv(UniformLocation location, bool transpose, value,
+      [int srcOffset, int srcLength]) native;
+
+  @JSName('uniformMatrix3fv')
+  void uniformMatrix3fv2(
+      UniformLocation location, bool transpose, array, int srcOffset,
+      [int srcLength]) native;
+
+  void uniformMatrix3x2fv(UniformLocation location, bool transpose, value,
+      [int srcOffset, int srcLength]) native;
+
+  void uniformMatrix3x4fv(UniformLocation location, bool transpose, value,
+      [int srcOffset, int srcLength]) native;
+
+  @JSName('uniformMatrix4fv')
+  void uniformMatrix4fv2(
+      UniformLocation location, bool transpose, array, int srcOffset,
+      [int srcLength]) native;
+
+  void uniformMatrix4x2fv(UniformLocation location, bool transpose, value,
+      [int srcOffset, int srcLength]) native;
+
+  void uniformMatrix4x3fv(UniformLocation location, bool transpose, value,
+      [int srcOffset, int srcLength]) native;
+
+  void vertexAttribDivisor(int index, int divisor) native;
+
+  void vertexAttribI4i(int index, int x, int y, int z, int w) native;
+
+  void vertexAttribI4iv(int index, v) native;
+
+  void vertexAttribI4ui(int index, int x, int y, int z, int w) native;
+
+  void vertexAttribI4uiv(int index, v) native;
+
+  void vertexAttribIPointer(
+      int index, int size, int type, int stride, int offset) native;
+
+  void waitSync(Sync sync, int flags, int timeout) native;
+
+  // From WebGLRenderingContextBase
+
+  final int drawingBufferHeight;
+
+  final int drawingBufferWidth;
+
+  void activeTexture(int texture) native;
+
+  void attachShader(Program program, Shader shader) native;
+
+  void bindAttribLocation(Program program, int index, String name) native;
+
+  void bindBuffer(int target, Buffer buffer) native;
+
+  void bindFramebuffer(int target, Framebuffer framebuffer) native;
+
+  void bindRenderbuffer(int target, Renderbuffer renderbuffer) native;
+
+  void bindTexture(int target, Texture texture) native;
+
+  void blendColor(num red, num green, num blue, num alpha) native;
+
+  void blendEquation(int mode) native;
+
+  void blendEquationSeparate(int modeRGB, int modeAlpha) native;
+
+  void blendFunc(int sfactor, int dfactor) native;
+
+  void blendFuncSeparate(int srcRGB, int dstRGB, int srcAlpha, int dstAlpha)
+      native;
+
+  void bufferData(int target, data_OR_size, int usage) native;
+
+  void bufferSubData(int target, int offset, data) native;
+
+  int checkFramebufferStatus(int target) native;
+
+  void clear(int mask) native;
+
+  void clearColor(num red, num green, num blue, num alpha) native;
+
+  void clearDepth(num depth) native;
+
+  void clearStencil(int s) native;
+
+  void colorMask(bool red, bool green, bool blue, bool alpha) native;
+
+  Future commit() => promiseToFuture(JS("", "#.commit()", this));
+
+  void compileShader(Shader shader) native;
+
+  void compressedTexImage2D(int target, int level, int internalformat,
+      int width, int height, int border, TypedData data) native;
+
+  void compressedTexSubImage2D(int target, int level, int xoffset, int yoffset,
+      int width, int height, int format, TypedData data) native;
+
+  void copyTexImage2D(int target, int level, int internalformat, int x, int y,
+      int width, int height, int border) native;
+
+  void copyTexSubImage2D(int target, int level, int xoffset, int yoffset, int x,
+      int y, int width, int height) native;
+
+  Buffer createBuffer() native;
+
+  Framebuffer createFramebuffer() native;
+
+  Program createProgram() native;
+
+  Renderbuffer createRenderbuffer() native;
+
+  Shader createShader(int type) native;
+
+  Texture createTexture() native;
+
+  void cullFace(int mode) native;
+
+  void deleteBuffer(Buffer buffer) native;
+
+  void deleteFramebuffer(Framebuffer framebuffer) native;
+
+  void deleteProgram(Program program) native;
+
+  void deleteRenderbuffer(Renderbuffer renderbuffer) native;
+
+  void deleteShader(Shader shader) native;
+
+  void deleteTexture(Texture texture) native;
+
+  void depthFunc(int func) native;
+
+  void depthMask(bool flag) native;
+
+  void depthRange(num zNear, num zFar) native;
+
+  void detachShader(Program program, Shader shader) native;
+
+  void disable(int cap) native;
+
+  void disableVertexAttribArray(int index) native;
+
+  void drawArrays(int mode, int first, int count) native;
+
+  void drawElements(int mode, int count, int type, int offset) native;
+
+  void enable(int cap) native;
+
+  void enableVertexAttribArray(int index) native;
+
+  void finish() native;
+
+  void flush() native;
+
+  void framebufferRenderbuffer(int target, int attachment,
+      int renderbuffertarget, Renderbuffer renderbuffer) native;
+
+  void framebufferTexture2D(int target, int attachment, int textarget,
+      Texture texture, int level) native;
+
+  void frontFace(int mode) native;
+
+  void generateMipmap(int target) native;
+
+  ActiveInfo getActiveAttrib(Program program, int index) native;
+
+  ActiveInfo getActiveUniform(Program program, int index) native;
+
+  List<Shader> getAttachedShaders(Program program) native;
+
+  int getAttribLocation(Program program, String name) native;
+
+  Object getBufferParameter(int target, int pname) native;
+
+  Map getContextAttributes() {
+    return convertNativeToDart_Dictionary(_getContextAttributes_1());
+  }
+
+  @JSName('getContextAttributes')
+  _getContextAttributes_1() native;
+
+  int getError() native;
+
+  Object getExtension(String name) native;
+
+  Object getFramebufferAttachmentParameter(
+      int target, int attachment, int pname) native;
+
+  Object getParameter(int pname) native;
+
+  String getProgramInfoLog(Program program) native;
+
+  Object getProgramParameter(Program program, int pname) native;
+
+  Object getRenderbufferParameter(int target, int pname) native;
+
+  String getShaderInfoLog(Shader shader) native;
+
+  Object getShaderParameter(Shader shader, int pname) native;
+
+  ShaderPrecisionFormat getShaderPrecisionFormat(
+      int shadertype, int precisiontype) native;
+
+  String getShaderSource(Shader shader) native;
+
+  List<String> getSupportedExtensions() native;
+
+  Object getTexParameter(int target, int pname) native;
+
+  Object getUniform(Program program, UniformLocation location) native;
+
+  UniformLocation getUniformLocation(Program program, String name) native;
+
+  Object getVertexAttrib(int index, int pname) native;
+
+  int getVertexAttribOffset(int index, int pname) native;
+
+  void hint(int target, int mode) native;
+
+  bool isBuffer(Buffer buffer) native;
+
+  bool isContextLost() native;
+
+  bool isEnabled(int cap) native;
+
+  bool isFramebuffer(Framebuffer framebuffer) native;
+
+  bool isProgram(Program program) native;
+
+  bool isRenderbuffer(Renderbuffer renderbuffer) native;
+
+  bool isShader(Shader shader) native;
+
+  bool isTexture(Texture texture) native;
+
+  void lineWidth(num width) native;
+
+  void linkProgram(Program program) native;
+
+  void pixelStorei(int pname, int param) native;
+
+  void polygonOffset(num factor, num units) native;
+
+  @JSName('readPixels')
+  void _readPixels(int x, int y, int width, int height, int format, int type,
+      TypedData pixels) native;
+
+  void renderbufferStorage(
+      int target, int internalformat, int width, int height) native;
+
+  void sampleCoverage(num value, bool invert) native;
+
+  void scissor(int x, int y, int width, int height) native;
+
+  void shaderSource(Shader shader, String string) native;
+
+  void stencilFunc(int func, int ref, int mask) native;
+
+  void stencilFuncSeparate(int face, int func, int ref, int mask) native;
+
+  void stencilMask(int mask) native;
+
+  void stencilMaskSeparate(int face, int mask) native;
+
+  void stencilOp(int fail, int zfail, int zpass) native;
+
+  void stencilOpSeparate(int face, int fail, int zfail, int zpass) native;
+
+  void texImage2D(
+      int target,
+      int level,
+      int internalformat,
+      int format_OR_width,
+      int height_OR_type,
+      bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video,
+      [int format,
+      int type,
+      TypedData pixels]) {
+    if (type != null &&
+        format != null &&
+        (bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video is int)) {
+      _texImage2D_1(
+          target,
+          level,
+          internalformat,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video,
+          format,
+          type,
+          pixels);
+      return;
+    }
+    if ((bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video is ImageData) &&
+        format == null &&
+        type == null &&
+        pixels == null) {
+      var pixels_1 = convertDartToNative_ImageData(
+          bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video);
+      _texImage2D_2(target, level, internalformat, format_OR_width,
+          height_OR_type, pixels_1);
+      return;
+    }
+    if ((bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video
+            is ImageElement) &&
+        format == null &&
+        type == null &&
+        pixels == null) {
+      _texImage2D_3(
+          target,
+          level,
+          internalformat,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video
+            is CanvasElement) &&
+        format == null &&
+        type == null &&
+        pixels == null) {
+      _texImage2D_4(
+          target,
+          level,
+          internalformat,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video
+            is VideoElement) &&
+        format == null &&
+        type == null &&
+        pixels == null) {
+      _texImage2D_5(
+          target,
+          level,
+          internalformat,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video
+            is ImageBitmap) &&
+        format == null &&
+        type == null &&
+        pixels == null) {
+      _texImage2D_6(
+          target,
+          level,
+          internalformat,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video);
+      return;
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('texImage2D')
+  void _texImage2D_1(target, level, internalformat, width, height, int border,
+      format, type, TypedData pixels) native;
+  @JSName('texImage2D')
+  void _texImage2D_2(target, level, internalformat, format, type, pixels)
+      native;
+  @JSName('texImage2D')
+  void _texImage2D_3(
+      target, level, internalformat, format, type, ImageElement image) native;
+  @JSName('texImage2D')
+  void _texImage2D_4(
+      target, level, internalformat, format, type, CanvasElement canvas) native;
+  @JSName('texImage2D')
+  void _texImage2D_5(
+      target, level, internalformat, format, type, VideoElement video) native;
+  @JSName('texImage2D')
+  void _texImage2D_6(
+      target, level, internalformat, format, type, ImageBitmap bitmap) native;
+
+  void texParameterf(int target, int pname, num param) native;
+
+  void texParameteri(int target, int pname, int param) native;
+
+  void texSubImage2D(
+      int target,
+      int level,
+      int xoffset,
+      int yoffset,
+      int format_OR_width,
+      int height_OR_type,
+      bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video,
+      [int type,
+      TypedData pixels]) {
+    if (type != null &&
+        (bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video is int)) {
+      _texSubImage2D_1(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video,
+          type,
+          pixels);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video is ImageData) &&
+        type == null &&
+        pixels == null) {
+      var pixels_1 = convertDartToNative_ImageData(
+          bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video);
+      _texSubImage2D_2(target, level, xoffset, yoffset, format_OR_width,
+          height_OR_type, pixels_1);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video
+            is ImageElement) &&
+        type == null &&
+        pixels == null) {
+      _texSubImage2D_3(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video
+            is CanvasElement) &&
+        type == null &&
+        pixels == null) {
+      _texSubImage2D_4(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video
+            is VideoElement) &&
+        type == null &&
+        pixels == null) {
+      _texSubImage2D_5(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video);
+      return;
+    }
+    if ((bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video
+            is ImageBitmap) &&
+        type == null &&
+        pixels == null) {
+      _texSubImage2D_6(
+          target,
+          level,
+          xoffset,
+          yoffset,
+          format_OR_width,
+          height_OR_type,
+          bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video);
+      return;
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @JSName('texSubImage2D')
+  void _texSubImage2D_1(target, level, xoffset, yoffset, width, height,
+      int format, type, TypedData pixels) native;
+  @JSName('texSubImage2D')
+  void _texSubImage2D_2(target, level, xoffset, yoffset, format, type, pixels)
+      native;
+  @JSName('texSubImage2D')
+  void _texSubImage2D_3(
+      target, level, xoffset, yoffset, format, type, ImageElement image) native;
+  @JSName('texSubImage2D')
+  void _texSubImage2D_4(target, level, xoffset, yoffset, format, type,
+      CanvasElement canvas) native;
+  @JSName('texSubImage2D')
+  void _texSubImage2D_5(
+      target, level, xoffset, yoffset, format, type, VideoElement video) native;
+  @JSName('texSubImage2D')
+  void _texSubImage2D_6(
+      target, level, xoffset, yoffset, format, type, ImageBitmap bitmap) native;
+
+  void uniform1f(UniformLocation location, num x) native;
+
+  void uniform1fv(UniformLocation location, v) native;
+
+  void uniform1i(UniformLocation location, int x) native;
+
+  void uniform1iv(UniformLocation location, v) native;
+
+  void uniform2f(UniformLocation location, num x, num y) native;
+
+  void uniform2fv(UniformLocation location, v) native;
+
+  void uniform2i(UniformLocation location, int x, int y) native;
+
+  void uniform2iv(UniformLocation location, v) native;
+
+  void uniform3f(UniformLocation location, num x, num y, num z) native;
+
+  void uniform3fv(UniformLocation location, v) native;
+
+  void uniform3i(UniformLocation location, int x, int y, int z) native;
+
+  void uniform3iv(UniformLocation location, v) native;
+
+  void uniform4f(UniformLocation location, num x, num y, num z, num w) native;
+
+  void uniform4fv(UniformLocation location, v) native;
+
+  void uniform4i(UniformLocation location, int x, int y, int z, int w) native;
+
+  void uniform4iv(UniformLocation location, v) native;
+
+  void uniformMatrix2fv(UniformLocation location, bool transpose, array) native;
+
+  void uniformMatrix3fv(UniformLocation location, bool transpose, array) native;
+
+  void uniformMatrix4fv(UniformLocation location, bool transpose, array) native;
+
+  void useProgram(Program program) native;
+
+  void validateProgram(Program program) native;
+
+  void vertexAttrib1f(int indx, num x) native;
+
+  void vertexAttrib1fv(int indx, values) native;
+
+  void vertexAttrib2f(int indx, num x, num y) native;
+
+  void vertexAttrib2fv(int indx, values) native;
+
+  void vertexAttrib3f(int indx, num x, num y, num z) native;
+
+  void vertexAttrib3fv(int indx, values) native;
+
+  void vertexAttrib4f(int indx, num x, num y, num z, num w) native;
+
+  void vertexAttrib4fv(int indx, values) native;
+
+  void vertexAttribPointer(int indx, int size, int type, bool normalized,
+      int stride, int offset) native;
+
+  void viewport(int x, int y, int width, int height) native;
+
+  void readPixels(int x, int y, int width, int height, int format, int type,
+      TypedData pixels) {
+    _readPixels(x, y, width, height, format, type, pixels);
+  }
+}
+
+// Copyright (c) 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.
+
+@Native("WebGLSampler")
+class Sampler extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Sampler._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("WebGLShader")
+class Shader extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Shader._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("WebGLShaderPrecisionFormat")
+class ShaderPrecisionFormat extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory ShaderPrecisionFormat._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int precision;
+
+  final int rangeMax;
+
+  final int rangeMin;
+}
+// Copyright (c) 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.
+
+@Native("WebGLSync")
+class Sync extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Sync._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("WebGLTexture")
+class Texture extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory Texture._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final bool lastUploadedVideoFrameWasSkipped;
+
+  final int lastUploadedVideoHeight;
+
+  final num lastUploadedVideoTimestamp;
+
+  final int lastUploadedVideoWidth;
+}
+// Copyright (c) 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.
+
+@Native("WebGLTimerQueryEXT")
+class TimerQueryExt extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory TimerQueryExt._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("WebGLTransformFeedback")
+class TransformFeedback extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory TransformFeedback._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("WebGLUniformLocation")
+class UniformLocation extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory UniformLocation._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("WebGLVertexArrayObject")
+class VertexArrayObject extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory VertexArrayObject._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 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.
+
+@Native("WebGLVertexArrayObjectOES")
+class VertexArrayObjectOes extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory VertexArrayObjectOes._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Amalgamation of the WebGL constants from the IDL interfaces in
+/// WebGLRenderingContextBase, WebGL2RenderingContextBase, & WebGLDrawBuffers.
+/// Because the RenderingContextBase interfaces are hidden they would be
+/// replicated in more than one class (e.g., RenderingContext and
+/// RenderingContext2) to prevent that duplication these 600+ constants are
+/// defined in one abstract class (WebGL).
+@Native("WebGL")
+abstract class WebGL {
+  // To suppress missing implicit constructor warnings.
+  factory WebGL._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int ACTIVE_ATTRIBUTES = 0x8B89;
+
+  static const int ACTIVE_TEXTURE = 0x84E0;
+
+  static const int ACTIVE_UNIFORMS = 0x8B86;
+
+  static const int ACTIVE_UNIFORM_BLOCKS = 0x8A36;
+
+  static const int ALIASED_LINE_WIDTH_RANGE = 0x846E;
+
+  static const int ALIASED_POINT_SIZE_RANGE = 0x846D;
+
+  static const int ALPHA = 0x1906;
+
+  static const int ALPHA_BITS = 0x0D55;
+
+  static const int ALREADY_SIGNALED = 0x911A;
+
+  static const int ALWAYS = 0x0207;
+
+  static const int ANY_SAMPLES_PASSED = 0x8C2F;
+
+  static const int ANY_SAMPLES_PASSED_CONSERVATIVE = 0x8D6A;
+
+  static const int ARRAY_BUFFER = 0x8892;
+
+  static const int ARRAY_BUFFER_BINDING = 0x8894;
+
+  static const int ATTACHED_SHADERS = 0x8B85;
+
+  static const int BACK = 0x0405;
+
+  static const int BLEND = 0x0BE2;
+
+  static const int BLEND_COLOR = 0x8005;
+
+  static const int BLEND_DST_ALPHA = 0x80CA;
+
+  static const int BLEND_DST_RGB = 0x80C8;
+
+  static const int BLEND_EQUATION = 0x8009;
+
+  static const int BLEND_EQUATION_ALPHA = 0x883D;
+
+  static const int BLEND_EQUATION_RGB = 0x8009;
+
+  static const int BLEND_SRC_ALPHA = 0x80CB;
+
+  static const int BLEND_SRC_RGB = 0x80C9;
+
+  static const int BLUE_BITS = 0x0D54;
+
+  static const int BOOL = 0x8B56;
+
+  static const int BOOL_VEC2 = 0x8B57;
+
+  static const int BOOL_VEC3 = 0x8B58;
+
+  static const int BOOL_VEC4 = 0x8B59;
+
+  static const int BROWSER_DEFAULT_WEBGL = 0x9244;
+
+  static const int BUFFER_SIZE = 0x8764;
+
+  static const int BUFFER_USAGE = 0x8765;
+
+  static const int BYTE = 0x1400;
+
+  static const int CCW = 0x0901;
+
+  static const int CLAMP_TO_EDGE = 0x812F;
+
+  static const int COLOR = 0x1800;
+
+  static const int COLOR_ATTACHMENT0 = 0x8CE0;
+
+  static const int COLOR_ATTACHMENT0_WEBGL = 0x8CE0;
+
+  static const int COLOR_ATTACHMENT1 = 0x8CE1;
+
+  static const int COLOR_ATTACHMENT10 = 0x8CEA;
+
+  static const int COLOR_ATTACHMENT10_WEBGL = 0x8CEA;
+
+  static const int COLOR_ATTACHMENT11 = 0x8CEB;
+
+  static const int COLOR_ATTACHMENT11_WEBGL = 0x8CEB;
+
+  static const int COLOR_ATTACHMENT12 = 0x8CEC;
+
+  static const int COLOR_ATTACHMENT12_WEBGL = 0x8CEC;
+
+  static const int COLOR_ATTACHMENT13 = 0x8CED;
+
+  static const int COLOR_ATTACHMENT13_WEBGL = 0x8CED;
+
+  static const int COLOR_ATTACHMENT14 = 0x8CEE;
+
+  static const int COLOR_ATTACHMENT14_WEBGL = 0x8CEE;
+
+  static const int COLOR_ATTACHMENT15 = 0x8CEF;
+
+  static const int COLOR_ATTACHMENT15_WEBGL = 0x8CEF;
+
+  static const int COLOR_ATTACHMENT1_WEBGL = 0x8CE1;
+
+  static const int COLOR_ATTACHMENT2 = 0x8CE2;
+
+  static const int COLOR_ATTACHMENT2_WEBGL = 0x8CE2;
+
+  static const int COLOR_ATTACHMENT3 = 0x8CE3;
+
+  static const int COLOR_ATTACHMENT3_WEBGL = 0x8CE3;
+
+  static const int COLOR_ATTACHMENT4 = 0x8CE4;
+
+  static const int COLOR_ATTACHMENT4_WEBGL = 0x8CE4;
+
+  static const int COLOR_ATTACHMENT5 = 0x8CE5;
+
+  static const int COLOR_ATTACHMENT5_WEBGL = 0x8CE5;
+
+  static const int COLOR_ATTACHMENT6 = 0x8CE6;
+
+  static const int COLOR_ATTACHMENT6_WEBGL = 0x8CE6;
+
+  static const int COLOR_ATTACHMENT7 = 0x8CE7;
+
+  static const int COLOR_ATTACHMENT7_WEBGL = 0x8CE7;
+
+  static const int COLOR_ATTACHMENT8 = 0x8CE8;
+
+  static const int COLOR_ATTACHMENT8_WEBGL = 0x8CE8;
+
+  static const int COLOR_ATTACHMENT9 = 0x8CE9;
+
+  static const int COLOR_ATTACHMENT9_WEBGL = 0x8CE9;
+
+  static const int COLOR_BUFFER_BIT = 0x00004000;
+
+  static const int COLOR_CLEAR_VALUE = 0x0C22;
+
+  static const int COLOR_WRITEMASK = 0x0C23;
+
+  static const int COMPARE_REF_TO_TEXTURE = 0x884E;
+
+  static const int COMPILE_STATUS = 0x8B81;
+
+  static const int COMPRESSED_TEXTURE_FORMATS = 0x86A3;
+
+  static const int CONDITION_SATISFIED = 0x911C;
+
+  static const int CONSTANT_ALPHA = 0x8003;
+
+  static const int CONSTANT_COLOR = 0x8001;
+
+  static const int CONTEXT_LOST_WEBGL = 0x9242;
+
+  static const int COPY_READ_BUFFER = 0x8F36;
+
+  static const int COPY_READ_BUFFER_BINDING = 0x8F36;
+
+  static const int COPY_WRITE_BUFFER = 0x8F37;
+
+  static const int COPY_WRITE_BUFFER_BINDING = 0x8F37;
+
+  static const int CULL_FACE = 0x0B44;
+
+  static const int CULL_FACE_MODE = 0x0B45;
+
+  static const int CURRENT_PROGRAM = 0x8B8D;
+
+  static const int CURRENT_QUERY = 0x8865;
+
+  static const int CURRENT_VERTEX_ATTRIB = 0x8626;
+
+  static const int CW = 0x0900;
+
+  static const int DECR = 0x1E03;
+
+  static const int DECR_WRAP = 0x8508;
+
+  static const int DELETE_STATUS = 0x8B80;
+
+  static const int DEPTH = 0x1801;
+
+  static const int DEPTH24_STENCIL8 = 0x88F0;
+
+  static const int DEPTH32F_STENCIL8 = 0x8CAD;
+
+  static const int DEPTH_ATTACHMENT = 0x8D00;
+
+  static const int DEPTH_BITS = 0x0D56;
+
+  static const int DEPTH_BUFFER_BIT = 0x00000100;
+
+  static const int DEPTH_CLEAR_VALUE = 0x0B73;
+
+  static const int DEPTH_COMPONENT = 0x1902;
+
+  static const int DEPTH_COMPONENT16 = 0x81A5;
+
+  static const int DEPTH_COMPONENT24 = 0x81A6;
+
+  static const int DEPTH_COMPONENT32F = 0x8CAC;
+
+  static const int DEPTH_FUNC = 0x0B74;
+
+  static const int DEPTH_RANGE = 0x0B70;
+
+  static const int DEPTH_STENCIL = 0x84F9;
+
+  static const int DEPTH_STENCIL_ATTACHMENT = 0x821A;
+
+  static const int DEPTH_TEST = 0x0B71;
+
+  static const int DEPTH_WRITEMASK = 0x0B72;
+
+  static const int DITHER = 0x0BD0;
+
+  static const int DONT_CARE = 0x1100;
+
+  static const int DRAW_BUFFER0 = 0x8825;
+
+  static const int DRAW_BUFFER0_WEBGL = 0x8825;
+
+  static const int DRAW_BUFFER1 = 0x8826;
+
+  static const int DRAW_BUFFER10 = 0x882F;
+
+  static const int DRAW_BUFFER10_WEBGL = 0x882F;
+
+  static const int DRAW_BUFFER11 = 0x8830;
+
+  static const int DRAW_BUFFER11_WEBGL = 0x8830;
+
+  static const int DRAW_BUFFER12 = 0x8831;
+
+  static const int DRAW_BUFFER12_WEBGL = 0x8831;
+
+  static const int DRAW_BUFFER13 = 0x8832;
+
+  static const int DRAW_BUFFER13_WEBGL = 0x8832;
+
+  static const int DRAW_BUFFER14 = 0x8833;
+
+  static const int DRAW_BUFFER14_WEBGL = 0x8833;
+
+  static const int DRAW_BUFFER15 = 0x8834;
+
+  static const int DRAW_BUFFER15_WEBGL = 0x8834;
+
+  static const int DRAW_BUFFER1_WEBGL = 0x8826;
+
+  static const int DRAW_BUFFER2 = 0x8827;
+
+  static const int DRAW_BUFFER2_WEBGL = 0x8827;
+
+  static const int DRAW_BUFFER3 = 0x8828;
+
+  static const int DRAW_BUFFER3_WEBGL = 0x8828;
+
+  static const int DRAW_BUFFER4 = 0x8829;
+
+  static const int DRAW_BUFFER4_WEBGL = 0x8829;
+
+  static const int DRAW_BUFFER5 = 0x882A;
+
+  static const int DRAW_BUFFER5_WEBGL = 0x882A;
+
+  static const int DRAW_BUFFER6 = 0x882B;
+
+  static const int DRAW_BUFFER6_WEBGL = 0x882B;
+
+  static const int DRAW_BUFFER7 = 0x882C;
+
+  static const int DRAW_BUFFER7_WEBGL = 0x882C;
+
+  static const int DRAW_BUFFER8 = 0x882D;
+
+  static const int DRAW_BUFFER8_WEBGL = 0x882D;
+
+  static const int DRAW_BUFFER9 = 0x882E;
+
+  static const int DRAW_BUFFER9_WEBGL = 0x882E;
+
+  static const int DRAW_FRAMEBUFFER = 0x8CA9;
+
+  static const int DRAW_FRAMEBUFFER_BINDING = 0x8CA6;
+
+  static const int DST_ALPHA = 0x0304;
+
+  static const int DST_COLOR = 0x0306;
+
+  static const int DYNAMIC_COPY = 0x88EA;
+
+  static const int DYNAMIC_DRAW = 0x88E8;
+
+  static const int DYNAMIC_READ = 0x88E9;
+
+  static const int ELEMENT_ARRAY_BUFFER = 0x8893;
+
+  static const int ELEMENT_ARRAY_BUFFER_BINDING = 0x8895;
+
+  static const int EQUAL = 0x0202;
+
+  static const int FASTEST = 0x1101;
+
+  static const int FLOAT = 0x1406;
+
+  static const int FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD;
+
+  static const int FLOAT_MAT2 = 0x8B5A;
+
+  static const int FLOAT_MAT2x3 = 0x8B65;
+
+  static const int FLOAT_MAT2x4 = 0x8B66;
+
+  static const int FLOAT_MAT3 = 0x8B5B;
+
+  static const int FLOAT_MAT3x2 = 0x8B67;
+
+  static const int FLOAT_MAT3x4 = 0x8B68;
+
+  static const int FLOAT_MAT4 = 0x8B5C;
+
+  static const int FLOAT_MAT4x2 = 0x8B69;
+
+  static const int FLOAT_MAT4x3 = 0x8B6A;
+
+  static const int FLOAT_VEC2 = 0x8B50;
+
+  static const int FLOAT_VEC3 = 0x8B51;
+
+  static const int FLOAT_VEC4 = 0x8B52;
+
+  static const int FRAGMENT_SHADER = 0x8B30;
+
+  static const int FRAGMENT_SHADER_DERIVATIVE_HINT = 0x8B8B;
+
+  static const int FRAMEBUFFER = 0x8D40;
+
+  static const int FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE = 0x8215;
+
+  static const int FRAMEBUFFER_ATTACHMENT_BLUE_SIZE = 0x8214;
+
+  static const int FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING = 0x8210;
+
+  static const int FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE = 0x8211;
+
+  static const int FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE = 0x8216;
+
+  static const int FRAMEBUFFER_ATTACHMENT_GREEN_SIZE = 0x8213;
+
+  static const int FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1;
+
+  static const int FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0;
+
+  static const int FRAMEBUFFER_ATTACHMENT_RED_SIZE = 0x8212;
+
+  static const int FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE = 0x8217;
+
+  static const int FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
+
+  static const int FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER = 0x8CD4;
+
+  static const int FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2;
+
+  static const int FRAMEBUFFER_BINDING = 0x8CA6;
+
+  static const int FRAMEBUFFER_COMPLETE = 0x8CD5;
+
+  static const int FRAMEBUFFER_DEFAULT = 0x8218;
+
+  static const int FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6;
+
+  static const int FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9;
+
+  static const int FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
+
+  static const int FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = 0x8D56;
+
+  static const int FRAMEBUFFER_UNSUPPORTED = 0x8CDD;
+
+  static const int FRONT = 0x0404;
+
+  static const int FRONT_AND_BACK = 0x0408;
+
+  static const int FRONT_FACE = 0x0B46;
+
+  static const int FUNC_ADD = 0x8006;
+
+  static const int FUNC_REVERSE_SUBTRACT = 0x800B;
+
+  static const int FUNC_SUBTRACT = 0x800A;
+
+  static const int GENERATE_MIPMAP_HINT = 0x8192;
+
+  static const int GEQUAL = 0x0206;
+
+  static const int GREATER = 0x0204;
+
+  static const int GREEN_BITS = 0x0D53;
+
+  static const int HALF_FLOAT = 0x140B;
+
+  static const int HIGH_FLOAT = 0x8DF2;
+
+  static const int HIGH_INT = 0x8DF5;
+
+  static const int IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B;
+
+  static const int IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A;
+
+  static const int INCR = 0x1E02;
+
+  static const int INCR_WRAP = 0x8507;
+
+  static const int INT = 0x1404;
+
+  static const int INTERLEAVED_ATTRIBS = 0x8C8C;
+
+  static const int INT_2_10_10_10_REV = 0x8D9F;
+
+  static const int INT_SAMPLER_2D = 0x8DCA;
+
+  static const int INT_SAMPLER_2D_ARRAY = 0x8DCF;
+
+  static const int INT_SAMPLER_3D = 0x8DCB;
+
+  static const int INT_SAMPLER_CUBE = 0x8DCC;
+
+  static const int INT_VEC2 = 0x8B53;
+
+  static const int INT_VEC3 = 0x8B54;
+
+  static const int INT_VEC4 = 0x8B55;
+
+  static const int INVALID_ENUM = 0x0500;
+
+  static const int INVALID_FRAMEBUFFER_OPERATION = 0x0506;
+
+  static const int INVALID_INDEX = 0xFFFFFFFF;
+
+  static const int INVALID_OPERATION = 0x0502;
+
+  static const int INVALID_VALUE = 0x0501;
+
+  static const int INVERT = 0x150A;
+
+  static const int KEEP = 0x1E00;
+
+  static const int LEQUAL = 0x0203;
+
+  static const int LESS = 0x0201;
+
+  static const int LINEAR = 0x2601;
+
+  static const int LINEAR_MIPMAP_LINEAR = 0x2703;
+
+  static const int LINEAR_MIPMAP_NEAREST = 0x2701;
+
+  static const int LINES = 0x0001;
+
+  static const int LINE_LOOP = 0x0002;
+
+  static const int LINE_STRIP = 0x0003;
+
+  static const int LINE_WIDTH = 0x0B21;
+
+  static const int LINK_STATUS = 0x8B82;
+
+  static const int LOW_FLOAT = 0x8DF0;
+
+  static const int LOW_INT = 0x8DF3;
+
+  static const int LUMINANCE = 0x1909;
+
+  static const int LUMINANCE_ALPHA = 0x190A;
+
+  static const int MAX = 0x8008;
+
+  static const int MAX_3D_TEXTURE_SIZE = 0x8073;
+
+  static const int MAX_ARRAY_TEXTURE_LAYERS = 0x88FF;
+
+  static const int MAX_CLIENT_WAIT_TIMEOUT_WEBGL = 0x9247;
+
+  static const int MAX_COLOR_ATTACHMENTS = 0x8CDF;
+
+  static const int MAX_COLOR_ATTACHMENTS_WEBGL = 0x8CDF;
+
+  static const int MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = 0x8A33;
+
+  static const int MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
+
+  static const int MAX_COMBINED_UNIFORM_BLOCKS = 0x8A2E;
+
+  static const int MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = 0x8A31;
+
+  static const int MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C;
+
+  static const int MAX_DRAW_BUFFERS = 0x8824;
+
+  static const int MAX_DRAW_BUFFERS_WEBGL = 0x8824;
+
+  static const int MAX_ELEMENTS_INDICES = 0x80E9;
+
+  static const int MAX_ELEMENTS_VERTICES = 0x80E8;
+
+  static const int MAX_ELEMENT_INDEX = 0x8D6B;
+
+  static const int MAX_FRAGMENT_INPUT_COMPONENTS = 0x9125;
+
+  static const int MAX_FRAGMENT_UNIFORM_BLOCKS = 0x8A2D;
+
+  static const int MAX_FRAGMENT_UNIFORM_COMPONENTS = 0x8B49;
+
+  static const int MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD;
+
+  static const int MAX_PROGRAM_TEXEL_OFFSET = 0x8905;
+
+  static const int MAX_RENDERBUFFER_SIZE = 0x84E8;
+
+  static const int MAX_SAMPLES = 0x8D57;
+
+  static const int MAX_SERVER_WAIT_TIMEOUT = 0x9111;
+
+  static const int MAX_TEXTURE_IMAGE_UNITS = 0x8872;
+
+  static const int MAX_TEXTURE_LOD_BIAS = 0x84FD;
+
+  static const int MAX_TEXTURE_SIZE = 0x0D33;
+
+  static const int MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 0x8C8A;
+
+  static const int MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 0x8C8B;
+
+  static const int MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = 0x8C80;
+
+  static const int MAX_UNIFORM_BLOCK_SIZE = 0x8A30;
+
+  static const int MAX_UNIFORM_BUFFER_BINDINGS = 0x8A2F;
+
+  static const int MAX_VARYING_COMPONENTS = 0x8B4B;
+
+  static const int MAX_VARYING_VECTORS = 0x8DFC;
+
+  static const int MAX_VERTEX_ATTRIBS = 0x8869;
+
+  static const int MAX_VERTEX_OUTPUT_COMPONENTS = 0x9122;
+
+  static const int MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C;
+
+  static const int MAX_VERTEX_UNIFORM_BLOCKS = 0x8A2B;
+
+  static const int MAX_VERTEX_UNIFORM_COMPONENTS = 0x8B4A;
+
+  static const int MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB;
+
+  static const int MAX_VIEWPORT_DIMS = 0x0D3A;
+
+  static const int MEDIUM_FLOAT = 0x8DF1;
+
+  static const int MEDIUM_INT = 0x8DF4;
+
+  static const int MIN = 0x8007;
+
+  static const int MIN_PROGRAM_TEXEL_OFFSET = 0x8904;
+
+  static const int MIRRORED_REPEAT = 0x8370;
+
+  static const int NEAREST = 0x2600;
+
+  static const int NEAREST_MIPMAP_LINEAR = 0x2702;
+
+  static const int NEAREST_MIPMAP_NEAREST = 0x2700;
+
+  static const int NEVER = 0x0200;
+
+  static const int NICEST = 0x1102;
+
+  static const int NONE = 0;
+
+  static const int NOTEQUAL = 0x0205;
+
+  static const int NO_ERROR = 0;
+
+  static const int OBJECT_TYPE = 0x9112;
+
+  static const int ONE = 1;
+
+  static const int ONE_MINUS_CONSTANT_ALPHA = 0x8004;
+
+  static const int ONE_MINUS_CONSTANT_COLOR = 0x8002;
+
+  static const int ONE_MINUS_DST_ALPHA = 0x0305;
+
+  static const int ONE_MINUS_DST_COLOR = 0x0307;
+
+  static const int ONE_MINUS_SRC_ALPHA = 0x0303;
+
+  static const int ONE_MINUS_SRC_COLOR = 0x0301;
+
+  static const int OUT_OF_MEMORY = 0x0505;
+
+  static const int PACK_ALIGNMENT = 0x0D05;
+
+  static const int PACK_ROW_LENGTH = 0x0D02;
+
+  static const int PACK_SKIP_PIXELS = 0x0D04;
+
+  static const int PACK_SKIP_ROWS = 0x0D03;
+
+  static const int PIXEL_PACK_BUFFER = 0x88EB;
+
+  static const int PIXEL_PACK_BUFFER_BINDING = 0x88ED;
+
+  static const int PIXEL_UNPACK_BUFFER = 0x88EC;
+
+  static const int PIXEL_UNPACK_BUFFER_BINDING = 0x88EF;
+
+  static const int POINTS = 0x0000;
+
+  static const int POLYGON_OFFSET_FACTOR = 0x8038;
+
+  static const int POLYGON_OFFSET_FILL = 0x8037;
+
+  static const int POLYGON_OFFSET_UNITS = 0x2A00;
+
+  static const int QUERY_RESULT = 0x8866;
+
+  static const int QUERY_RESULT_AVAILABLE = 0x8867;
+
+  static const int R11F_G11F_B10F = 0x8C3A;
+
+  static const int R16F = 0x822D;
+
+  static const int R16I = 0x8233;
+
+  static const int R16UI = 0x8234;
+
+  static const int R32F = 0x822E;
+
+  static const int R32I = 0x8235;
+
+  static const int R32UI = 0x8236;
+
+  static const int R8 = 0x8229;
+
+  static const int R8I = 0x8231;
+
+  static const int R8UI = 0x8232;
+
+  static const int R8_SNORM = 0x8F94;
+
+  static const int RASTERIZER_DISCARD = 0x8C89;
+
+  static const int READ_BUFFER = 0x0C02;
+
+  static const int READ_FRAMEBUFFER = 0x8CA8;
+
+  static const int READ_FRAMEBUFFER_BINDING = 0x8CAA;
+
+  static const int RED = 0x1903;
+
+  static const int RED_BITS = 0x0D52;
+
+  static const int RED_INTEGER = 0x8D94;
+
+  static const int RENDERBUFFER = 0x8D41;
+
+  static const int RENDERBUFFER_ALPHA_SIZE = 0x8D53;
+
+  static const int RENDERBUFFER_BINDING = 0x8CA7;
+
+  static const int RENDERBUFFER_BLUE_SIZE = 0x8D52;
+
+  static const int RENDERBUFFER_DEPTH_SIZE = 0x8D54;
+
+  static const int RENDERBUFFER_GREEN_SIZE = 0x8D51;
+
+  static const int RENDERBUFFER_HEIGHT = 0x8D43;
+
+  static const int RENDERBUFFER_INTERNAL_FORMAT = 0x8D44;
+
+  static const int RENDERBUFFER_RED_SIZE = 0x8D50;
+
+  static const int RENDERBUFFER_SAMPLES = 0x8CAB;
+
+  static const int RENDERBUFFER_STENCIL_SIZE = 0x8D55;
+
+  static const int RENDERBUFFER_WIDTH = 0x8D42;
+
+  static const int RENDERER = 0x1F01;
+
+  static const int REPEAT = 0x2901;
+
+  static const int REPLACE = 0x1E01;
+
+  static const int RG = 0x8227;
+
+  static const int RG16F = 0x822F;
+
+  static const int RG16I = 0x8239;
+
+  static const int RG16UI = 0x823A;
+
+  static const int RG32F = 0x8230;
+
+  static const int RG32I = 0x823B;
+
+  static const int RG32UI = 0x823C;
+
+  static const int RG8 = 0x822B;
+
+  static const int RG8I = 0x8237;
+
+  static const int RG8UI = 0x8238;
+
+  static const int RG8_SNORM = 0x8F95;
+
+  static const int RGB = 0x1907;
+
+  static const int RGB10_A2 = 0x8059;
+
+  static const int RGB10_A2UI = 0x906F;
+
+  static const int RGB16F = 0x881B;
+
+  static const int RGB16I = 0x8D89;
+
+  static const int RGB16UI = 0x8D77;
+
+  static const int RGB32F = 0x8815;
+
+  static const int RGB32I = 0x8D83;
+
+  static const int RGB32UI = 0x8D71;
+
+  static const int RGB565 = 0x8D62;
+
+  static const int RGB5_A1 = 0x8057;
+
+  static const int RGB8 = 0x8051;
+
+  static const int RGB8I = 0x8D8F;
+
+  static const int RGB8UI = 0x8D7D;
+
+  static const int RGB8_SNORM = 0x8F96;
+
+  static const int RGB9_E5 = 0x8C3D;
+
+  static const int RGBA = 0x1908;
+
+  static const int RGBA16F = 0x881A;
+
+  static const int RGBA16I = 0x8D88;
+
+  static const int RGBA16UI = 0x8D76;
+
+  static const int RGBA32F = 0x8814;
+
+  static const int RGBA32I = 0x8D82;
+
+  static const int RGBA32UI = 0x8D70;
+
+  static const int RGBA4 = 0x8056;
+
+  static const int RGBA8 = 0x8058;
+
+  static const int RGBA8I = 0x8D8E;
+
+  static const int RGBA8UI = 0x8D7C;
+
+  static const int RGBA8_SNORM = 0x8F97;
+
+  static const int RGBA_INTEGER = 0x8D99;
+
+  static const int RGB_INTEGER = 0x8D98;
+
+  static const int RG_INTEGER = 0x8228;
+
+  static const int SAMPLER_2D = 0x8B5E;
+
+  static const int SAMPLER_2D_ARRAY = 0x8DC1;
+
+  static const int SAMPLER_2D_ARRAY_SHADOW = 0x8DC4;
+
+  static const int SAMPLER_2D_SHADOW = 0x8B62;
+
+  static const int SAMPLER_3D = 0x8B5F;
+
+  static const int SAMPLER_BINDING = 0x8919;
+
+  static const int SAMPLER_CUBE = 0x8B60;
+
+  static const int SAMPLER_CUBE_SHADOW = 0x8DC5;
+
+  static const int SAMPLES = 0x80A9;
+
+  static const int SAMPLE_ALPHA_TO_COVERAGE = 0x809E;
+
+  static const int SAMPLE_BUFFERS = 0x80A8;
+
+  static const int SAMPLE_COVERAGE = 0x80A0;
+
+  static const int SAMPLE_COVERAGE_INVERT = 0x80AB;
+
+  static const int SAMPLE_COVERAGE_VALUE = 0x80AA;
+
+  static const int SCISSOR_BOX = 0x0C10;
+
+  static const int SCISSOR_TEST = 0x0C11;
+
+  static const int SEPARATE_ATTRIBS = 0x8C8D;
+
+  static const int SHADER_TYPE = 0x8B4F;
+
+  static const int SHADING_LANGUAGE_VERSION = 0x8B8C;
+
+  static const int SHORT = 0x1402;
+
+  static const int SIGNALED = 0x9119;
+
+  static const int SIGNED_NORMALIZED = 0x8F9C;
+
+  static const int SRC_ALPHA = 0x0302;
+
+  static const int SRC_ALPHA_SATURATE = 0x0308;
+
+  static const int SRC_COLOR = 0x0300;
+
+  static const int SRGB = 0x8C40;
+
+  static const int SRGB8 = 0x8C41;
+
+  static const int SRGB8_ALPHA8 = 0x8C43;
+
+  static const int STATIC_COPY = 0x88E6;
+
+  static const int STATIC_DRAW = 0x88E4;
+
+  static const int STATIC_READ = 0x88E5;
+
+  static const int STENCIL = 0x1802;
+
+  static const int STENCIL_ATTACHMENT = 0x8D20;
+
+  static const int STENCIL_BACK_FAIL = 0x8801;
+
+  static const int STENCIL_BACK_FUNC = 0x8800;
+
+  static const int STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802;
+
+  static const int STENCIL_BACK_PASS_DEPTH_PASS = 0x8803;
+
+  static const int STENCIL_BACK_REF = 0x8CA3;
+
+  static const int STENCIL_BACK_VALUE_MASK = 0x8CA4;
+
+  static const int STENCIL_BACK_WRITEMASK = 0x8CA5;
+
+  static const int STENCIL_BITS = 0x0D57;
+
+  static const int STENCIL_BUFFER_BIT = 0x00000400;
+
+  static const int STENCIL_CLEAR_VALUE = 0x0B91;
+
+  static const int STENCIL_FAIL = 0x0B94;
+
+  static const int STENCIL_FUNC = 0x0B92;
+
+  static const int STENCIL_INDEX8 = 0x8D48;
+
+  static const int STENCIL_PASS_DEPTH_FAIL = 0x0B95;
+
+  static const int STENCIL_PASS_DEPTH_PASS = 0x0B96;
+
+  static const int STENCIL_REF = 0x0B97;
+
+  static const int STENCIL_TEST = 0x0B90;
+
+  static const int STENCIL_VALUE_MASK = 0x0B93;
+
+  static const int STENCIL_WRITEMASK = 0x0B98;
+
+  static const int STREAM_COPY = 0x88E2;
+
+  static const int STREAM_DRAW = 0x88E0;
+
+  static const int STREAM_READ = 0x88E1;
+
+  static const int SUBPIXEL_BITS = 0x0D50;
+
+  static const int SYNC_CONDITION = 0x9113;
+
+  static const int SYNC_FENCE = 0x9116;
+
+  static const int SYNC_FLAGS = 0x9115;
+
+  static const int SYNC_FLUSH_COMMANDS_BIT = 0x00000001;
+
+  static const int SYNC_GPU_COMMANDS_COMPLETE = 0x9117;
+
+  static const int SYNC_STATUS = 0x9114;
+
+  static const int TEXTURE = 0x1702;
+
+  static const int TEXTURE0 = 0x84C0;
+
+  static const int TEXTURE1 = 0x84C1;
+
+  static const int TEXTURE10 = 0x84CA;
+
+  static const int TEXTURE11 = 0x84CB;
+
+  static const int TEXTURE12 = 0x84CC;
+
+  static const int TEXTURE13 = 0x84CD;
+
+  static const int TEXTURE14 = 0x84CE;
+
+  static const int TEXTURE15 = 0x84CF;
+
+  static const int TEXTURE16 = 0x84D0;
+
+  static const int TEXTURE17 = 0x84D1;
+
+  static const int TEXTURE18 = 0x84D2;
+
+  static const int TEXTURE19 = 0x84D3;
+
+  static const int TEXTURE2 = 0x84C2;
+
+  static const int TEXTURE20 = 0x84D4;
+
+  static const int TEXTURE21 = 0x84D5;
+
+  static const int TEXTURE22 = 0x84D6;
+
+  static const int TEXTURE23 = 0x84D7;
+
+  static const int TEXTURE24 = 0x84D8;
+
+  static const int TEXTURE25 = 0x84D9;
+
+  static const int TEXTURE26 = 0x84DA;
+
+  static const int TEXTURE27 = 0x84DB;
+
+  static const int TEXTURE28 = 0x84DC;
+
+  static const int TEXTURE29 = 0x84DD;
+
+  static const int TEXTURE3 = 0x84C3;
+
+  static const int TEXTURE30 = 0x84DE;
+
+  static const int TEXTURE31 = 0x84DF;
+
+  static const int TEXTURE4 = 0x84C4;
+
+  static const int TEXTURE5 = 0x84C5;
+
+  static const int TEXTURE6 = 0x84C6;
+
+  static const int TEXTURE7 = 0x84C7;
+
+  static const int TEXTURE8 = 0x84C8;
+
+  static const int TEXTURE9 = 0x84C9;
+
+  static const int TEXTURE_2D = 0x0DE1;
+
+  static const int TEXTURE_2D_ARRAY = 0x8C1A;
+
+  static const int TEXTURE_3D = 0x806F;
+
+  static const int TEXTURE_BASE_LEVEL = 0x813C;
+
+  static const int TEXTURE_BINDING_2D = 0x8069;
+
+  static const int TEXTURE_BINDING_2D_ARRAY = 0x8C1D;
+
+  static const int TEXTURE_BINDING_3D = 0x806A;
+
+  static const int TEXTURE_BINDING_CUBE_MAP = 0x8514;
+
+  static const int TEXTURE_COMPARE_FUNC = 0x884D;
+
+  static const int TEXTURE_COMPARE_MODE = 0x884C;
+
+  static const int TEXTURE_CUBE_MAP = 0x8513;
+
+  static const int TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;
+
+  static const int TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;
+
+  static const int TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A;
+
+  static const int TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;
+
+  static const int TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;
+
+  static const int TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;
+
+  static const int TEXTURE_IMMUTABLE_FORMAT = 0x912F;
+
+  static const int TEXTURE_IMMUTABLE_LEVELS = 0x82DF;
+
+  static const int TEXTURE_MAG_FILTER = 0x2800;
+
+  static const int TEXTURE_MAX_LEVEL = 0x813D;
+
+  static const int TEXTURE_MAX_LOD = 0x813B;
+
+  static const int TEXTURE_MIN_FILTER = 0x2801;
+
+  static const int TEXTURE_MIN_LOD = 0x813A;
+
+  static const int TEXTURE_WRAP_R = 0x8072;
+
+  static const int TEXTURE_WRAP_S = 0x2802;
+
+  static const int TEXTURE_WRAP_T = 0x2803;
+
+  static const int TIMEOUT_EXPIRED = 0x911B;
+
+  static const int TIMEOUT_IGNORED = -1;
+
+  static const int TRANSFORM_FEEDBACK = 0x8E22;
+
+  static const int TRANSFORM_FEEDBACK_ACTIVE = 0x8E24;
+
+  static const int TRANSFORM_FEEDBACK_BINDING = 0x8E25;
+
+  static const int TRANSFORM_FEEDBACK_BUFFER = 0x8C8E;
+
+  static const int TRANSFORM_FEEDBACK_BUFFER_BINDING = 0x8C8F;
+
+  static const int TRANSFORM_FEEDBACK_BUFFER_MODE = 0x8C7F;
+
+  static const int TRANSFORM_FEEDBACK_BUFFER_SIZE = 0x8C85;
+
+  static const int TRANSFORM_FEEDBACK_BUFFER_START = 0x8C84;
+
+  static const int TRANSFORM_FEEDBACK_PAUSED = 0x8E23;
+
+  static const int TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = 0x8C88;
+
+  static const int TRANSFORM_FEEDBACK_VARYINGS = 0x8C83;
+
+  static const int TRIANGLES = 0x0004;
+
+  static const int TRIANGLE_FAN = 0x0006;
+
+  static const int TRIANGLE_STRIP = 0x0005;
+
+  static const int UNIFORM_ARRAY_STRIDE = 0x8A3C;
+
+  static const int UNIFORM_BLOCK_ACTIVE_UNIFORMS = 0x8A42;
+
+  static const int UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8A43;
+
+  static const int UNIFORM_BLOCK_BINDING = 0x8A3F;
+
+  static const int UNIFORM_BLOCK_DATA_SIZE = 0x8A40;
+
+  static const int UNIFORM_BLOCK_INDEX = 0x8A3A;
+
+  static const int UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8A46;
+
+  static const int UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8A44;
+
+  static const int UNIFORM_BUFFER = 0x8A11;
+
+  static const int UNIFORM_BUFFER_BINDING = 0x8A28;
+
+  static const int UNIFORM_BUFFER_OFFSET_ALIGNMENT = 0x8A34;
+
+  static const int UNIFORM_BUFFER_SIZE = 0x8A2A;
+
+  static const int UNIFORM_BUFFER_START = 0x8A29;
+
+  static const int UNIFORM_IS_ROW_MAJOR = 0x8A3E;
+
+  static const int UNIFORM_MATRIX_STRIDE = 0x8A3D;
+
+  static const int UNIFORM_OFFSET = 0x8A3B;
+
+  static const int UNIFORM_SIZE = 0x8A38;
+
+  static const int UNIFORM_TYPE = 0x8A37;
+
+  static const int UNPACK_ALIGNMENT = 0x0CF5;
+
+  static const int UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
+
+  static const int UNPACK_FLIP_Y_WEBGL = 0x9240;
+
+  static const int UNPACK_IMAGE_HEIGHT = 0x806E;
+
+  static const int UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;
+
+  static const int UNPACK_ROW_LENGTH = 0x0CF2;
+
+  static const int UNPACK_SKIP_IMAGES = 0x806D;
+
+  static const int UNPACK_SKIP_PIXELS = 0x0CF4;
+
+  static const int UNPACK_SKIP_ROWS = 0x0CF3;
+
+  static const int UNSIGNALED = 0x9118;
+
+  static const int UNSIGNED_BYTE = 0x1401;
+
+  static const int UNSIGNED_INT = 0x1405;
+
+  static const int UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B;
+
+  static const int UNSIGNED_INT_24_8 = 0x84FA;
+
+  static const int UNSIGNED_INT_2_10_10_10_REV = 0x8368;
+
+  static const int UNSIGNED_INT_5_9_9_9_REV = 0x8C3E;
+
+  static const int UNSIGNED_INT_SAMPLER_2D = 0x8DD2;
+
+  static const int UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7;
+
+  static const int UNSIGNED_INT_SAMPLER_3D = 0x8DD3;
+
+  static const int UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4;
+
+  static const int UNSIGNED_INT_VEC2 = 0x8DC6;
+
+  static const int UNSIGNED_INT_VEC3 = 0x8DC7;
+
+  static const int UNSIGNED_INT_VEC4 = 0x8DC8;
+
+  static const int UNSIGNED_NORMALIZED = 0x8C17;
+
+  static const int UNSIGNED_SHORT = 0x1403;
+
+  static const int UNSIGNED_SHORT_4_4_4_4 = 0x8033;
+
+  static const int UNSIGNED_SHORT_5_5_5_1 = 0x8034;
+
+  static const int UNSIGNED_SHORT_5_6_5 = 0x8363;
+
+  static const int VALIDATE_STATUS = 0x8B83;
+
+  static const int VENDOR = 0x1F00;
+
+  static const int VERSION = 0x1F02;
+
+  static const int VERTEX_ARRAY_BINDING = 0x85B5;
+
+  static const int VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
+
+  static const int VERTEX_ATTRIB_ARRAY_DIVISOR = 0x88FE;
+
+  static const int VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622;
+
+  static const int VERTEX_ATTRIB_ARRAY_INTEGER = 0x88FD;
+
+  static const int VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A;
+
+  static const int VERTEX_ATTRIB_ARRAY_POINTER = 0x8645;
+
+  static const int VERTEX_ATTRIB_ARRAY_SIZE = 0x8623;
+
+  static const int VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624;
+
+  static const int VERTEX_ATTRIB_ARRAY_TYPE = 0x8625;
+
+  static const int VERTEX_SHADER = 0x8B31;
+
+  static const int VIEWPORT = 0x0BA2;
+
+  static const int WAIT_FAILED = 0x911D;
+
+  static const int ZERO = 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.
+
+@Native("WebGL2RenderingContextBase")
+abstract class _WebGL2RenderingContextBase extends Interceptor
+    implements _WebGLRenderingContextBase {
+  // To suppress missing implicit constructor warnings.
+  factory _WebGL2RenderingContextBase._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  // From WebGLRenderingContextBase
+}
+// Copyright (c) 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.
+
+abstract class _WebGLRenderingContextBase extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory _WebGLRenderingContextBase._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
diff --git a/sdk_nnbd/lib/web_sql/dart2js/web_sql_dart2js.dart b/sdk_nnbd/lib/web_sql/dart2js/web_sql_dart2js.dart
new file mode 100644
index 0000000..0f703f9
--- /dev/null
+++ b/sdk_nnbd/lib/web_sql/dart2js/web_sql_dart2js.dart
@@ -0,0 +1,306 @@
+/**
+ * An API for storing data in the browser that can be queried with SQL.
+ *
+ * **Caution:** this specification is no longer actively maintained by the Web
+ * Applications Working Group and may be removed at any time.
+ * See [the W3C Web SQL Database specification](http://www.w3.org/TR/webdatabase/)
+ * for more information.
+ *
+ * The [dart:indexed_db] APIs is a recommended alternatives.
+ *
+ * {@category Web}
+ */
+library dart.dom.web_sql;
+
+import 'dart:async';
+import 'dart:collection' hide LinkedList, LinkedListEntry;
+import 'dart:_internal' show FixedLengthListMixin;
+import 'dart:html';
+import 'dart:html_common';
+import 'dart:_foreign_helper' show JS;
+import 'dart:_interceptors' show Interceptor;
+// DO NOT EDIT - unless you are editing documentation as per:
+// https://code.google.com/p/dart/wiki/ContributingHTMLDocumentation
+// Auto-generated dart:audio library.
+
+import 'dart:_js_helper'
+    show
+        applyExtension,
+        convertDartClosureToJS,
+        Creates,
+        JSName,
+        Native,
+        JavaScriptIndexingBehavior;
+
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void SqlStatementCallback(
+    SqlTransaction transaction, SqlResultSet resultSet);
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void SqlStatementErrorCallback(
+    SqlTransaction transaction, SqlError error);
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void SqlTransactionCallback(SqlTransaction transaction);
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+typedef void SqlTransactionErrorCallback(SqlError error);
+// Copyright (c) 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.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Native("Database")
+class SqlDatabase extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory SqlDatabase._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(window.openDatabase)');
+
+  final String version;
+
+  @JSName('changeVersion')
+  /**
+   * Atomically update the database version to [newVersion], asynchronously
+   * running [callback] on the [SqlTransaction] representing this
+   * [changeVersion] transaction.
+   *
+   * If [callback] runs successfully, then [successCallback] is called.
+   * Otherwise, [errorCallback] is called.
+   *
+   * [oldVersion] should match the database's current [version] exactly.
+   *
+   * See also:
+   *
+   * * [Database.changeVersion](http://www.w3.org/TR/webdatabase/#dom-database-changeversion) from W3C.
+   */
+  void _changeVersion(String oldVersion, String newVersion,
+      [SqlTransactionCallback callback,
+      SqlTransactionErrorCallback errorCallback,
+      VoidCallback successCallback]) native;
+
+  @JSName('changeVersion')
+  /**
+   * Atomically update the database version to [newVersion], asynchronously
+   * running [callback] on the [SqlTransaction] representing this
+   * [changeVersion] transaction.
+   *
+   * If [callback] runs successfully, then [successCallback] is called.
+   * Otherwise, [errorCallback] is called.
+   *
+   * [oldVersion] should match the database's current [version] exactly.
+   *
+   * See also:
+   *
+   * * [Database.changeVersion](http://www.w3.org/TR/webdatabase/#dom-database-changeversion) from W3C.
+   */
+  Future<SqlTransaction> changeVersion(String oldVersion, String newVersion) {
+    var completer = new Completer<SqlTransaction>();
+    _changeVersion(oldVersion, newVersion, (value) {
+      completer.complete(value);
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+
+  @JSName('readTransaction')
+  void _readTransaction(SqlTransactionCallback callback,
+      [SqlTransactionErrorCallback errorCallback,
+      VoidCallback successCallback]) native;
+
+  @JSName('readTransaction')
+  Future<SqlTransaction> readTransaction() {
+    var completer = new Completer<SqlTransaction>();
+    _readTransaction((value) {
+      completer.complete(value);
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+
+  void transaction(SqlTransactionCallback callback,
+      [SqlTransactionErrorCallback errorCallback,
+      VoidCallback successCallback]) native;
+
+  @JSName('transaction')
+  Future<SqlTransaction> transaction_future() {
+    var completer = new Completer<SqlTransaction>();
+    transaction((value) {
+      applyExtension('SQLTransaction', value);
+      completer.complete(value);
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+}
+// Copyright (c) 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.
+
+@Native("SQLError")
+class SqlError extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory SqlError._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  static const int CONSTRAINT_ERR = 6;
+
+  static const int DATABASE_ERR = 1;
+
+  static const int QUOTA_ERR = 4;
+
+  static const int SYNTAX_ERR = 5;
+
+  static const int TIMEOUT_ERR = 7;
+
+  static const int TOO_LARGE_ERR = 3;
+
+  static const int UNKNOWN_ERR = 0;
+
+  static const int VERSION_ERR = 2;
+
+  final int code;
+
+  final String message;
+}
+// Copyright (c) 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.
+
+@Native("SQLResultSet")
+class SqlResultSet extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory SqlResultSet._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  final int insertId;
+
+  final SqlResultSetRowList rows;
+
+  final int rowsAffected;
+}
+// Copyright (c) 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.
+
+@Native("SQLResultSetRowList")
+class SqlResultSetRowList extends Interceptor
+    with ListMixin<Map>, ImmutableListMixin<Map>
+    implements List<Map> {
+  // To suppress missing implicit constructor warnings.
+  factory SqlResultSetRowList._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  int get length => JS("int", "#.length", this);
+
+  Map operator [](int index) {
+    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
+      throw new RangeError.index(index, this);
+    return this.item(index);
+  }
+
+  void operator []=(int index, Map value) {
+    throw new UnsupportedError("Cannot assign element of immutable List.");
+  }
+  // -- start List<Map> mixins.
+  // Map is the element type.
+
+  set length(int value) {
+    throw new UnsupportedError("Cannot resize immutable List.");
+  }
+
+  Map get first {
+    if (this.length > 0) {
+      return JS('Map', '#[0]', this);
+    }
+    throw new StateError("No elements");
+  }
+
+  Map get last {
+    int len = this.length;
+    if (len > 0) {
+      return JS('Map', '#[#]', this, len - 1);
+    }
+    throw new StateError("No elements");
+  }
+
+  Map get single {
+    int len = this.length;
+    if (len == 1) {
+      return JS('Map', '#[0]', this);
+    }
+    if (len == 0) throw new StateError("No elements");
+    throw new StateError("More than one element");
+  }
+
+  Map elementAt(int index) => this[index];
+  // -- end List<Map> mixins.
+
+  Map item(int index) {
+    return convertNativeToDart_Dictionary(_item_1(index));
+  }
+
+  @JSName('item')
+  _item_1(index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+// http://www.w3.org/TR/webdatabase/#sqltransaction
+@deprecated // deprecated
+@Native("SQLTransaction")
+class SqlTransaction extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory SqlTransaction._() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @JSName('executeSql')
+  void _executeSql(String sqlStatement,
+      [List arguments,
+      SqlStatementCallback callback,
+      SqlStatementErrorCallback errorCallback]) native;
+
+  @JSName('executeSql')
+  Future<SqlResultSet> executeSql(String sqlStatement, [List arguments]) {
+    var completer = new Completer<SqlResultSet>();
+    _executeSql(sqlStatement, arguments, (transaction, resultSet) {
+      applyExtension('SQLResultSet', resultSet);
+      applyExtension('SQLResultSetRowList', resultSet.rows);
+      completer.complete(resultSet);
+    }, (transaction, error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+}
diff --git a/tests/compiler/dart2js_extra/38005_test.dart b/tests/compiler/dart2js_extra/38005_test.dart
new file mode 100644
index 0000000..2789b31
--- /dev/null
+++ b/tests/compiler/dart2js_extra/38005_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 {}
+
+int foo<T>() {
+  switch (T) {
+    case A:
+      return 42;
+    default:
+      return -1;
+  }
+}
+
+void main() {
+  Expect.equals(42, foo<A>());
+  Expect.equals(-1, foo<int>());
+}
diff --git a/tests/language_2/extension_methods/static_extension_getter_setter_conflicts_test.dart b/tests/language_2/extension_methods/static_extension_getter_setter_conflicts_test.dart
index 402ff2d..e1baee5 100644
--- a/tests/language_2/extension_methods/static_extension_getter_setter_conflicts_test.dart
+++ b/tests/language_2/extension_methods/static_extension_getter_setter_conflicts_test.dart
@@ -68,13 +68,13 @@
   c1a.m1;
 
   c1a.m1 = 0;
-  //  ^^^^^^
-  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_EXTENSION_SETTER
+  //  ^^
+  // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_LOCAL
   // [cfe] unspecified
 
   c1a.m2;
   //  ^^
-  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_EXTENSION_GETTER
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
   // [cfe] unspecified
 
   c1a.m2 = 0;
@@ -87,7 +87,7 @@
   // [cfe] unspecified
 
   c1b.m1 = 0;
-  //  ^^^^^^
+  //  ^^
   // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
   // [cfe] unspecified
 
@@ -97,7 +97,7 @@
   // [cfe] unspecified
 
   c1b.m2 = 0;
-  //  ^^^^^^
+  //  ^^
   // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
   // [cfe] unspecified
 }
@@ -119,14 +119,14 @@
 
     this.m1;
     this.m1 = 0;
-    //   ^^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_EXTENSION_SETTER
+    //   ^^
+    // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
     // [cfe] unspecified
 
     this.m2 = 0;
     this.m2;
     //   ^^
-    // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_EXTENSION_GETTER
+    // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
     // [cfe] unspecified
 
     // Check that `this.mc` refers to `C2.mc`.
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index bb945c5..cddcbd3 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -7,7 +7,6 @@
 [ $compiler == dart2analyzer ]
 generic_no_such_method_dispatcher_simple_test: Skip # failing-by-design: This test is just for kernel
 large_class_declaration_test: Slow
-regress_23408_test: Skip # don't care about the static warning.
 vm/debug_break_enabled_vm_test: Skip
 vm/debug_break_vm_test/*: Skip
 vm/regress_27201_test: SkipByDesign # Loads bad library, so will always crash.
diff --git a/tests/language_2/map_literal3_test.dart b/tests/language_2/map_literal3_test.dart
index 36827f6..a5d054c 100644
--- a/tests/language_2/map_literal3_test.dart
+++ b/tests/language_2/map_literal3_test.dart
@@ -40,35 +40,20 @@
           "b": b,
         }["b"]);
 
-    // Make map grow. We currently don't have a way to construct
-    // strings from an integer value, so we can't use a loop here.
     var m = new Map();
     Expect.equals(m.length, 0);
-    m["1"] = 1;
-    m["2"] = 2;
-    m["3"] = 3;
-    m["4"] = 4;
-    m["5"] = 5;
-    m["6"] = 6;
-    m["7"] = 7;
-    m["8"] = 8;
-    m["9"] = 9;
-    m["10"] = 10;
-    m["11"] = 11;
-    m["12"] = 12;
-    m["13"] = 13;
-    m["14"] = 14;
-    m["15"] = 15;
-    m["16"] = 16;
+    for (var i = 1; i <= 16; i++) {
+      m[i.toString()] = i;
+    }
     Expect.equals(16, m.length);
-    m.remove("1");
-    m.remove("1"); // Remove element twice.
-    m.remove("16");
+    Expect.equals(1, m.remove("1"));
+    Expect.isNull(m.remove("1")); // Remove element twice.
+    Expect.equals(16, m.remove("16"));
     Expect.equals(14, m.length);
 
     final cmap = const <String, num>{"a": 10, "b": 100, "a": 1000}; //# 01: compile-time error
     final cmap2 = const <String, num>{"a": 10, "a": 100, "a": 1000}; //# 02: compile-time error
-    var mmap = <String, num>{"a": 10, "b": 100, "a": 1000}; //# 03: compile-time error
+    var mmap = <String, num>{"a": 10, "b": 100, "a": 1000}; //# 03: ok
     var mmap = <String, num>{"a": ctr(), "b": ctr(), "a": ctr()}; //# 04: compile-time error
 
     Expect.equals(10, {"beta": 100, "alpha": 9 + 1}["alpha"]);
diff --git a/tests/language_2/vm/osr_nonempty_stack_test.dart b/tests/language_2/vm/osr_nonempty_stack_test.dart
index 9797e6e..a31df50 100644
--- a/tests/language_2/vm/osr_nonempty_stack_test.dart
+++ b/tests/language_2/vm/osr_nonempty_stack_test.dart
@@ -93,6 +93,12 @@
   return x;
 }
 
+List<int> globalList = [
+  1,
+  for (int loc1 = 2; loc1 <= 100000; loc1++) loc1,
+  100001
+];
+
 main() {
   int n = 20000;
   int g = 457;
@@ -134,4 +140,10 @@
     Expect.equals(e[i], expect);
     if (++k == (n + 2)) k = 0;
   }
+
+  Expect.isTrue(globalList != null);
+  Expect.equals(100001, globalList.length);
+  for (int i = 0; i < globalList.length; i++) {
+    Expect.equals(globalList[i], i + 1);
+  }
 }
diff --git a/tests/lib_2/async/future_test.dart b/tests/lib_2/async/future_test.dart
index 515adca..9223646 100644
--- a/tests/lib_2/async/future_test.dart
+++ b/tests/lib_2/async/future_test.dart
@@ -1248,7 +1248,7 @@
   UglyFuture(int badness)
       : _result = (badness == 0) ? 42 : new UglyFuture(badness - 1);
   Future<S> then<S>(action(value), {Function onError}) {
-    var c = new Completer();
+    var c = new Completer<S>();
     c.complete(new Future.microtask(() => action(_result)));
     return c.future;
   }
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status
index 23463b5..2aeba0c 100644
--- a/tests/lib_2/lib_2_kernel.status
+++ b/tests/lib_2/lib_2_kernel.status
@@ -68,9 +68,9 @@
 
 [ ($compiler == dartk || $compiler == dartkb) && ($hot_reload || $hot_reload_rollback) ]
 isolate/message4_test: Crash # Timeout and sporadic crash (issue 33824)
-mirrors/dynamic_load_test: Crash
-mirrors/library_uri_io_test: Skip # Timeout
-mirrors/library_uri_package_test: Skip # Timeout
+mirrors/dynamic_load_test: Skip # Reload has an effect similar to deleting the dynamically loaded library
+mirrors/immutable_collections_test: Pass, Slow
+mirrors/mirrors_reader_test: Pass, Slow
 
 [ $compiler == app_jitk || $compiler == dartk || $compiler == dartkb || $compiler == dartkp ]
 html/*: SkipByDesign
diff --git a/tests/standalone_2/io/server_socket_exception_test.dart b/tests/standalone_2/io/server_socket_exception_test.dart
index f6c0993..16d1c34 100644
--- a/tests/standalone_2/io/server_socket_exception_test.dart
+++ b/tests/standalone_2/io/server_socket_exception_test.dart
@@ -28,10 +28,9 @@
     Expect.equals(true, !wrongExceptionCaught);
 
     // Test invalid host.
-    ServerSocket
-        .bind("__INVALID_HOST__", 0)
-        .then((server) {})
-        .catchError((e) => e is SocketException);
+    ServerSocket.bind("__INVALID_HOST__", 0).then((server) {
+      Expect.fail('Connection succeeded.');
+    }).catchError((e) => Expect.isTrue(e is SocketException));
   });
 }
 
diff --git a/tools/VERSION b/tools/VERSION
index e822ddc..da78ef9 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
 MAJOR 2
 MINOR 6
 PATCH 0
-PRERELEASE 0
+PRERELEASE 1
 PRERELEASE_PATCH 0
 ABI_VERSION 14
 OLDEST_SUPPORTED_ABI_VERSION 13
diff --git a/tools/approve_results.dart b/tools/approve_results.dart
index ebf1dd1..dc39a52 100755
--- a/tools/approve_results.dart
+++ b/tools/approve_results.dart
@@ -99,7 +99,9 @@
   bool get isApproved => result == null || result == approvedResult;
   List<String> get flakyModes =>
       flakinessData != null ? flakinessData["outcomes"].cast<String>() : null;
-  bool get isFlake => flakinessData != null && flakyModes.contains(result);
+  bool get isFlake =>
+      resultData != null && resultData["flaky"] ||
+      flakinessData != null && flakyModes.contains(result);
 }
 
 /// Loads the results file as as a map if the file exists, otherwise returns the
